feat(fe): add attribute consent screen for explicit user approval#3771
Open
sea-snake wants to merge 16 commits intosea-snake/icrc3-text-typesfrom
Open
feat(fe): add attribute consent screen for explicit user approval#3771sea-snake wants to merge 16 commits intosea-snake/icrc3-text-typesfrom
sea-snake wants to merge 16 commits intosea-snake/icrc3-text-typesfrom
Conversation
- Scenario 2 (explicit): continue page checks for pending attribute requests and redirects to /authorize/consent. Authorization proceeds in parallel. - Scenario 1 (OpenID): resume-openid-authorize checks needsConsentScreen before processing attributes. Redirects to consent page for non-implicit attributes. - Scenario 3 (standalone): AuthorizationChannel listens for attribute requests without prior delegation and navigates to consent page. - channelStore: add ii_attributes and ii-icrc3-attributes to scopes.
Wire up both legacy (prepare_attributes/get_attributes) and ICRC-3 (prepare_icrc3_attributes/get_icrc3_attributes) response flows in the consent page's handleContinue handler.
- Validate icrc95DerivationOrigin in attribute requests using the same validateDerivationOrigin used by the authorization store. - Add icrc95DerivationOrigin to Icrc3AttributesParamsSchema. - Consent page derives effectiveOrigin from derivationOrigin or channel origin, independent of authorizationContextStore. - Clean up unused imports.
…ders When a standalone ii-icrc3-attributes request arrives without a delegation, resolve the authorizeChannel promise so the auth UI renders. After the user authenticates, continue/+page.svelte picks up the pending attribute request and redirects to consent.
The consent screen redirect in resume-openid-authorize was breaking the existing ICRC-3 attribute e2e tests. The OpenID flow consent integration will be added in a follow-up with proper e2e coverage.
…textStore crash The standalone ii-icrc3-attributes listener was resolving the auth channel promise, causing the authorize UI to render without an authorization context set — crashing authorizationContextStore. Standalone flow deferred to a follow-up.
addEventListener emits pending requests synchronously during the call. Store the result in a variable and unsubscribe in the next microtask.
Replace the isAuthenticating flag (which blocked consent rendering) with a request-driven architecture: - New authorizeFlowComplete store: layout shows children when false, redirect screen when true. - Idle timeout: starts after each channel.send() response via a new 'response' event on the Channel interface. Resets when new requests arrive. Fires when no more requests come in within the timeout window. - AuthorizationChannel handles both icrc34_delegation and ii-icrc3-attributes requests, resolving the auth UI for either. - authorizationStore.authorize() is now pure business logic — no UI state. - AuthorizationContext: authRequest and requestId are optional (only present when delegation was requested). - Channel interface: added 'response' event, implemented in both PostMessageChannel and LegacyChannel.
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.
Motivation
When apps request user attributes (email, name, etc.) via ICRC-3, there's no UI for users to review and approve what's being shared. The existing authorize flow was built for a single path (authenticate → delegate → close) and its
isAuthenticatingflag immediately hid all layout children, making it impossible to show a consent screen after delegation.Changes
Architecture: request-driven authorize flow
Replaced the
isAuthenticatingboolean with a request-driven architecture:authorizeFlowCompletestore — Layout shows children whenfalse, redirect/close screen whentrue.channel.send()response via a new"response"event on theChannelinterface. Resets when new requests arrive. Fires when no more requests come in within the timeout window (500ms).AuthorizationChannelhandles bothicrc34_delegationandii-icrc3-attributesrequests, resolving the auth UI for either.authorizationStore.authorize()is now pure business logic — no UI state.AuthorizationContexthas optionalauthRequest/requestId(only present when delegation was requested)."response"event, implemented in bothPostMessageChannelandLegacyChannel.Attribute consent screen
/authorize/consentinside(panel)layout with checkboxes per attribute group.consent/utils.ts) —parseAttributeKey,isImplicitConsentAttribute,needsConsentScreen,buildConsentGroupswith email/verified_email merging.icrc95DerivationOriginfrom attribute request params.Deferred