fix: handle colons in DID when parsing Basic Auth for git push

Author: Aaron Steven White
Commit e8a70b1cb4b0a432a159b218ac935bec5d1adcb7
Parent: d65077d1ee
Structural diff unavailable

These commits were pushed via plain git push, so no pre-parsed schemas are available. Install git-remote-cospan and re-push via panproto:// to see scope-level changes, breaking change detection, and semantic diffs.

brew install panproto/tap/git-remote-cospan
1 file changed +11 -2
@@ -40,6 +40,10 @@ struct PushTokenClaims {
4040 }
4141 
4242 /// Extract HTTP Basic Auth credentials from the Authorization header.
43+///
44+/// The username is a DID (`did:plc:abc123`) which contains colons.
45+/// The password is a JWT (starts with `eyJ`). We split at `:eyJ`
46+/// to find the boundary between DID and token.
4347 fn extract_basic_auth(headers: &axum::http::HeaderMap) -> Option<(String, String)> {
4448     let auth = headers.get("authorization")?.to_str().ok()?;
4549     let encoded = auth.strip_prefix("Basic ")?;
@@ -47,8 +51,13 @@ fn extract_basic_auth(headers: &axum::http::HeaderMap) -> Option<(String, String
4751         .decode(encoded)
4852         .ok()?;
4953     let text = String::from_utf8(decoded).ok()?;
50-    let (user, pass) = text.split_once(':')?;
51-    Some((user.to_string(), pass.to_string()))
54+    // JWT always starts with "eyJ" (base64 of '{"'). DIDs never contain this.
55+    if let Some(pos) = text.find(":eyJ") {
56+        Some((text[..pos].to_string(), text[pos + 1..].to_string()))
57+    } else {
58+        let (user, pass) = text.split_once(':')?;
59+        Some((user.to_string(), pass.to_string()))
60+    }
5261 }
5362 
5463 /// Verify a push token from git credentials.
cospan · schematic version control on atproto built on AT Protocol