feat(ui): highlight auth flow state machine (YPE-1034, PR 2/3)#285
Draft
cameronapak wants to merge 2 commits into
Draft
feat(ui): highlight auth flow state machine (YPE-1034, PR 2/3)#285cameronapak wants to merge 2 commits into
cameronapak wants to merge 2 commits into
Conversation
Turn a color tap without a session or the `highlights` permission into an applied highlight across the two auth paths, behind the internal HIGHLIGHTS_LIVE flag. Core: DataExchangeClient (POST /data-exchange/token, Zod-validated), the hosted-grant URL builder + callback parser/handler, and an optimistic permission cache on YouVersionPlatformConfiguration seeded from `granted_permissions` on the sign-in and data-exchange callbacks (server 401/403 invalidates it). SignInWithYouVersionResult gains `permissions`. Hooks: useHighlightAuthActions exposes one-fell-swoop sign-in (requesting `highlights`), the just-in-time data-exchange redirect, permission reads/invalidation, and the data-exchange return handler. UI: useBibleReaderHighlights runs the state machine — pending highlights persist to sessionStorage (~10-min expiry) across the redirect round-trip and apply on a granted return; a permission confirm dialog (copy matched to the native SDK, en/fr/es) gates the grant. Write failures route by status (401/403 re-prompts and keeps pending; 5xx/network reverts and discards). Apply/remove writes are serialized through a FIFO queue with per-verse ownership, closing the two concurrency windows PR1 documented. Copy/share-only behavior with no auth provider is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…on hydrates The resume effect consumed the data-exchange return status into a local, but bailed on `!isAuthenticated` first. The shipped YouVersionAuthProvider hydrates userInfo asynchronously, so the first effect run after a redirect return is always unauthenticated: the status was consumed and lost, and when the session flipped the cancel/failure branch was skipped — the pending highlight survived a decline and the just-declined dialog re-opened. Discard the pending highlight at consume time for any non-granted return, before the auth gate: it runs exactly once and needs no session (a decline kills the intent regardless of who signs in). Tests: the cancel-return test previously set signedIn=true synchronously — a timing the real provider never produces — which hid the bug. It now mounts signed out and flips the session after mount (failed against the old code, passes now), plus a failure-status variant with the same timing and the granted-return test aligned for realism. Also document the three review-deferred follow-ups (expired-token 401 misrouting, resume-write failure handling, remove-failure re-prompt) at their code sites and in the changeset. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: f275bbf 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 |
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.
Description
PR 2 of the YPE-1034 stack (stacked on #283 — do not merge before it; retarget to main once PR 1 lands). Implements the highlight auth flow state machine: tapping a highlight color without a session or the
highlightspermission now routes through sign-in or a just-in-time data-exchange grant, with the user's intent preserved across the redirect.Everything remains dark-launched behind the internal
HIGHLIGHTS_LIVEflag (off).What's in it
DataExchangeClient(POST /data-exchange/token→ consent URL → callback parsing, mirroring platform-sdk-swift#179),granted_permissionsparsed from the sign-in callback, optimistic permission cache onYouVersionPlatformConfiguration(cleared on sign-out, invalidated by any 401/403)useHighlightAuthActions— one-fell-swoop sign-in requestinghighlights, data-exchange redirect, permission reads/invalidation; safe without an auth providerFailure routing
console.error(snackbar is YPE-3873), discard pendingKnown assumptions / deferred (documented in code + changeset)
/data-exchangepage is assumed to redirect back withdata_exchange_status+granted_permissions; handling is isolated inbuildDataExchangeUrl/parseDataExchangeCallback— needs one live round-trip before flag flipVerification
Adversarially reviewed; the one blocker (declined consent return re-opening the dialog under real async session hydration) is fixed in f275bbf with tests rewritten to real provider timing. Full gate: 838 tests green (core 334, hooks 285, ui 219), typecheck + lint clean.
Related Issues
Relates to YPE-1034
Stacked on #283
🤖 Generated with Claude Code