Skip to content

feat(verify-email): /verify-email page + verify-first OAuth merge guidance#40

Merged
amrtgaber merged 1 commit into
mainfrom
feat/verify-email-flow
May 26, 2026
Merged

feat(verify-email): /verify-email page + verify-first OAuth merge guidance#40
amrtgaber merged 1 commit into
mainfrom
feat/verify-email-flow

Conversation

@amrtgaber
Copy link
Copy Markdown
Contributor

Summary

  • New /verify-email route that POSTs ?token=... to /auth/verify and renders success / invalid-link / generic-error cards. Treats VERIFY_USER_ALREADY_VERIFIED (400) as success so a second click (e.g. from another device) doesn't read as an error.
  • The Google callback now maps the API's new 400 OAUTH_USER_ALREADY_EXISTS detail 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".
  • Adds .playwright-mcp/ to .gitignore so 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.tsxOAUTH_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:

Scenario Result Network DB
/verify-email (no token) "Invalid link" no call
/verify-email?token=garbage "Invalid link" POST /auth/verify → 400
Register fake user → click verify URL from API logs "Email verified" POST /auth/verify → 200 is_verified=true
Re-click same URL (already-verified) "Email verified" POST /auth/verify → 400 mapped to success unchanged

Not covered end-to-end

  • OAuth merge refusal path. Covered by the unit test in 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
  • Click through /verify-email with no token / garbage token — both render "Invalid link".
  • Register a new user against a local auth-api, grep email.skipped in API logs for the verify_url, click it — should land on "Email verified".

…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.
@netlify
Copy link
Copy Markdown

netlify Bot commented May 26, 2026

Deploy Preview for criticalbit-auth-web ready!

Name Link
🔨 Latest commit 6334c21
🔍 Latest deploy log https://app.netlify.com/projects/criticalbit-auth-web/deploys/6a1608ac0e36180008232bae
😎 Deploy Preview https://deploy-preview-40--criticalbit-auth-web.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@amrtgaber amrtgaber merged commit a89bfae into main May 26, 2026
6 checks passed
@amrtgaber amrtgaber deleted the feat/verify-email-flow branch May 26, 2026 21:20
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.

1 participant