Skip to content

Feat/email verification otp#37

Merged
juicycleff merged 7 commits into
mainfrom
feat/email-verification-otp
Jun 7, 2026
Merged

Feat/email verification otp#37
juicycleff merged 7 commits into
mainfrom
feat/email-verification-otp

Conversation

@jaymesC

@jaymesC jaymesC commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

No description provided.

jaymesC and others added 6 commits June 6, 2026 15:52
Add the foundation for 6-digit OTP email verification:
- GenerateOTPCode(): crypto-random zero-padded 6-digit code.
- Verification.Attempts: track failed OTP entries (enforce a max before resend).
- NewEmailVerificationCode(): constructor producing an email verification record
  whose Token holds the OTP code.

Covered by account/otp_test.go. Subsequent commits add the store lookup,
engine issue/verify, API, and notification wiring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wire the missing email-verification flow end-to-end on the engine/store side:

- Engine: IssueEmailVerification (mint 6-digit OTP, store it, fire
  ActionEmailVerificationRequested carrying the code) and VerifyEmailCode
  (per-user lookup, expiry, max-attempts, constant-time compare → set
  EmailVerified). SignUp now issues a code for unverified users. Adds
  ErrTooManyAttempts.
- Store: GetActiveEmailVerification(userID) + UpdateVerification on the
  interface and all four backends (memory/postgres/sqlite/mongo), plus an
  `attempts` column and a non-unique token index (6-digit codes are not
  globally unique) with a per-user active-code index.

Covered by service_otp_test.go (issue, wrong→right, max-attempts) and
account/otp_test.go.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- API: POST /v1/verify-email now accepts {code} (verifies the authenticated
  session user's email via VerifyEmailCode) in addition to legacy {token};
  ErrTooManyAttempts maps to HTTP 429.
- Engine: SendEmailVerification + SignUp + resend all delegate to one OTP issue
  path (issueEmailVerificationForUser), so the hook carries `code` everywhere.
- Notification: OnAfterUserCreate is now a no-op — the engine owns issuance and
  fires ActionEmailVerificationRequested (carrying the code), delivered by
  handleHookEvent. Stops the previous duplicate, tokenless email.
- Update the resend hook test to assert the 6-digit code.

Full backend suite (account/api/memory/plugins/root) green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The @authsome/ui-components EmailVerificationForm submits the OTP as
{token: <6-digit code>}. Detect a 6-digit numeric value from an authenticated
session user and verify it via the secure per-user VerifyEmailCode path
(attempt-limited, constant-time) instead of the global token lookup; long
tokens and the unauthenticated fallback still use VerifyEmail.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
authsome_verifications.env_id is a non-null FK, but the OTP issue path never
set it, so CreateVerification failed with fk_authsome_verifications_env and no
code was ever minted. Populate EnvID from the app's default environment before
insert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
authsome Ready Ready Preview, Comment Jun 7, 2026 6:50pm

Request Review

@juicycleff juicycleff merged commit 074850f into main Jun 7, 2026
12 checks passed
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