feat(sso): App Links autoVerify callback + paired-host trust check #17

Merged
whitlocktech merged 2 commits from feat/app-links into main 2026-07-21 00:20:52 +00:00
Member

App side of Android App Links (M9 follow-up), layered on the M9 Part 2 native SSO callback (#16, now merged to main). Companion PRs: website #81, docs #25. Spec: docs/android/APP_LINKS.md.

What

  • Build-time appLinkHost Gradle property (default empty) → BuildConfig.APP_LINK_HOST + manifestPlaceholders["appLinkHost"]. Android autoVerify needs a literal host, so the generic multi-tenant build leaves it empty (the placeholder falls back to the reserved runic-gateway.invalid sentinel, making the filter inert — matches no real link, never verifies). A white-label/first-party 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 on every build).
  • SsoAuthManager: requests the https App Link redirect_uri iff the baked host matches the paired shard host; matchesAppLinkCallback() enforces a paired-host trust check (callback host must equal the currently-paired base-URL host) as defense-in-depth. Both matchers feed the same complete()//exchange path — no second auth path.
  • MainActivity routes custom-scheme and App Link callbacks identically.

Tests / build

+5 JVM tests (SsoAuthManagerTest14). Built green (JDK 21, -Pksp.incremental=false: :app:processDebugMainManifest :app:testDebugUnitTest); white-label -PappLinkHost=play.myshard.com verified to bake into the merged manifest, default build verified inert.

Version bump is CI-driven (conventional-commit release.yml) — no manual bump. Open QA: on-device verification (adb shell pm get-app-links) against a shard serving assetlinks.json — requires a white-label build baking that host.


🤖 AI-assisted: authored with Claude Code (Opus 4.8); commits carry a Co-Authored-By: Claude trailer.

🤖 Generated with Claude Code

App side of Android **App Links** (M9 follow-up), layered on the M9 Part 2 native SSO callback (#16, now merged to `main`). Companion PRs: website [#81](https://gitea.whitlocktech.com/RunicGateway/website/pulls/81), docs [#25](https://gitea.whitlocktech.com/RunicGateway/docs/pulls/25). Spec: `docs/android/APP_LINKS.md`. ## What - **Build-time `appLinkHost`** Gradle property (default empty) → `BuildConfig.APP_LINK_HOST` + `manifestPlaceholders["appLinkHost"]`. Android `autoVerify` needs a **literal host**, so the generic multi-tenant build leaves it empty (the placeholder falls back to the reserved `runic-gateway.invalid` sentinel, making the filter **inert** — matches no real link, never verifies). A white-label/first-party 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 on every build). - **`SsoAuthManager`:** requests the `https` App Link `redirect_uri` iff the baked host matches the paired shard host; `matchesAppLinkCallback()` enforces a **paired-host trust check** (callback host must equal the currently-paired base-URL host) as defense-in-depth. Both matchers feed the same `complete()`/`/exchange` path — no second auth path. - **`MainActivity`** routes custom-scheme and App Link callbacks identically. ## Tests / build +5 JVM tests (`SsoAuthManagerTest` → **14**). Built green (JDK 21, `-Pksp.incremental=false`: `:app:processDebugMainManifest :app:testDebugUnitTest`); white-label `-PappLinkHost=play.myshard.com` verified to bake into the merged manifest, default build verified inert. Version bump is CI-driven (conventional-commit `release.yml`) — no manual bump. **Open QA:** on-device verification (`adb shell pm get-app-links`) against a shard serving `assetlinks.json` — requires a white-label build baking that host. --- 🤖 AI-assisted: authored with **Claude Code** (Opus 4.8); commits carry a `Co-Authored-By: Claude` trailer. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
wtclaude added 1 commit 2026-07-20 23:40:01 +00:00
feat(sso): App Links autoVerify callback + paired-host trust check
All checks were successful
PR Checks / android-build (pull_request) Successful in 20m53s
987ddb54f8
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
whitlocktech approved these changes 2026-07-20 23:43:54 +00:00
whitlocktech added 1 commit 2026-07-20 23:44:04 +00:00
Merge branch 'main' into feat/app-links
All checks were successful
PR Checks / android-build (pull_request) Successful in 10m39s
3050443aac
whitlocktech scheduled this pull request to auto merge when all checks succeed 2026-07-20 23:44:15 +00:00
whitlocktech merged commit 0ea6495d9e into main 2026-07-21 00:20:52 +00:00
whitlocktech deleted branch feat/app-links 2026-07-21 00:20:52 +00:00
Sign in to join this conversation.
No description provided.