Add password recovery to BackToSchool sign-in - #181
Merged
Merged
Conversation
ralyodio
added a commit
that referenced
this pull request
Sep 16, 2026
… already serves (#216) PR #181 built password recovery (hashed single-use links, Resend mail, session revocation) and put a "Forgot password?" link on the BackToSchool sign-in, but nixamp.com's own account panel never linked to it. A member whose password no longer matched read "that email and password do not match an account" with nowhere to go, although /reset-password was live on the same origin. The link sits next to "Create one", hides while creating an account, and opens in its own tab inside a classroom embed so the host page's iframe is not navigated away. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
ralyodio
added a commit
that referenced
this pull request
Sep 16, 2026
… card said once (#217) * Account panel: a "Forgot password?" link to the reset page nixamp.com already serves PR #181 built password recovery (hashed single-use links, Resend mail, session revocation) and put a "Forgot password?" link on the BackToSchool sign-in, but nixamp.com's own account panel never linked to it. A member whose password no longer matched read "that email and password do not match an account" with nowhere to go, although /reset-password was live on the same origin. The link sits next to "Create one", hides while creating an account, and opens in its own tab inside a classroom embed so the host page's iframe is not navigated away. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * BackToSchool is its own account; nixamp is an optional backend; the host card is said once backtoschool.help runs in the nixamp process over the same users table, and its sign-in dialog said so ("your BackToSchool identity is your NixAmp account"), which filed the nixamp password under the school in a password manager and made nixamp a thing every teacher had to have. Neither is wanted. The account card, shared by both apps: src/profiles.ts keeps a name, a homepage, a line, a linked avatar and an uploaded photo (bytes in Postgres, type sniffed, served with an etag) against the account. An OpenProfile.md fills it in one move and its address is remembered on the persona. A class made without host fields takes the card, so the school form no longer asks for a name and photo every time; it shows the card and points at settings. Connect nixamp, optional: the school is a built-in public OAuth 2.1 client of nixamp.com (PKCE, consent page, refresh rotation, a new `streams` scope). src/nixamp-link.ts keeps the tokens against the school account and refreshes them; src/nixamp-link-api.ts is connect, callback, connection and streams. What it buys is a pick list of the servers you run and what is live on them, instead of a link pasted from a terminal. Withdrawing it on either side ends it on both. The school gets a settings dialog (profile, photo, OpenProfile, the connection, sign out) and loses every mention of nixamp on the way in. nixamp.com gets "Teach this on backtoschool.help": one click makes the class from the live room and the card, starts it, and opens it. Tests: unit tests for the card parser, the link module and the streams reader; two real-Postgres runs (card round trip with a photo, an import and a class; connect through consent to callback, streams and disconnect over one server that is both sides). The server's catch-all now logs under NIXAMP_DEBUG, which is how the second of those was made to pass. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <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.
BackToSchool users had no way to recover a forgotten password. Add “Forgot password?” to sign-in and branded request/new-password pages backed by durable, expiring, single-use recovery links sent through the configured Resend sender.
Recovery atomically changes the password and revokes existing browser, CLI, and legacy JWT sessions. Requests use generic responses, bounded payloads, and IP/address throttles; tokens are hashed in Postgres and carried in URL fragments.
Validation: real Postgres recovery tests cover replacement, expiry, simultaneous consumption, restart, invalid passwords, and session revocation. Playwright verifies the complete mobile browser flow, same-tab email links, new login, reuse rejection, and preserved focus. Typechecks and builds pass.