Repository navigation
feat(enrollment): track and invite passkey enrollment - #351
Merged
Merged
Conversation
Adds GET /admin/enrollment for enrollment progress per organization and POST /admin/enrollment/invites to email users a notice to sign in and add a passkey. A new prompt_passkey_enrollment setting makes code and magic link sign-ins return nextStep: 'enroll_passkey' for a user with no passkey. Part of #338.
4 tasks
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.
Closes #338 (epic #334). Contract change. It adds two admin routes, a system config key,
nextStepon code and magic link sign-ins, an auth event type and a delivery kind. The ripple PRs are listed below.Changes
GET /admin/enrollment(admin read)none,one,two_or_more. TOTP does not count.organizationId,status,imported(users fromPOST /admin/users/import) and emailsearch. LIKE wildcards in the search are matched literally.summarycounts every match whatever thestatusfilter, which also feeds the coverage report in No authentication coverage report for assessment and insurance responses #178.POST /admin/enrollment/invites(admin write)signInUrlon a configured origin, default<frontend_url>/login) and carries no credential.userIds(up to 200) or anorganizationId. For an organization, members at or belowstatusare invited 200 at a time, anyone invited in the last 24 hours is skipped, andremainingsays what is left.not_found,already_enrolled,recently_invited,delivery_failed.x-seamless-auth-delivery-mode: external, each result carries the delivery for the caller to send instead. This does not require the service token, because the invite holds no secret.admin_enrollment_invite_sentagainst the acting admin.users.enrollment_invited_atrecords the last invite. This needs a migration.prompt_passkey_enrollment(default off, envPROMPT_PASSKEY_ENROLLMENT)With it on, these sign-ins carry
nextStep: 'enroll_passkey'for a user with no passkey: email and phone code sign-ins, the registration email code, and the magic link poll. That is what sends an invited user into enrollment, whichever way they sign in.Dependencies
@seamless-auth/types0.26.0 and@seamless-auth/messaging0.2.0 (plus aws and twilio). That also clears the lastAGPL-3.0-onlylockfile entries left after #335.Ripple
Verification
enrollment_invited_atupdates. The migration ran up and down cleanly.signInUrl, and the external delivery exemption. No findings.npm run typecheck,lint,format:check,test:run(1585),build,check:changeset-bumpandnpm audit --omit=dev --audit-level=high(0) all pass. Branch coverage is above the 95% pre-commit gate.