Repository navigation
fix(oauth): fetch private GitHub emails; drop unverified Google emails - #1765
Conversation
GitHub's /user only returns the public email, so most GitHub sign-ins created users with no email. Fall back to the primary verified address from /user/emails. Google emails without verified_email are dropped. Existing users with no email get the provider email on next sign-in, unless another user already has it. Fixes #1761 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@kevinpapst Want to take a quick look before it comes in? |
There was a problem hiding this comment.
🟡 Changes recommended
The OAuth email backfill uses a stale empty-email check and an unconditional update, which can overwrite an email address the user concurrently confirmed in another tab.
1 open issue
What changed in this PR
This PR addresses #1761 by retrieving private GitHub email addresses for OAuth sign-ins, helping affected users receive notifications.
Changes:
- Fetches the primary verified GitHub email when the public email is absent, with a non-blocking fallback on failure.
- Removes unverified Google emails from built-in provider profiles.
- Backfills missing user emails on sign-in when the address is available, with tests for backfill and provider behavior.
| File | Description |
|---|---|
app/services/oauth/oauth.go |
Adds GitHub email retrieval and Google email verification filtering. |
app/services/oauth/email_internal_test.go |
Tests provider email selection, filtering, and fallback behavior. |
app/handlers/oauth.go |
Adds email backfill for existing users during sign-in. |
app/handlers/oauth_test.go |
Tests successful backfill and skipping addresses already in use. |
Review effort: Balanced
There was a problem hiding this comment.
As I am not a Go dev, I tested the branch instead of doing a code review (Copilot is better anyway) like this:
- Created a new Github OAuth app
- Ran the branch locally on a database that didn't knew my account yet
- Logged in with Github => the account was created including the Email
Then I set an empty string via update users set email = '' where id = 2; as if it was an existing account and logged in a second time: the email was backfilled correctly.
So the logic works as expected, thanks for the quick fix 👍

Fixes #1761
Problem
GitHub's
GET /useronly returns the user's public email. Anyone without a public email signed in with an empty email, so they got no notifications. Fider never called/user/emails, even though it already requests theuser:emailscope.Changes
GET /user/emails. If that call fails (e.g. a GitHub App without the "Email addresses" permission returns 403), log a warning and sign in without an email, as before.verified_emailisn'ttrue.!guard). Custom providers and Facebook are unchanged. Facebook only returns confirmed emails.Tests
app/services/oauth/email_internal_test.go: GitHub primary/verified selection, public email skips the extra call, 403 fallback, Google verified/unverified.app/handlers/oauth_test.go: backfill on sign-in, and no change when another user has the email.🤖 Generated with Claude Code