Skip to content

fix: allow self-hosted GitHub users without email#435

Open
KMKoushik wants to merge 1 commit into
mainfrom
codex/fix-self-hosted-github-auth
Open

fix: allow self-hosted GitHub users without email#435
KMKoushik wants to merge 1 commit into
mainfrom
codex/fix-self-hosted-github-auth

Conversation

@KMKoushik

@KMKoushik KMKoushik commented Jul 21, 2026

Copy link
Copy Markdown
Member

Summary

  • allow existing linked OAuth accounts to sign in when GitHub does not return an email
  • allow the first user to bootstrap an empty self-hosted instance without an email
  • continue rejecting later no-email or uninvited accounts, including inside the transaction lock
  • document the GitHub App Email addresses: Read-only permission required for invitation matching
  • add focused unit regression coverage for the permanent policy branches

Root cause

GitHub Apps without the Email addresses: Read-only account permission return no email for users whose address is private. The self-hosted registration policy added in 1.9.5 rejected a missing email before checking whether the OAuth account was already linked or whether the installation had no users yet. That caused both upgraded installations and fresh installations to redirect to AccessDenied.

Impact

Existing self-hosted GitHub users can sign in again, and a fresh instance can bootstrap its owner even if GitHub omits the email. The invitation-only policy remains enforced for every later account.

Verification

  • pnpm --filter=web exec vitest run -c vitest.unit.config.ts src/server/auth.unit.test.ts — 14 passed
  • reproduced the 1.9.5 AccessDenied with a temporary NextAuth HTTP callback harness and the exact no-email GitHub response
  • verified the fix against real PostgreSQL and Redis: user/account/session persistence, repeat login, and rejection of a second uninvited no-email identity
  • ran the complete integration suite with the temporary harness — 5 files and 12 tests passed; the one-off harness was removed after verification
  • pnpm --filter=web exec tsc --noEmit --pretty false
  • ESLint and Prettier checks for all touched files

No application build or database schema migration is required.

Fixes #434

Summary by CodeRabbit

  • Bug Fixes
    • Improved self-hosted login and registration handling for OAuth sign-ins, including cases where the provider doesn’t return an email.
    • Updated account creation rules to better handle first-user bootstrap and invitation gating, improving reliability during self-hosted sign-in.
  • Documentation
    • Added clearer GitHub App credential guidance for self-hosting, setting Email addresses to read-only for account matching and team invitations.
  • Tests
    • Expanded unit test coverage for self-hosted OAuth and no-email edge cases.

@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
unsend-marketing Ready Ready Preview, Comment Jul 21, 2026 4:54am

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 87f72eb8-4f44-4d67-ba10-70163b62afea

📥 Commits

Reviewing files that changed from the base of the PR and between 60c8f0b and 78ad751.

📒 Files selected for processing (4)
  • apps/docs/self-hosting/overview.mdx
  • apps/docs/self-hosting/railway.mdx
  • apps/web/src/server/auth.ts
  • apps/web/src/server/auth.unit.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/docs/self-hosting/railway.mdx
  • apps/docs/self-hosting/overview.mdx
  • apps/web/src/server/auth.unit.test.ts

Walkthrough

Self-hosted authentication now passes OAuth account details into registration checks, permits existing OAuth accounts without email, and gates new email-based accounts on invitations. User creation performs missing-email validation inside the advisory-lock transaction. Unit tests cover these registration and creation paths. Self-hosting documentation specifies the GitHub App Email addresses permission as Read-only.

Possibly related PRs

  • usesend/useSend#423: Modifies the same authentication registration, sign-in callback, transaction, and unit-test areas.

Suggested labels: codex

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: self-hosted GitHub users can now log in without an email address.
Linked Issues check ✅ Passed The changes address #434 by fixing self-hosted GitHub login failures and covering the no-email and bootstrap cases.
Out of Scope Changes check ✅ Passed The docs, auth logic, and tests all support the self-hosted login fix; no unrelated changes are evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

apps/docs/self-hosting/overview.mdx

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

apps/docs/self-hosting/railway.mdx

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

apps/web/src/server/auth.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

  • 1 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 21, 2026

Copy link
Copy Markdown

Deploying usesend with  Cloudflare Pages  Cloudflare Pages

Latest commit: 78ad751
Status: ✅  Deploy successful!
Preview URL: https://f9e782c3.usesend.pages.dev
Branch Preview URL: https://codex-fix-self-hosted-github.usesend.pages.dev

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/web/src/server/auth.ts (1)

62-71: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Scope the email fallback away from OAuth sign-ins. Both GitHub and Google enable allowDangerousEmailAccountLinking, so a new OAuth login with a matching email can skip the invite check here. Restrict this branch to non-OAuth flows, or to already-linked accounts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/server/auth.ts` around lines 62 - 71, Update the email-based
existing-user fallback in the authentication flow to run only for non-OAuth
sign-ins or users whose account is already linked to the current OAuth provider.
Preserve the existing invite-check behavior for new OAuth users with matching
emails, using the provider/account-linking context available around this branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/web/src/server/auth.ts`:
- Around line 62-71: Update the email-based existing-user fallback in the
authentication flow to run only for non-OAuth sign-ins or users whose account is
already linked to the current OAuth provider. Preserve the existing invite-check
behavior for new OAuth users with matching emails, using the
provider/account-linking context available around this branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 02d04c6c-11ae-4514-b33a-5847d8fe9655

📥 Commits

Reviewing files that changed from the base of the PR and between b1b1f86 and 15133ea.

📒 Files selected for processing (6)
  • apps/docs/self-hosting/overview.mdx
  • apps/docs/self-hosting/railway.mdx
  • apps/web/src/server/auth.integration.test.ts
  • apps/web/src/server/auth.ts
  • apps/web/src/server/auth.unit.test.ts
  • apps/web/src/test/setup/setup-env.ts

Entire-Checkpoint: 9d403c1dae5f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐞 - Access Denied when trying to login after updating to 1.9.5

1 participant