auth: collect verified primary email from GitHub - #37
Open
utsengar wants to merge 1 commit into
Open
Conversation
Adds users.email column + 0003 migration. Expands OAuth scope to read:user user:email so the callback can hit /user/emails and persist the primary+verified address. Email is optional — sign-in never blocks on it (denied scope / no verified email / lookup failure → NULL). Refreshed on every sign-in, so pre-user:email rows backfill the first time their owner signs in again. No UNIQUE constraint on email: two distinct GitHub accounts can legitimately share an address. github_user_id remains the identity. Dashboard user-detail page surfaces the email as a mailto: link so operator outreach (e.g. "are you the StressLessAgency publishing X?") is one click. No automated send, no marketing list, no unsubscribe surface, no user-facing email UI — disclosure is the GitHub consent screen only. CLAUDE.md rule #4 expanded to document the new exception. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🚀 Cloudflare previewURL: https://ee4267d4-htmlbin.utkarsh2012.workers.dev Built from commit
|
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.
Summary
read:usertoread:user user:email.users.email(nullable, no UNIQUE) via migration0003-add-user-email.sqland updatesschema.sqlfor fresh installs./user/emails, picks the primary + verified entry, and stores it. Email is optional — sign-in never blocks on it (denied scope / no verified email / lookup failure → NULL).updateUserEmail(), so pre-user:emailusers (includingStressLessAgency) get their email backfilled the first time they sign in again.npm run dashboarduser-detail page surfaces the email as amailto:link, which is the whole point — one click to reach the owner.<mock_login>@example.test(reserved TLD, can't accidentally send mail) so the e2e script keeps working.Caveats
email IS NULLforever. There is no scheduled backfill job (would need server-side write access to all users' GitHub accounts, which we don't have).npm run db:migrate:remoteto add the column.Test plan
/verifyflow works against a real GitHub accountusers.emailusers.email(verify via dashboard)users.email IS NULLnpm run dashboarduser-detail page shows the email as amailto:link./scripts/agent-e2e.shagainst the preview URL still passes (dev-mock synthesizes*@example.test)npm run db:migrate:remoteapplied; verifyusersschema includesemail TEXT🤖 Generated with Claude Code