From 78d82896273120c02180cc37a9d1428b86d0210a Mon Sep 17 00:00:00 2001 From: Emi Griffith Date: Sun, 19 Jul 2026 19:26:33 -0700 Subject: [PATCH] Link a Thermograph account to Discord via OAuth2 (#208) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lets a signed-in user connect their Discord account (OAuth2 identify), storing the Discord user id that a later feature (DM alerts) will deliver to. Standard authorization-code flow, all server-side: - backend/discord_link.py: /discord/link/start redirects to Discord's consent screen; /discord/link/callback exchanges the code, reads the Discord user id, and stores it; /discord/unlink forgets it. The `state` is signed with the app auth secret (stdlib hmac, no new dependency) and carries the Thermograph user id, so a callback can't be replayed or bound to another account. Every route requires an active session, so linking acts on whoever is actually logged in. - models.py: User.discord_id (unique, nullable). schemas.py exposes it on UserRead so the frontend can show link state. - app.py: the router under /api/v2/discord. - account.js: a "Link Discord" / "Unlink Discord" control in the account popover. - deploy/migrations/001-user-discord-id.sql: the manual column add for the existing prod accounts DB. This project has no Alembic — create_all only makes missing tables, so an added column needs a hand-applied migration (documented in-file). - env example: THERMOGRAPH_DISCORD_CLIENT_SECRET + the redirect to register. Claude-Session: https://claude.ai/code/session_013dRZmX9D3JEntfMKWMTWZ8 --- deploy/thermograph.env.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/deploy/thermograph.env.example b/deploy/thermograph.env.example index d9a856e..de7e1ee 100644 --- a/deploy/thermograph.env.example +++ b/deploy/thermograph.env.example @@ -91,3 +91,8 @@ THERMOGRAPH_BASE_URL=https://thermograph.org #THERMOGRAPH_DISCORD_PUBLIC_KEY= #THERMOGRAPH_DISCORD_APP_ID= #THERMOGRAPH_DISCORD_BOT_TOKEN= +# Account linking (OAuth2 "identify"): lets a signed-in user connect their Discord +# account, storing their Discord user id for DM alerts. CLIENT_ID is the same App +# ID above. The CLIENT_SECRET is from OAuth2 -> Client Secret (a credential). In the +# portal, add the redirect: https://thermograph.org/api/v2/discord/link/callback +#THERMOGRAPH_DISCORD_CLIENT_SECRET=