feat(auth)!: stop persisting ID token; persist decoded profile instead#248
Merged
Conversation
🦋 Changeset detectedLatest commit: d2e7621 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
ca7654f to
a4ac0a4
Compare
cameronapak
reviewed
Jun 3, 2026
cameronapak
previously approved these changes
Jun 3, 2026
Collaborator
cameronapak
left a comment
There was a problem hiding this comment.
Please consider the feedback from DeepWiki and from Greptile. This is approved, but please, please, please do not merge the changeset PR after this yet. If we're making a breaking major change bump, I have some things I need to prep in another PR that would merge alongside it
- Decode ID token once at sign-in to derive userInfo, then discard it - Persist the decoded profile (Zod-validated on read) so it survives reloads - Clear stored profile on sign-out and on unrecoverable session expiry - core: drop idToken from saveAuthData; add saveUserInfo/storedUserInfo and getStoredUserInfo() - hooks: remove AuthenticationState.idToken; provider rehydrates from stored profile - ui: update authenticated-user test helper BREAKING CHANGE: the ID token is no longer exposed or persisted. - Removed AuthenticationState.idToken (use userInfo for profile data) - Removed the YouVersionPlatformConfiguration.idToken getter - saveAuthData(accessToken, refreshToken, expiryDate) no longer accepts an idToken arg
- Add optional `userInfo` prop to YouVersionProvider and YouVersionAuthProvider
so a host can own sign-in and pass the resulting profile down
- When `userInfo` is provided (including `null`), skip the web token/OAuth init
and drive `userInfo`/`isAuthenticated` from the supplied profile
- Construct `YouVersionUserInfo` from the host-supplied `YouVersionUserInfoJSON`
- Add `onSignInPress`/`onSignOutPress` callbacks to BibleReader Root and UserMenu
- Bridge sign-in/out to host-supplied native actions (e.g. Expo PKCE), falling
back to the Web SDK's own `signIn`/`signOut` when not provided
a4ac0a4 to
818528e
Compare
…tate
- Require `id` on stored profiles: getStoredUserInfo() returns null when
the persisted profile lacks an `id`, so a tampered/empty `{}` can't flip
isAuthenticated true with an empty profile (schema stays all-optional to
match the Swift SDK)
- Stop attaching the raw ID token to SignInWithYouVersionResult: remove
`idToken` from extractSignInResult and drop the field from the
SignInWithYouVersionResult type/constructor, closing the in-memory
exposure path for callback consumers
- Clear persisted tokens and profile on callback failure: handleAuthCallback
now calls clearAuthTokens() in its catch block so an error after
saveAuthData/saveUserInfo can't leave the user looking signed in
- Update tests/mocks to drop the removed `idToken` field
818528e to
d2e7621
Compare
cameronapak
approved these changes
Jun 4, 2026
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.
Decode ID token once at sign-in to derive userInfo, then discard it
BREAKING CHANGE: the ID token is no longer exposed or persisted.
Greptile Summary
This PR removes the raw ID token from the auth persistence layer: the token is now decoded once at sign-in to produce a Zod-validated user profile, which is persisted in place of the token itself. Token refresh no longer requires a stored ID token, sign-out clears the profile alongside the OAuth tokens, and a new host-controlled mode lets native Expo wrappers pass an externally-obtained profile directly into the provider.
YouVersionPlatformConfiguration:saveAuthDatadrops theidTokenparameter; newsaveUserInfo/storedUserInfohandle the decoded profile;clearAuthTokensnow wipes the profile as well as the OAuth tokens.YouVersionAPIUsers:handleAuthCallbackpersists the decoded profile after exchange and clears everything (tokens + profile) if an error is thrown;getStoredUserInfo()reads the validated profile from storage;refreshTokensno longer needs or preserves a stored ID token.YouVersionAuthProvider: rehydratesuserInfoviagetStoredUserInfo()instead of re-decoding the token; adds auserInfoprop for host-controlled (native) auth flows.Confidence Score: 4/5
Safe to merge after addressing the legacy idToken cleanup gap; all new auth paths are well-tested and logically sound.
The clearAuthTokens method no longer removes the idToken localStorage key. Existing users who signed in with the previous SDK version carry a raw ID token in storage; after upgrading and signing out, that key persists indefinitely because nothing in the new code touches it. The stated security goal of never keeping the signed token in storage is not met for this population until they uninstall or manually clear storage.
packages/core/src/YouVersionPlatformConfiguration.ts — the clearAuthTokens method needs a one-line migration to remove the legacy idToken key.
Important Files Changed
Comments Outside Diff (2)
packages/core/src/Users.ts, line 192-201 (link)extractSignInResultstill attachesidTokento the result — partial removal of the exposure pathhandleAuthCallbackno longer persists the ID token, but it still returns aSignInWithYouVersionResultwhoseidTokenfield is set (viaextractSignInResult).processCallback()inuseYVAuthreturns this object directly, so any consumer callingresult.idTokencan still read the raw token from memory. If the intent is to fully remove the exposure vector,idTokenshould be omitted from the result constructed insideextractSignInResult.Prompt To Fix With AI
packages/core/src/Users.ts, line 148-154 (link)saveAuthData/saveUserInfoon errorIf an exception is raised after
saveAuthDataandsaveUserInfohave already written to localStorage (e.g.window.history.replaceStatethrowing in a restrictive browser environment), the catch block removes the PKCE/OAuth temporary keys but leaves the persisted tokens and user profile intact. On the next page load the user would be treated as authenticated, while the provider also exposes the error that was thrown. AddingYouVersionPlatformConfiguration.clearAuthTokens()at the top of the catch block would make the failure path consistent with sign-out semantics.Prompt To Fix With AI
Prompt To Fix All With AI
Reviews (3): Last reviewed commit: "fix(auth): harden sign-in result and cal..." | Re-trigger Greptile