Skip to content

Conversation

tomassrnka
Copy link
Member

@tomassrnka tomassrnka commented Oct 1, 2025

Summary

Implements email verification validation for OAuth providers during authentication callback. Users with unverified emails are rejected and signed out.

Changes

  • Add isOAuthEmailVerified() helper function to validate OAuth identity data
  • Integrate verification check in OAuth callback with structured logging
  • Add error message for unverified email accounts

Behavior

  • Verified accounts: sign in successfully
  • Unverified accounts: rejected with error message and signed out
  • Supports Google (email_verified) and GitHub (verified) providers

Testing

Verified locally with Google OAuth. Logs confirm check executes on every OAuth authentication.


Note

Adds OAuth email verification at auth callback for new users, with provider-specific error handling and messages.

  • Auth Callback (src/app/api/auth/callback/route.ts):
    • Validate OAuth email on signup using isOAuthEmailVerified; treat users with a single identity as new.
    • On unverified email: log warning, signOut, and redirect to AUTH_URLS.SIGN_IN with provider-specific error message from USER_MESSAGES.
    • Add structured logs for verification outcomes and existing-user path.
  • Utils (src/lib/utils/auth.ts):
    • Add isOAuthEmailVerified(user) to check identity data (supports google via email_verified and github via verified).
  • User Messages (src/configs/user-messages.ts):
    • Add googleEmailNotVerified, githubEmailNotVerified, oauthEmailNotVerified, and genericEmailNotVerified with 30s timeouts.

Written by Cursor Bugbot for commit 64f1a03. This will update automatically on new commits. Configure here.

Copy link

vercel bot commented Oct 1, 2025

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

Project Deployment Preview Comments Updated (UTC)
web Ready Ready Preview Comment Oct 3, 2025 2:37pm
web-juliett Ready Ready Preview Comment Oct 3, 2025 2:37pm

cursor[bot]

This comment was marked as outdated.

  Changes !== false to !== true to fail closed if verification
  field is missing, null, or false. Prevents bypass attacks.
cursor[bot]

This comment was marked as outdated.

}

// If we get here, the check passed
return { verified: true, provider }
Copy link

Choose a reason for hiding this comment

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

Bug: OAuth Email Verification Bypass

The isOAuthEmailVerified function's default case for OAuth providers marks emails as verified without any actual check. This means users from unhandled providers are considered verified even if their email isn't, creating a security vulnerability.

Fix in Cursor Fix in Web


// Check email verification only for new users (signup)
// Existing users with linked identities can sign in with any provider
const isNewUser = data.user.identities?.length === 1
Copy link

Choose a reason for hiding this comment

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

Bug: OAuth Users Blocked by Incorrect New User Check

The isNewUser check, based on data.user.identities?.length === 1, incorrectly identifies existing users with a single OAuth identity as new. This subjects existing users to email verification checks, potentially blocking their sign-in if their OAuth provider's email verification status isn't met.

Fix in Cursor Fix in Web

@tomassrnka
Copy link
Member Author

Agreed with Ben, we will not merge this in favor of possible other mitigations.

@tomassrnka tomassrnka closed this Oct 7, 2025
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.

2 participants