Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

clean up and add size limit to requests

Changed files
+13 -16
pocket
+8 -12
pocket/src/server.rs
··· 4 4 endpoint::{StaticFileEndpoint, make_sync}, 5 5 http::Method, 6 6 listener::TcpListener, 7 - middleware::{CatchPanic, Cors, Tracing}, 7 + middleware::{CatchPanic, Cors, SizeLimit, Tracing}, 8 8 }; 9 9 use poem_openapi::{ 10 10 ApiResponse, ContactObject, ExternalDocumentObject, Object, OpenApi, OpenApiService, ··· 94 94 verifier: TokenVerifier, 95 95 } 96 96 97 - // app.bsky.actor.getPreferences 98 - // com.bad-example.pocket.getPreferences 99 - 100 97 #[OpenApi] 101 98 impl Xrpc { 102 99 /// com.bad-example.pocket.getPreferences 103 100 /// 104 - /// get stored bluesky prefs 101 + /// get stored preferencess 105 102 #[oai( 106 - path = "/app.bsky.actor.getPreferences", 103 + path = "/com.bad-example.pocket.getPreferences", 107 104 method = "get", 108 105 tag = "ApiTags::Pocket" 109 106 )] 110 - async fn app_bsky_get_prefs(&self, XrpcAuth(auth): XrpcAuth) -> GetBskyPrefsResponse { 107 + async fn pocket_get_prefs(&self, XrpcAuth(auth): XrpcAuth) -> GetBskyPrefsResponse { 111 108 let (did, aud) = match self 112 109 .verifier 113 - .verify("app.bsky.actor.getPreferences", &auth.token) 110 + .verify("com.bad-example.pocket.getPreferences", &auth.token) 114 111 .await 115 112 { 116 113 Ok(d) => d, ··· 129 126 method = "post", 130 127 tag = "ApiTags::Pocket" 131 128 )] 132 - async fn app_bsky_put_prefs( 129 + async fn pocket_put_prefs( 133 130 &self, 134 131 XrpcAuth(auth): XrpcAuth, 135 132 Json(prefs): Json<Value>, 136 133 ) -> PutBskyPrefsResponse { 137 134 let (did, aud) = match self 138 135 .verifier 139 - .verify("app.bsky.actor.getPreferences", &auth.token) 136 + .verify("com.bad-example.pocket.putPreferences", &auth.token) 140 137 .await 141 138 { 142 139 Ok(d) => d, ··· 168 165 service: [ 169 166 AppViewService { 170 167 id: "#pocket_prefs".to_string(), 171 - // id: "#bsky_appview".to_string(), 172 168 r#type: "PocketPreferences".to_string(), 173 169 service_endpoint: format!("https://{domain}"), 174 170 }, 175 171 AppViewService { 176 172 id: "#bsky_appview".to_string(), 177 - // id: "#bsky_appview".to_string(), 178 173 r#type: "BlueskyAppview".to_string(), 179 174 service_endpoint: format!("https://{domain}"), 180 175 }, ··· 201 196 .nest("/xrpc/", api_service) 202 197 .at("/.well-known/did.json", get_did_doc(domain)) 203 198 .at("/", StaticFileEndpoint::new("./static/index.html")) 199 + .with(SizeLimit::new(100 * 2_usize.pow(10))) 204 200 .with( 205 201 Cors::new() 206 202 .allow_method(Method::GET)
+5 -4
pocket/src/token.rs
··· 118 118 let Some(aud) = claims.custom.get("aud") else { 119 119 return Err(VerifyError::VerificationFailed("missing aud")); 120 120 }; 121 - let Some(aud) = aud.strip_prefix("did:web:") else { 121 + let Some(mut aud) = aud.strip_prefix("did:web:") else { 122 122 return Err(VerifyError::VerificationFailed("expected a did:web aud")); 123 123 }; 124 - let Some((aud, _)) = aud.split_once("#") else { 125 - return Err(VerifyError::VerificationFailed("aud missing #fragment")); 126 - }; 124 + if let Some((aud_without_hash, _)) = aud.split_once("#") { 125 + log::warn!("aud claim is missing service id fragment: {aud:?}"); 126 + aud = aud_without_hash; 127 + } 127 128 let Some(lxm) = claims.custom.get("lxm") else { 128 129 return Err(VerifyError::VerificationFailed("missing lxm")); 129 130 };