thermograph/frontend/static
Emi Griffith 8b70a87555
All checks were successful
PR build (required check) / changes (pull_request) Successful in 8s
secrets-guard / encrypted (pull_request) Successful in 5s
shell-lint / shellcheck (pull_request) Successful in 8s
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Successful in 1m11s
PR build (required check) / build-backend (pull_request) Successful in 1m35s
PR build (required check) / gate (pull_request) Successful in 1s
accounts: sign in with Discord, sharing the existing link callback
Discord was already linkable from a signed-in session; it could not
authenticate one. Adds /discord/login/start, which resolves a Discord
identity to an account and issues a session.

Both flows return to the existing /discord/link/callback. Discord only
honours redirect URIs registered in the developer portal, so a second
callback path would have blocked this behind an operator change; the
signed state now carries a purpose, and since that is inside the HMAC a
state can only verify under the flow it was minted for.

Account resolution, in order: an existing discord_id (the durable key,
no email needed); otherwise the Discord email, but only when Discord
reports it verified — that flag is the sole evidence the person owns the
address, and matching on an unverified one would hand over the account.
Failing both, a new account is created.

A login state carries no user id, so it is replayable against whoever is
signed in. It therefore never links: doing so would be a forced-linking
takeover. Only link/start, whose state is bound to a user id, may link.

Accounts created this way have no password their owner has ever seen,
so user.discord_only records that and unlink is refused for them — no
reset-password router is mounted, so unlinking would be unrecoverable.
Migration 0003 adds the column conditionally: 0001 builds the schema
from live model metadata, so a fresh database already has it.

Also fixes two latent bugs in the link flow: the callback redirected to
/subscriptions, which no route serves (it is /alerts), and nothing ever
read the ?discord= status it has always sent, so a completed link gave
no feedback. Both now surface as a toast. Linking a Discord account that
another account already owns returned a 500 from the unique constraint;
it now explains itself.
2026-07-26 10:43:17 -07:00
..
.well-known Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
account.js accounts: sign in with Discord, sharing the existing link callback 2026-07-26 10:43:17 -07:00
app.js fix(frontend): Weekly view must always send an explicit date to /grade 2026-07-26 06:20:19 +00:00
apple-touch-icon.png Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
cache.js fix(frontend): Weekly view must always send an explicit date to /grade 2026-07-26 06:20:19 +00:00
calendar.html Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
calendar.js Frontend QA batch: date/TZ, https origin, date-422, VAPID rotation, trace-precip, partial-day gate (#70) 2026-07-24 23:13:36 +00:00
chart.js Frontend QA batch: date/TZ, https origin, date-422, VAPID rotation, trace-precip, partial-day gate (#70) 2026-07-24 23:13:36 +00:00
climate.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
compare.html Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
compare.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
day.html Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
day.js Frontend QA batch: date/TZ, https origin, date-422, VAPID rotation, trace-precip, partial-day gate (#70) 2026-07-24 23:13:36 +00:00
digest.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
favicon-16.png Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
favicon-32.png Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
favicon-48.png Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
favicon.svg Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
filtersheet.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
google03ab95daa090e8d9.html Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
ios-install.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
legend.html Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
logo-192.png Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
logo-maskable-192.png Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
logo-maskable-512.png Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
logo.png Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
manifest.webmanifest Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
mappicker.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
nav.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
package.json Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
push-client.js Frontend QA batch: date/TZ, https origin, date-422, VAPID rotation, trace-precip, partial-day gate (#70) 2026-07-24 23:13:36 +00:00
score.html Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
score.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
shared.js Frontend QA batch: date/TZ, https origin, date-422, VAPID rotation, trace-precip, partial-day gate (#70) 2026-07-24 23:13:36 +00:00
style.css accounts: sign in with Discord, sharing the existing link callback 2026-07-26 10:43:17 -07:00
subscriptions.html Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
subscriptions.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
sw.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00
units.js Subtree-merge thermograph-frontend (origin/main) into frontend/ 2026-07-22 22:01:11 -07:00