Skip to content

Handle magic-link sign-in via universal links / app links - #52

Merged
akulsharma1 merged 1 commit into
mainfrom
akul/magic-link-deep-links
Aug 13, 2026
Merged

Handle magic-link sign-in via universal links / app links#52
akulsharma1 merged 1 commit into
mainfrom
akul/magic-link-deep-links

Conversation

@akulsharma1

Copy link
Copy Markdown
Contributor

Summary

Tapping a magic-link email (https://reflectionsprojections.org/auth/mobile/login?token=…) should open rp-mobile and sign the user in. The server half — serving .well-known/apple-app-site-association and .well-known/assetlinks.json on the domain — ships from rp-web (ReflectionsProjections/rp-web#134; assetlinks is already live). This PR adds everything on the app side, for both iOS and Android.

Changes

Domain association (both platforms)

  • iOS: associatedDomains: ['applinks:reflectionsprojections.org'] in app.config.js and com.apple.developer.associated-domains in the checked-in entitlements file.
  • Android: autoVerify https intent filter for host reflectionsprojections.org, path prefix /auth/mobile/login, in app.config.js and the checked-in AndroidManifest.xml (kept in sync since the native projects are committed).

Link handling

  • app/auth/mobile/login.tsx: expo-router route matching the link's path. Reads token, posts /auth/magic-links/verify with client: 'mobile', stores the JWT in SecureStore, checks /auth/info roles and routes to home — mirroring the existing Google sign-in flow. Invalid/expired tokens alert and return to sign-in.

Requesting a link

  • New (auth)/email-sign-in screen: email input → POST /auth/magic-links (client: 'mobile'", intent: 'login') → "check your email" state. Linked from the sign-in screen. Copy doesn't disclose whether an account exists (API returns 202 either way; mobile links require an existing USER role).
  • Typed APIRoutes entries for both magic-link endpoints.

Testing

  • npx tsc --noEmit: only the two pre-existing errors on main (tabs scrollRef, shiftsSlice); no new errors.
  • npx eslint on changed screens: no errors (2 pre-existing warnings in sign-in.tsx).
  • Manual (after a dev build): request a link from the email screen for a registered account, tap it in Mail/Gmail — app opens on the verify screen and lands on home signed in. adb shell pm get-app-links com.reflectionsprojections should show the domain verified; on iOS, long-press the link → "Open in rp-mobile".

Deployment notes

  • iOS: the App ID must have the Associated Domains capability enabled (EAS/Xcode automatic signing handles this on next build). Apple's CDN caches the AASA up to ~24h after rp-web#134 deploys; the "Associated Domains Development" toggle in iOS developer settings bypasses it for testing.
  • Android: assetlinks.json is already live with the release-cert fingerprint; verification happens at install/update.
  • Requires new store builds — this is native config, not OTA-updatable.

🤖 Generated with Claude Code

Tapping a magic-link email (https://reflectionsprojections.org/auth/mobile/login?token=...)
should open the app and sign the user in. This adds the app half of that:

- iOS: associatedDomains entitlement for applinks:reflectionsprojections.org
  (app.config.js + checked-in entitlements file)
- Android: autoVerify https intent filter for the /auth/mobile/login path
  (app.config.js + checked-in AndroidManifest.xml)
- app/auth/mobile/login.tsx: expo-router route matching the link path;
  posts the token to /auth/magic-links/verify with client mobile, stores
  the JWT, and routes to the tabs (or back to sign-in on failure)
- Email-entry screen to request a link (POST /auth/magic-links) plus a
  link to it from the sign-in screen
- Typed API routes for /auth/magic-links and /auth/magic-links/verify

The server half (apple-app-site-association / assetlinks.json on
reflectionsprojections.org) ships from rp-web.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@akulsharma1
akulsharma1 merged commit 9ccea93 into main Aug 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants