···
// allowedMobileRedirectURIs contains the EXACT allowed redirect URIs for mobile apps.
13
-
// SECURITY: Only Universal Links (HTTPS) are allowed - cryptographically bound to app.
14
+
// Per atproto OAuth spec (https://atproto.com/specs/oauth#mobile-clients):
15
+
// - Custom URL schemes are allowed for native mobile apps
16
+
// - The scheme must match the client_id hostname in REVERSE-DOMAIN order
17
+
// - For client_id https://coves.social/..., the scheme is "social.coves"
19
+
// We support two redirect URI types:
20
+
// 1. Custom scheme: social.coves:/callback (per atproto spec, simpler for mobile)
21
+
// 2. Universal Links: https://coves.social/app/oauth/callback (cryptographically bound)
15
-
// Universal Links provide strong security guarantees:
23
+
// Universal Links provide stronger security guarantees but require:
// - iOS: Verified via /.well-known/apple-app-site-association
// - Android: Verified via /.well-known/assetlinks.json
18
-
// - System verifies domain ownership before routing to app
19
-
// - Prevents malicious apps from intercepting OAuth callbacks
21
-
// Custom URL schemes (coves-app://, coves://) are NOT allowed because:
22
-
// - Any app can register the same scheme and intercept tokens
23
-
// - No cryptographic binding to app identity
24
-
// - Token theft is trivial for malicious apps
26
-
// See: https://atproto.com/specs/oauth#mobile-clients
var allowedMobileRedirectURIs = map[string]bool{
28
-
// Universal Links only - cryptographically bound to app
27
+
// Custom scheme per atproto spec (reverse-domain of coves.social)
28
+
"social.coves:/callback": true,
29
+
"social.coves://callback": true, // Some platforms add double slash
30
+
"social.coves:/oauth/callback": true, // Alternative path
31
+
"social.coves://oauth/callback": true,
32
+
// Universal Links - cryptographically bound to app (preferred for security)
"https://coves.social/app/oauth/callback": true,
// isAllowedMobileRedirectURI validates that the redirect URI is in the exact allowlist.
33
-
// SECURITY: Exact URI matching prevents token theft by rogue apps that register the same scheme.
37
+
// SECURITY: Exact URI matching prevents token theft by rogue apps.
35
-
// Custom URL schemes are NOT cryptographically bound to apps:
36
-
// - Any app on the device can register "coves-app://" or "coves://"
37
-
// - A malicious app can intercept deep links intended for Coves
38
-
// - Without exact URI matching, the attacker receives the sealed token
39
+
// Per atproto OAuth spec, custom schemes must match the client_id hostname
40
+
// in reverse-domain order (social.coves for coves.social), which provides
41
+
// some protection as malicious apps would need to know the specific scheme.
40
-
// This function performs EXACT matching (not scheme-only) as a security measure.
41
-
// For production, migrate to Universal Links (iOS) or App Links (Android).
43
+
// Universal Links (https://) provide stronger security as they're cryptographically
44
+
// bound to the app via .well-known verification files.
func isAllowedMobileRedirectURI(redirectURI string) bool {
// Normalize and check exact match
return allowedMobileRedirectURIs[redirectURI]