|
All checks were successful
PR build (required check) / changes (pull_request) Successful in 6s
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 1m1s
PR build (required check) / build-backend (pull_request) Successful in 1m29s
PR build (required check) / gate (pull_request) Successful in 1s
Adds Google as a second identity provider. Rather than a second copy of the Discord flow, the flow itself moves to accounts/oauth.py and both providers become configurations of it — account resolution is the security-critical part, and a parallel hand-rolled copy is where a subtle divergence becomes a takeover. A third provider is now a PROVIDERS entry and nothing else. Identity moves to an oauth_account table keyed (provider, subject), so a login resolves on the provider's own stable id rather than an email that can be changed or reassigned. user.discord_id deliberately stays: it is the DM delivery address notify.py reads, not merely an identity, and the Discord link keeps writing it. discord_only becomes oauth_only, and the lockout guard now refuses to unlink the *last* provider from a password-less account rather than singling out Discord — with two linked, either may go. Migration 0005 renames the flag and backfills an oauth_account row for every existing discord_id. Without that backfill an already-linked user would stop being recognised at login and would silently get a second account on their next sign-in. It also drops a vestigial discord_only that 0003 re-adds on a database whose 0001 already built oauth_only from current metadata, which otherwise left fresh and upgraded databases with different schemas. Compatibility, since the frontend deploys independently of this service: /discord/link/callback keeps answering because that URL is registered in Discord's developer portal, the other /discord/* routes stay because the deployed frontend calls them, the callback still emits ?discord= alongside ?oauth=, and UserRead still carries discord_only as a computed alias. Google needs THERMOGRAPH_GOOGLE_CLIENT_ID/_CLIENT_SECRET and its own registered redirect URI; unset, it reports disabled and shows no UI. |
||
|---|---|---|
| .. | ||
| .well-known | ||
| account.js | ||
| app.js | ||
| apple-touch-icon.png | ||
| bookmarks-ui.js | ||
| bookmarks.js | ||
| cache.js | ||
| calendar.html | ||
| calendar.js | ||
| chart.js | ||
| climate.js | ||
| compare.html | ||
| compare.js | ||
| day.html | ||
| day.js | ||
| digest.js | ||
| favicon-16.png | ||
| favicon-32.png | ||
| favicon-48.png | ||
| favicon.svg | ||
| filtersheet.js | ||
| google03ab95daa090e8d9.html | ||
| ios-install.js | ||
| legend.html | ||
| logo-192.png | ||
| logo-maskable-192.png | ||
| logo-maskable-512.png | ||
| logo.png | ||
| manifest.webmanifest | ||
| mappicker.js | ||
| nav.js | ||
| package.json | ||
| push-client.js | ||
| score.html | ||
| score.js | ||
| shared.js | ||
| style.css | ||
| subscriptions.html | ||
| subscriptions.js | ||
| sw.js | ||
| units.js | ||