feat(verify-email): /verify-email page + verify-first OAuth merge guidance#40
Merged
Conversation
…uidance on OAuth merge refusal Backend just landed email verification (auto-send on registration, link points at FRONTEND_URL/verify-email?token=...). Add the page so the link isn't a 404, and treat VERIFY_USER_ALREADY_VERIFIED as success so a second click (e.g. from another device) doesn't read as an error. The same backend change refuses OAuth merges into unverified password accounts (400 OAUTH_USER_ALREADY_EXISTS), which previously surfaced as a generic "Google sign-in failed". Map that detail to verify-first copy on the Google callback page so users know what to do. Tests cover all five page states (no token, success, already-verified, bad token, generic failure) and both new callback branches.
✅ Deploy Preview for criticalbit-auth-web ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
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
/verify-emailroute that POSTs?token=...to/auth/verifyand renders success / invalid-link / generic-error cards. TreatsVERIFY_USER_ALREADY_VERIFIED(400) as success so a second click (e.g. from another device) doesn't read as an error.400 OAUTH_USER_ALREADY_EXISTSdetail to verify-first copy: "An unverified account already exists for this email. Sign in with your password, verify your email, then link Google from your profile." This is the security-relevant piece — without it the takeover-vector mitigation just looks like a generic "Google sign-in failed"..playwright-mcp/to.gitignoreso MCP-driven browser sessions don't leak snapshot YAMLs/screenshots/console logs into the working tree.Why now
Pairs with ag-tech-group/criticalbit-auth-api#39, which just merged. Registration now auto-dispatches a verification email pointing at
${FRONTEND_URL}/verify-email?token=<jwt>— until this PR lands, every new registrant clicks a 404. Same PR introduced the OAuth merge refusal that this page's callback change explains to the user.Closes
Test plan
Unit (vitest, 7 new tests, 27 total — all passing)
verify-email-page.test.tsx— no token, success, already-verified mapped to success, bad-token → invalid card, 500 → generic failure card.google-callback-page.test.tsx—OAUTH_USER_ALREADY_EXISTS→ verify-first copy; other 400 detail → generic copy.Manual end-to-end (Playwright against real API + Postgres)
Drove the actual auth-api on a non-default port wired to a fresh Postgres:
/verify-email(no token)/verify-email?token=garbageis_verified=trueNot covered end-to-end
google-callback-page.test.tsx. A real Playwright run would need Google OAuth client creds plus a Google account whose email matches an unverified password user, which is more setup than the change warrants.Reviewer checklist
pnpm test:run/verify-emailwith no token / garbage token — both render "Invalid link".email.skippedin API logs for theverify_url, click it — should land on "Email verified".