feat(sso): App Links autoVerify callback + paired-host trust check
All checks were successful
PR Checks / android-build (pull_request) Successful in 20m53s
All checks were successful
PR Checks / android-build (pull_request) Successful in 20m53s
Add the app side of Android App Links (M9 follow-up, docs/android/APP_LINKS.md), layered on the M9 Part 2 native SSO callback: - Build-time `appLinkHost` Gradle property -> BuildConfig.APP_LINK_HOST + manifestPlaceholders["appLinkHost"]. autoVerify needs a literal host, so the generic multi-tenant build leaves it empty (placeholder falls back to the reserved runic-gateway.invalid sentinel, making the filter inert); a white-label build bakes one host with -PappLinkHost=play.myshard.com. - Manifest: an autoVerify https `/mobile/callback` intent-filter beside the unchanged custom-scheme one (the permanent fallback). - SsoAuthManager: request the https App Link redirect_uri iff the baked host matches the paired shard host; matchesAppLinkCallback() enforces a paired-host trust check (host must equal the currently-paired base URL host) as defense-in-depth. Both matchers feed the same complete()/exchange path. - MainActivity routes custom-scheme and App Link callbacks identically. +5 JVM tests (SsoAuthManagerTest -> 14). Built green (JDK 21, -Pksp.incremental=false); white-label host substitution verified in the merged manifest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
This commit is contained in:
@@ -39,8 +39,8 @@
|
||||
<!-- Native SSO callback (M9, PLAN.md §4.2). The bridge deep-links the
|
||||
one-time authorization code back to this fixed, app-owned custom
|
||||
scheme; it must match SsoAuthManager.REDIRECT_URI and the backend's
|
||||
MOBILE_AUTH_REDIRECT_URIS allowlist exactly. Custom scheme only for
|
||||
now — HTTPS App Links are deferred (docs/android/APP_LINKS.md). -->
|
||||
MOBILE_AUTH_REDIRECT_URIS allowlist exactly. This is the permanent
|
||||
fallback on every build (docs/android/APP_LINKS.md). -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -50,6 +50,22 @@
|
||||
android:host="auth"
|
||||
android:path="/callback" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- App Links hardening (docs/android/APP_LINKS.md): a verified https
|
||||
callback that only the domain's real owner can claim. autoVerify
|
||||
needs a literal host, so ${appLinkHost} is baked at build time
|
||||
(build.gradle.kts). The generic build leaves it as the reserved
|
||||
runic-gateway.invalid sentinel — the filter then matches no real
|
||||
link and never verifies. A white-label build sets -PappLinkHost. -->
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="${appLinkHost}"
|
||||
android:path="/mobile/callback" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- The embedded distributor's persistent ntfy connection (M7, PLAN.md §11).
|
||||
|
||||
Reference in New Issue
Block a user