feat(auth): request highlights permission at sign-in#280
Merged
Conversation
Wire the `highlights` permission through the auth flow. It rides alongside
OIDC scopes as a repeatable `requested_permissions[]` query param, not as a
scope, matching the YouVersion authorize contract.
- core: signIn/PKCE builder accept an optional `permissions` array
- hooks: useYVAuth().signIn({ permissions })
- ui: <YouVersionAuthButton permissions={['highlights']} />
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 9fb7e13 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 |
Passing undefined for optional params is identical to omitting them, so the if/else branch produced the same authorize URL either way. Collapse to a single call and update the three tests that asserted the bare signIn(url) shape. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dustin-Kelley
approved these changes
Jul 8, 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.
What
Lets apps request the
highlightspermission (and future data-exchange permissions) at sign-in.Why it's not a scope
highlightsis deliberately not an OIDC scope. Per the YouVersion authorize contract, it rides alongsidescopeas a repeatable query param and is authorized via a separate per-app ACL:Scopes stay generic/portable (
profile,email); bespoke YouVersion data (highlights, and laterprayer_requests, etc.) lives inrequested_permissions[].Changes
signIn(url, scopes?, permissions?)+ PKCE builder appendrequested_permissions[]useYVAuth().signIn({ permissions })<YouVersionAuthButton permissions={['highlights']} />Scopes and permissions are separate args. Existing scope-only calls are unaffected.
Test plan
requested_permissions[], multiple perms, omitted-when-empty, and not folded intoscopeuseYVAuth(19 pass)pnpm typecheckclean, Prettier + ESLint cleanNot in scope
Grant verification after callback. This wires up requesting; how a consumer confirms the grant (token claim / userinfo / ACL call) is unresolved and left for a follow-up once the backend contract is known.
🤖 Generated with Claude Code
Greptile Summary
This PR adds an optional
permissionsparameter to the sign-in stack — core PKCE builder,YouVersionAPIUsers.signIn,useYVAuth, andYouVersionAuthButton— so apps can request YouVersion data-exchange permissions (starting withhighlights) at authorize time. The newrequested_permissions[]query params ride alongside OIDCscopeas the backend contract requires and are kept fully separate from it.SignInWithYouVersionPKCEAuthorizationRequestBuilderappends each permission as arequested_permissions[]param; three new test cases cover single permission, multiple permissions, and the empty/omit case.useYVAuth().signInaccepts apermissionsarray and forwards it via optional chaining, replacing the previous redundant if/else branch.YouVersionAuthButtonexposes apermissionsprop typed asSignInWithYouVersionPermissionValues[]; all three packages receive aminorchangeset bump.Confidence Score: 5/5
Additive change with no impact on existing call sites; permissions are appended as typed, URL-encoded query params and never mixed into the OIDC scope string.
The change is backward compatible at every layer, the new code paths are exercised by targeted unit tests (including a guard that
highlightsnever appears inscope), and the PKCE URL builder usesURLSearchParams.appendwhich handles encoding correctly.No files require special attention; the only suggestion is adding
SignInWithYouVersionPermissionValuesto the UI package re-export list for a complete public surface.Important Files Changed
permissionsparameter tomakeandauthorizeURL; appends each permission as arequested_permissions[]query param. Logic is correct and well-commented.permissionsarray throughYouVersionAPIUsers.signInto the PKCE builder. Backward compatible; no logic issues.permissionsto thesignInparams object and forwards it via optional chaining, replacing the previous redundant if/else branch. Clean and correct.permissionsprop and passes it through tosignIn. JSDoc example importsSignInWithYouVersionPermissionbut the existing docblock example doesn't demonstrate its usage — minor pre-existing doc gap.scopeparam. Good coverage.permissionsforwarding. All assertions align with the updated implementation.minorbumps, which is appropriate for a backward-compatible additive API change.Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant App participant YouVersionAuthButton participant useYVAuth participant YouVersionAPIUsers participant PKCEBuilder as SignInWithYouVersionPKCEAuthorizationRequestBuilder participant Browser App->>YouVersionAuthButton: "render permissions={['highlights']}" YouVersionAuthButton->>useYVAuth: "signIn({ scopes, permissions })" useYVAuth->>YouVersionAPIUsers: signIn(url, scopes, permissions) YouVersionAPIUsers->>PKCEBuilder: make(appKey, redirectURL, scopes, permissions) PKCEBuilder->>PKCEBuilder: authorizeURL(..., scopes, permissions) Note over PKCEBuilder: queryParams.set('scope', 'openid profile')<br/>queryParams.append('requested_permissions[]', 'highlights') PKCEBuilder-->>YouVersionAPIUsers: "{ url, parameters }" YouVersionAPIUsers->>Browser: "window.location.href = url" Note over Browser: /auth/authorize?scope=openid+profile&requested_permissions%5B%5D=highlights%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant App participant YouVersionAuthButton participant useYVAuth participant YouVersionAPIUsers participant PKCEBuilder as SignInWithYouVersionPKCEAuthorizationRequestBuilder participant Browser App->>YouVersionAuthButton: "render permissions={['highlights']}" YouVersionAuthButton->>useYVAuth: "signIn({ scopes, permissions })" useYVAuth->>YouVersionAPIUsers: signIn(url, scopes, permissions) YouVersionAPIUsers->>PKCEBuilder: make(appKey, redirectURL, scopes, permissions) PKCEBuilder->>PKCEBuilder: authorizeURL(..., scopes, permissions) Note over PKCEBuilder: queryParams.set('scope', 'openid profile')<br/>queryParams.append('requested_permissions[]', 'highlights') PKCEBuilder-->>YouVersionAPIUsers: "{ url, parameters }" YouVersionAPIUsers->>Browser: "window.location.href = url" Note over Browser: /auth/authorize?scope=openid+profile&requested_permissions%5B%5D=highlightsReviews (2): Last reviewed commit: "refactor(hooks): collapse redundant sign..." | Re-trigger Greptile