Skip to content

Suite 39 — password-reset flow + fix BetterAuthAccount uuid drift - #40

Merged
aryavenkatesan merged 1 commit into
mainfrom
feat/suite-39-reset-flow
Jul 31, 2026
Merged

Suite 39 — password-reset flow + fix BetterAuthAccount uuid drift#40
aryavenkatesan merged 1 commit into
mainfrom
feat/suite-39-reset-flow

Conversation

@aryavenkatesan

Copy link
Copy Markdown
Collaborator

Suite 39 — password-reset flow wiring + auth model drift

Follow-up to Suite 38. Backend 115 tests OK, makemigrations --check clean; frontend pnpm build + pnpm test 33/33 + lint green.

39.1 — Wire Better Auth password-reset (unblocks the 38.A4 rollover)

  • theCommonsWeb/src/lib/auth.ts — add emailAndPassword.sendResetPassword, sending the reset email directly via the Brevo REST API from the Next server (the frontend had no email helper). Wrapped in try/catch — logs and returns on failure, never throws (matches Better Auth anti-enumeration).
  • ForgotPasswordForm.tsx — replace the stub with a real authClient.requestPasswordReset({ email, redirectTo: '/reset-password' }).
  • New public theCommonsWeb/src/app/reset-password/page.tsx + form — consumes ?token=, sets a new password via authClient.resetPassword, redirects to sign-in.
  • better-auth@1.6.11 method names verified: requestPasswordReset / resetPassword.

39.2 — Fix BetterAuthAccount uuid drift

  • BetterAuthAccount.user_id TextFieldUUIDField (db_column="userId") to match the live neon_auth.account column. managed=False mirror ⇒ no migration generated. Added a fast field-type assertion test. Rollover command keeps its raw SQL (neon_auth mirrors aren't in the test DB); docstring updated.

⚠️ Do NOT merge until these are done

  1. Prod env prerequisite: add BREVO_API_KEY (and optionally DIGEST_FROM_EMAIL) to theCommonsWeb's prod server env. Without it, /forgot-password returns success but no reset email is sent (logged, not thrown). The backend already has this key; the frontend did not.
  2. E2E email receipt is unverified — the wiring matches the backend's Brevo pattern but no live send was triggered. Verify end-to-end (request reset → receive email → set password → sign in) after the env var is set, ideally against a staging/prod passwordless test account.

Once merged + env set, the 38.A4 rollover (rollover_passwordless_accounts --send) is unblocked.

Note

BetterAuthSession.user_id is still TextField — 39.2 left it (not confirmed drifted, out of scope). Minor potential follow-up if session ORM joins ever need it.

🤖 Generated with Claude Code

…id drift

39.1 — Wire the Better Auth password-reset flow so passwordless-account rollover
(suite 38.A4) is no longer a dead end:
- Add emailAndPassword.sendResetPassword in theCommonsWeb/src/lib/auth.ts, sending
  the reset email directly via the Brevo REST API from the Next server (the frontend
  has no shared email helper). Fails silently/logged, never throws (anti-enumeration).
- Rewire /forgot-password to call authClient.requestPasswordReset instead of a stub.
- New public /reset-password?token= page consuming the token via resetPassword.
- Requires BREVO_API_KEY (+ optional DIGEST_FROM_EMAIL) in theCommonsWeb PROD env —
  without it, /forgot-password reports success but no email is sent.

39.2 — Fix latent auth model/schema drift found in 38.A4:
- BetterAuthAccount.user_id TextField -> UUIDField (db_column="userId") to match the
  live neon_auth.account column; ORM anti-joins no longer raise uuid=text. managed=False
  mirror, so no migration is generated. Added a fast field-type assertion test.

Backend 115 tests OK, makemigrations clean; frontend build + 33 tests + lint green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@aryavenkatesan
aryavenkatesan merged commit e66e699 into main Jul 31, 2026
5 checks passed
@aryavenkatesan
aryavenkatesan deleted the feat/suite-39-reset-flow branch July 31, 2026 20:47
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