Repository navigation
feat: recovery codes, self-service account recovery and passkey management - #211
Merged
Merged
Conversation
Add client methods for the auth API v0.20 recovery routes, the bearer route rules that mirror their adapter manifest credentials, and the shared flows the bundled screens of every binding build on. A session issued by a recovery code or a completed account recovery is tracked by the client and mirrored into the session state. After a passkey or TOTP enrollment made from it, the client refreshes the session so the new access token no longer carries the recovery claim.
Add the sign-in side of account recovery to the prebuilt UI: - /recovery-code signs in with a recovery code - /recovery-codes generates and shows a first set after a passkey is enrolled, and asks the user to confirm they saved it - /account-recovery runs self-service recovery: channel, code, the waiting period, then completion - /recovery/cancel takes the token from the notice link's fragment, drops it from the address bar and cancels the request The sign-in screen offers recovery only where the public configuration reports it, and a recovery session goes straight to passkey enrollment, which it cannot skip. Refs #185, #208
Export router-free settings sections built on the public primitives: - PasskeyManagement lists passkeys with name, kind and last use, renames and deletes them, adds another, and asks for a second passkey when there is only one - RecoveryCodeSettings shows the codes left and generates or replaces a set, stepping up with the passkey when the API asks for it - RecoveryRequests lists open account recovery requests with cancel - AccountSecurity renders all three Refs #185, #186, #208
This was referenced Oct 25, 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.
Builds the v0.20 "never locked out" features in the client SDK and the React prebuilt UI, against the auth API's
docs/account-recovery.mdand adapter manifest on main.Client (
@seamless-auth/client)getRecoveryCodeStatus(),generateRecoveryCodes()(a403 step_up_requiredwhen replacing a set is recognized byisStepUpRequired();generateRecoveryCodesWithStepUp()runs the step-up and retries),redeemRecoveryCode(code).startAccountRecovery(channel),verifyAccountRecovery(code),getAccountRecoveryStatus(),completeAccountRecovery(),cancelAccountRecovery(cancelToken),listAccountRecoveryRequests(),cancelAccountRecoveryRequest(id).isRecoverySession()and the session state'srecoverySession; session actionsredeemRecoveryCodeandcompleteAccountRecovery. After a passkey registration or TOTP enrollment from a recovery session the client callsPOST /refresh(newTransport.refresh()), so the access token drops the recovery claim.ROUTE_RULESfor every recovery route, mirroring the manifest credentials (preAuth,access,none), withissueon redeem and complete.loadRecoveryOptions,recoveryCancelTokenFromHash,cancelRecoveryFromLink,recoveryErrorMessage,recoveryCodesText,passkeyKind,passkeyDisplayName, plusgetRecoveryErrorCode()andisEnrollmentRequired().credentials,updateCredential,deleteCredentialon/users/credentials), so nothing new was added there.React (
@seamless-auth/react)#185 recovery codes
/recovery-codes, shown after a passkey is enrolled: generates and shows a first set (or a new one once every code is spent), copy and download, and a "saved them" confirmation before continuing./recovery-code), which redeems the code and sends the user to enroll a passkey.RecoveryCodeSettingsto regenerate from account settings, stepping up with the passkey when the API asks.#186 passkey management
PasskeyManagement: list with name, kind (synced, device, security key) and last used; rename; delete with confirmation (stronger warning for the last one); add another; a nudge towards a second passkey when only one exists.#208 self-service recovery
/recovery/cancel: reads the token from the fragment, drops it from the address bar, posts it, and shows the outcome./account-recoveryfrom sign-in, offered only when the public config reportsaccountRecovery: channel, code, the waiting period (completesAt), "check again", then completion. Handles503 recovery_notice_failed,403 account_recovery_disabled, a wrong code and a lapsed pre-auth token./register-passkey, which cannot be skipped in that state.RecoveryRequests: open requests with cancel in settings.AccountSecurityrenders all three settings sections.Also:
@seamless-auth/typesbumped to^0.31.0(the changeset for that ships with #210), Svelte's session class exposes the new actions, and the client, React and React Native READMEs document it all.Checks
Contract notes
@seamless-auth/types0.31.0 does not publish theGET /recovery/requestslist shape, or the recovery error codes.AccountRecoveryRequestis composed fromAccountRecoveryStatusplusidandchannel, andRecoveryErrorCodeis a local union.GET /users/medoes not say whether the session is a recovery session, so the client only knows it in memory. After a reload it cannot route a half-recovered user to enrollment or refresh after enrolling (the adapter's silent refresh fixes the claim once the access token expires).Needs an auth API with account recovery (v0.20) and a server adapter that proxies its manifest routes, including
POST /auth/refresh.Closes #185
Closes #186
Closes #208