diff --git a/pocket/src/server.rs b/pocket/src/server.rs index 0dc7879..5c49a09 100644 --- a/pocket/src/server.rs +++ b/pocket/src/server.rs @@ -108,7 +108,7 @@ impl Xrpc { tag = "ApiTags::Pocket" )] async fn app_bsky_get_prefs(&self, XrpcAuth(auth): XrpcAuth) -> GetBskyPrefsResponse { - let did = match self + let (did, aud) = match self .verifier .verify("app.bsky.actor.getPreferences", &auth.token) .await @@ -116,7 +116,7 @@ impl Xrpc { Ok(d) => d, Err(e) => return GetBskyPrefsResponse::BadRequest(xrpc_error("boooo", e.to_string())), }; - log::info!("verified did: {did}"); + log::info!("verified did: {did}/{aud}"); // TODO: fetch from storage GetBskyPrefsResponse::Ok(Json(GetBskyPrefsResponseObject::example())) } @@ -134,7 +134,7 @@ impl Xrpc { XrpcAuth(auth): XrpcAuth, Json(prefs): Json, ) -> PutBskyPrefsResponse { - let did = match self + let (did, aud) = match self .verifier .verify("app.bsky.actor.getPreferences", &auth.token) .await @@ -142,7 +142,7 @@ impl Xrpc { Ok(d) => d, Err(e) => return PutBskyPrefsResponse::BadRequest(xrpc_error("boooo", e.to_string())), }; - log::info!("verified did: {did}"); + log::info!("verified did: {did}/{aud}"); log::warn!("received prefs: {prefs:?}"); // TODO: put prefs into storage PutBskyPrefsResponse::Ok(PlainText("hiiiiii".to_string())) @@ -184,7 +184,7 @@ fn get_did_doc(domain: &str) -> impl Endpoint + use<> { } pub async fn serve(domain: &str) -> () { - let verifier = TokenVerifier::new(domain); + let verifier = TokenVerifier::default(); let api_service = OpenApiService::new(Xrpc { verifier }, "Pocket", env!("CARGO_PKG_VERSION")) .server(domain) .url_prefix("/xrpc") diff --git a/pocket/src/token.rs b/pocket/src/token.rs index 33a7394..1133fd6 100644 --- a/pocket/src/token.rs +++ b/pocket/src/token.rs @@ -21,12 +21,11 @@ pub enum VerifyError { } pub struct TokenVerifier { - domain: String, client: reqwest::Client, } impl TokenVerifier { - pub fn new(domain: &str) -> Self { + pub fn new() -> Self { let client = reqwest::Client::builder() .user_agent(format!( "microcosm pocket v{} (dev: @bad-example.com)", @@ -36,13 +35,14 @@ impl TokenVerifier { .timeout(Duration::from_secs(12)) // slingshot timeout is 10s .build() .unwrap(); - Self { - client, - domain: domain.to_string(), - } + Self { client } } - pub async fn verify(&self, expected_lxm: &str, token: &str) -> Result { + pub async fn verify( + &self, + expected_lxm: &str, + token: &str, + ) -> Result<(String, String), VerifyError> { let untrusted = UntrustedToken::new(token).unwrap(); // danger! unfortunately we need to decode the DID from the jwt body before we have a public key to verify the jwt with @@ -118,9 +118,12 @@ impl TokenVerifier { let Some(aud) = claims.custom.get("aud") else { return Err(VerifyError::VerificationFailed("missing aud")); }; - if *aud != format!("did:web:{}#bsky_appview", self.domain) { - return Err(VerifyError::VerificationFailed("wrong aud")); - } + let Some(aud) = aud.strip_prefix("did:web:") else { + return Err(VerifyError::VerificationFailed("expected a did:web aud")); + }; + let Some((aud, _)) = aud.split_once("#") else { + return Err(VerifyError::VerificationFailed("aud missing #fragment")); + }; let Some(lxm) = claims.custom.get("lxm") else { return Err(VerifyError::VerificationFailed("missing lxm")); }; @@ -128,6 +131,12 @@ impl TokenVerifier { return Err(VerifyError::VerificationFailed("wrong lxm")); } - Ok(did.to_string()) + Ok((did.to_string(), aud.to_string())) + } +} + +impl Default for TokenVerifier { + fn default() -> Self { + Self::new() } }