BackToSchool is its own account, nixamp an optional backend, the host card said once - #217
Merged
Merged
Conversation
… 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>
…ost 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>
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.
Why
backtoschool.help runs in the nixamp process over the same users table, and its sign-in dialog said "Your BackToSchool identity is your NixAmp account". That filed the nixamp password under the school in Bitwarden, and made nixamp something every teacher had to have. Anthony's ruling: nixamp login from BackToSchool is optional; nobody needs nixamp except as the streaming backend.
Includes the one-line "Forgot password?" commit from #216 (branch cut from it).
What
src/profiles.ts, tablenixamp_profiles): name, homepage, a line, a linked avatar and an uploaded photo kept as bytes in Postgres (type sniffed from the file, served atGET /api/v1/profiles/<id>/photowith an etag and 304). RoutesGET/PUT /api/v1/me/profile,PUT/DELETE /api/v1/me/profile/photo,POST /api/v1/me/profile/import(fills the card from an OpenProfile.md and remembers the URL on the persona, so the phone voice reads the same file).POST /api/v1/eventsfills hostName/homepageUrl/avatarUrl from the profile when blank. The school form no longer asks for them; it shows the card with "Edit in settings". Editing a class never sends those keys, so nothing is wiped.src/nixamp-link.ts,src/nixamp-link-api.ts): the school is a built-in public OAuth 2.1 client of nixamp.com (PKCE, consent, refresh rotation, newstreamsscope;NIXAMP_OAUTH_BACKTOSCHOOL=offremoves it). Tokens kept innixamp_linksagainst the school account, refreshed when stale, dropped when nixamp.com refuses a refresh.GET /api/v1/nixamp/streamslists the servers you run and what is live on them, as links a classroom accepts. Disconnect withdraws the grant on nixamp.com too.backtoschool.help/live/<slug>.NIXAMP_DEBUG(a 500 in a test was invisible without it).Verification
bun run typecheck(server, web, school) clean;bun test test web/test851 pass, 0 fail, run withNIXAMP_TEST_DATABASE_URLset so the two real-Postgres tests ran: card round trip with a photo, an import and a class inheriting it; connect → consent → callback → streams → disconnect over one server acting as both sides.bun run buildfor web and school pass; both bundles carry the new markup.https://backtoschool.help/api/v1/nixamp/connectionanswers 401 when signed out, and thatnixamp.com/.well-known/oauth-authorization-serverlistsstreams.Not in this PR
myna profile); nothing serves it at profullstack.com yet, so the import has nowhere to read from until it is published.🤖 Generated with Claude Code