Repository navigation
feat(auth): restore password recovery (#96) - #99
Merged
Merged
Conversation
The "Forgot your password?" flow added in 2.x lived in toothfairy/urls.py and was lost with the rename to yggdrasil in 3.0, so nobody could reset a password. It comes back in common/ (auth in maxillo/ is legacy, not a pattern) as Django's token-based reset, with: - the branded text + HTML email the invitations send; the inline-logo code moves to common/emails.py so both share it; - the shared demo guest excluded, since its hand-made account may have an address and whoever reset it would own every phone visitor's session; - at most three emails per address per hour, answered with the same "sent" page as an unknown address so the form reveals nothing; - a completed reset clearing the django-axes lockout for that username; - phones getting the desktop-only card, with its own wording for a reset link. Fixes #96. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Fixes #96.
Problem
The "Forgot your password?" flow added in 2.x (1b8ce69) was wired up in
toothfairy/urls.py. When the project becameyggdrasilin 3.0, its URLs, templates, forms and the login link were all lost, so nobody could reset a password.What's back
/password-reset/, in four pages: request → check your email → choose a new password → done. A used or expired link gets a "This link no longer works" page with a button to send a new one. The pages use the same auth-card markup as sign-in and register, and only CSS classes already in the committedtailwind.css.maxillo/views/auth.pytocommon/emails.py, so both emails share it.The flow lives in
common/password_reset.pyrather than beside the rest of auth inmaxillo/, becausemaxillo/README.mdcalls that address legacy and says new cross-domain code belongs incommon/.Additions beyond the 2.x version
Notes
EMAIL_*), which the invitations already rely on.PASSWORD_RESET_TIMEOUT(3 days); the email states the lifetime.Tests
common/tests_password_reset.pycovers the login link, the branded email (HTML part and inline logo), same answer and no email for an unknown address, the demo guest refused, the per-address limit, a link that sets a new password exactly once, a forged link refused, a reset lifting an axes lockout, and phones getting the desktop-only card and sending no email.Full suite on MySQL 8 (dev stack):
Ran 1499 tests ... OK.ruff check .andlint-importsare clean.🤖 Generated with Claude Code