Add account recovery — email verification + password reset (#167)#181
Merged
Conversation
Phase 3 of the auth epic (#161), building on Auth (#163) + Mailer (#166). Adds Auth.verify_email/1, request_email_verification/1, request_password_reset/1, reset_password/2. - Single-use, hashed, expiring tokens stored in the existing auth_tokens table with a new `purpose` column (refresh | verify_email | reset_password). Refresh now sets and checks purpose, so a recovery link can't be redeemed at /auth/refresh (and vice versa). - register/2 emails a verification link when auth.verify_email is set. - request_password_reset always returns :ok (no user enumeration); emails a link only if the address exists. reset/verify tokens are single-use and expiry-checked. - New config: auth.verify_email, auth.verify_url / auth.reset_url, auth.verify_token_ttl (24h) / auth.reset_token_ttl (1h). auth_token schema + migration gain a `purpose` field. - Fake repo gains update/1. 9 new tests (verify flip + single-use + expiry + bad token, reset flow + single-use + expiry, no-enumeration, cross-purpose refresh rejection). 29 auth tests; full suite 766 (only the pre-existing esqlite-NIF failure). docs/modules.md + CHANGELOG updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
16 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.
Summary
Adds email verification and password reset to
Auth— sub-issue F (#167), the last runtime feature of the auth epic (#161). Builds onAuth(#163) +Mailer(#166); branched offdevelop.Design
auth_tokenstable with a newpurposecolumn (refresh/verify_email/reset_password). Only the SHA-256 hash is stored.refreshnow sets + checkspurpose, so a verification/reset link cannot be redeemed at/auth/refresh(and a refresh token can't verify/reset). Tested.request_password_resetalways returns:okand only emails if the address exists.register/2emails a verification link whenauth.verify_emailis on (off by default — no Mailer dependency for apps that don't want it).auth.verify_email,auth.verify_url/auth.reset_url,auth.verify_token_ttl(24h) /auth.reset_token_ttl(1h). Theauth_tokenschema + migration gainpurpose.Testing
9 new tests: verify-email (flip + single-use + expiry + bad token + opt-in default-off), password reset (full flow: old pw dead / new pw works + single-use + expiry), no-enumeration, and the cross-purpose rejection (a verify token is refused by
refresh). Fake repo gainedupdate/1. 29 auth tests; full suite 766, only the pre-existingwinn_sqlite_testsesqlite-NIF failure.Docs
docs/modules.md:purposein the schema/migration, the four recovery functions, recovery routes/handlers in the router example, and config. CHANGELOG updated.Part of #161. Closes #167 once merged. Completes Phase 3 — only #168 (the
winn create authscaffold + guide) remains.🤖 Generated with Claude Code