Add native (React Native) OAuth sign-in - #123
Draft
onelxj wants to merge 1 commit into
Draft
Conversation
React Native can't use Reboot's browser sign-in flow: there is no `window.location` to redirect and no cookie jar shared with the backend. Teach the same OAuth server and React client to run the standard authorization-code flow with PKCE that native apps use, so a mobile app writes the same `useSignIn()` / `useSignOut()` / `useUser()` as a web SPA does. Backend: - `Application(native_redirect_uris=[...])` lets an application claim the redirect URIs of its own first-party native apps. A client that registers only such URIs signs its user in directly, as the browser client already did; every other dynamically registered client still gets the consent screen, which is what stands between a user and an attacker who registers a client with their own `redirect_uri`. Expo development URIs are trusted by shape under `rbt dev run` only — deliberately not localhost, which MCP clients also register. - `/__/oauth/whoami` additionally accepts an `Authorization: Bearer` access token, so a native app can resolve its `default_ids` without hardcoding which state types are auto-constructed. React client: - `RebootClientProvider` takes an optional `nativeAuth`, and `useSignIn()` / `useSignOut()` dispatch to it. Omitted — as on the web — everything behaves exactly as before. - A new `@reboot-dev/reboot-react/native` subpath carries the whole OAuth protocol (discovery, RFC 7591 registration, PKCE, token exchange, refresh), plus `expoAuth()` for Expo apps. It adds no dependency to `@reboot-dev/reboot-react`: the pieces React Native has no standard answer for are passed in and typed structurally, which also lets an app's own type-checker confirm its installed Expo version matches. SHA-256 is carried here rather than taken from a platform module, for the same reason. The `bank-pydantic` mobile front end now signs in, and is scoped to the signed-in user like the web front end. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Current Aviator status
This pull request is currently open (not queued). How to mergeTo merge this PR, comment
See the real-time status of this PR on the
Aviator webapp.
Use the Aviator Chrome Extension
to see the status of your PR within GitHub.
|
onelxj
marked this pull request as draft
August 5, 2026 15:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
React Native can't use Reboot's browser sign-in flow: there is no
window.locationto redirect and no cookie jar shared with the backend. Teach the same OAuth server and React client to run the standard authorization-code flow with PKCE that native apps use, so a mobile app writes the sameuseSignIn()/useSignOut()/useUser()as a web SPA does.Backend:
Application(native_redirect_uris=[...])lets an application claim the redirect URIs of its own first-party native apps. A client that registers only such URIs signs its user in directly, as the browser client already did; every other dynamically registered client still gets the consent screen, which is what stands between a user and an attacker who registers a client with their ownredirect_uri. Expo development URIs are trusted by shape underrbt dev runonly — deliberately not localhost, which MCP clients also register./__/oauth/whoamiadditionally accepts anAuthorization: Beareraccess token, so a native app can resolve itsdefault_idswithout hardcoding which state types are auto-constructed.React client:
RebootClientProvidertakes an optionalnativeAuth, anduseSignIn()/useSignOut()dispatch to it. Omitted — as on the web — everything behaves exactly as before.@reboot-dev/reboot-react/nativesubpath carries the whole OAuth protocol (discovery, RFC 7591 registration, PKCE, token exchange, refresh), plusexpoAuth()for Expo apps. It adds no dependency to@reboot-dev/reboot-react: the pieces React Native has no standard answer for are passed in and typed structurally, which also lets an app's own type-checker confirm its installed Expo version matches. SHA-256 is carried here rather than taken from a platform module, for the same reason.The
bank-pydanticmobile front end now signs in, and is scoped to the signed-in user like the web front end.