fix(web): require User.email and reject SSO sign-ins without an email#1310
Conversation
Some User rows could be created with a null email — most commonly OAuth/OIDC accounts created from an identity-provider profile that returned no email. These rows crashed the Members and Pending Requests pages (`email.toLowerCase()` on a null) and left unusable identities in the org. - Make `User.email` required (`String @unique`) with a self-healing migration: backfill any existing null emails with a deterministic, unique, synthetic placeholder before applying NOT NULL, so the startup `migrate deploy` can never fail on instances that already have null rows. - Reject any sign-in that arrives without an email in the `signIn` callback, so a null can never reach `createUser`. - Drop the now-redundant `email!` assertions and tighten the public EE user API schemas (`email` is no longer nullable); regenerate the OpenAPI spec. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
Walkthrough
ChangesUser email non-nullable enforcement
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@CHANGELOG.md`:
- Line 20: The changelog entry in CHANGELOG.md contains multiple sentences
separated by periods, but the repository format requires a single sentence
followed by the PR link. Combine the two sentences about fixing the Members page
crash and making User.email required into one cohesive sentence, then follow it
with the PR link [`#1310`](https://github.com/sourcebot-dev/sourcebot/pull/1310)
to match the required format.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4a97f7ab-f167-441c-a0a0-266c9a164f8b
📒 Files selected for processing (11)
CHANGELOG.mddocs/api-reference/sourcebot-public.openapi.jsonpackages/db/prisma/migrations/20260616000000_make_user_email_required/migration.sqlpackages/db/prisma/schema.prismapackages/web/src/actions.tspackages/web/src/app/invite/actions.tspackages/web/src/auth.tspackages/web/src/features/userManagement/actions.tspackages/web/src/lib/authUtils.tspackages/web/src/lib/encryptedPrismaAdapter.tspackages/web/src/openapi/publicApiSchemas.ts
Fixes SOU-1335
Problem
The Members settings page (and the Pending Requests tab) crashed with
TypeError: Cannot read properties of null (reading 'toLowerCase')on instances that hadUserrows with a nullemail. These rows are created when an OAuth/OIDC identity provider returns a profile without an email — next-auth's adapter persists whateverprofile()produced, and nothing in the app ever backfills it. ThegetOrgMembers/getOrgAccountRequestsactions assertedemail!, hiding the nullability from the type checker, and the client list components then calledmember.email.toLowerCase().Approach
Make a non-null email an enforced invariant rather than something the UI has to defensively handle:
User.emailis nowString @unique(wasString?).20260616000000_make_user_email_required) — becauseprisma migrate deployruns automatically on container startup, a bareSET NOT NULLwould fail and brick the upgrade on any instance that still has null rows. The migration first backfills existing nulls with a deterministic, unique, obviously-synthetic placeholder (placeholder-<id>@no-email.invalid), then appliesNOT NULL. Backfilled rows are findable viaWHERE email LIKE 'placeholder-%@no-email.invalid'.signIncallback now rejects any sign-in that arrives without an email, so a null can never reachcreateUser(which would otherwise 500 on the NOT NULL insert). In practice only OAuth/OIDC profiles can lack one; the check is unconditional so future providers are covered too.email!assertions across the user-management/invite/auth code, corrected the stale "email is nullable" comment in the encrypted adapter, and tightened the public EE user API schemas (emailis no longer nullable) + regenerated the OpenAPI spec.Notes
LIKEquery above.emailwas already always populated in practice; the contract now states it's guaranteed.Testing
tsc --noEmiton@sourcebot/web: no new errors (pre-existinglastActiveAttest-fixture errors are unrelated).emailistype: stringand inrequiredforPublicEeUser/PublicEeUserListItem.🤖 Generated with Claude Code
Summary by CodeRabbit
emailnon-nullable.User.emailas required in the database via backfill + schema update.