feat(auth): email verification, Google OAuth, and account settings#4
Merged
BODMAT merged 18 commits intoMay 21, 2026
Merged
Conversation
Split provider/providerId into AuthIdentity for multi-provider support. Add EmailToken for verification flows. Backfill existing users as verified.
Lazy SMTP via env vars, jsonTransport fallback when credentials are missing. In-memory capture for tests; jest.setup resets it between tests.
Register issues a hashed EmailToken and sends a verify link instead of opening a session. Login rejects unverified accounts with 403. Adds verify-email and resend-verification endpoints.
Google callback no longer auto-links on email match. Issues a 1h merge_google token via email; /auth/verify-merge attaches the identity after the user clicks the link.
set-password creates a local AuthIdentity on first use and requires old password to change. OTP emails a random password. Account deletion requires password for local users or an email link for google-only.
Seed creates a local AuthIdentity per user and marks them verified. registerAndCreateWallet now flips the verified flag and re-logs in since register no longer opens a session.
Account deletion was failing with FK violation because Wallet.user had no onDelete rule. Migration drops and re-adds the FK with ON DELETE CASCADE.
Drop any unverified record with the same login or email before creating a new user. Lets the real owner recover and blocks squat attacks.
Auth button covers sign-in/sign-up, verifying stage with resend, and logout/logout-all. Settings popup adds tabs for password, OTP and account deletion. AuthQueryParamToast shows auth= outcomes with auto-dismiss.
- return photoUrl in safe user schema - allow Google linking when the same user starts Google auth - update header labels and profile copy - normalize photo URL handling
Add auth.security.int.test.ts covering takeover protection, verification states, Google linking, set-password, account deletion and logout-all.
Block request-delete for password accounts. Fix email template encoding. Stabilize auth security integration tests.
… verified emails - remove OTP, merge-confirmation and email-link deletion - deleteAccount now relies on session for google-only users - google sign-in auto-links to verified accounts and clears unverified squats - photoUrl restricted to https/data: URLs; PasswordField extracted for show/hide
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.
What
Adds email verification to the registration flow, Google OAuth sign-in with
automatic account linking, and a full account settings UI (profile, password,
account deletion).
Changes
Backend
AuthIdentitytable for multi-provider support (local + google)EmailTokentable for hashed, single-use verification tokens (24h TTL)new one; unverified squats on the same email are cleared
set-password,delete-account,update-profile,resend-verification,verify-emailauthController.tssplit into focused modules undercontrollers/auth/ON DELETE CASCADEFrontend
AuthQueryParamToastsurfaces?auth=outcomes on redirect back from Googleauth.utils.tswith sharedinputClass,secondaryButtonClass,extractServerErrorAuthPopupandAccountSettingsPopupsplit into subfoldersSecurity
before a new registration
sufficient for Google-only users
linking, set-password and logout-all
Testing
22 passed, 0 failed
auth.security.int.test.tscovers:set-passwordwith old-password checkupdate-profilerename, 409 on taken login, photoUrl validationlogout-allsession revocation