Skip to content

Add email verification flow#7

Merged
veverkap merged 5 commits into
mainfrom
copilot/add-email-verification
Apr 17, 2026
Merged

Add email verification flow#7
veverkap merged 5 commits into
mainfrom
copilot/add-email-verification

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

Users can sign up but cannot log in until their email address is verified. Verification uses the same SHA-256 hash-of-random-token pattern as API keys.

auth package

  • User gains EmailVerified bool
  • ErrEmailNotVerified sentinel added
  • EmailVerificationToken struct and EmailVerificationStore interface:
    • CreateEmailVerification — stores SHA-256 hash of plaintext token
    • ConsumeEmailVerification — single-use lookup-and-delete by hash; returns sql.ErrNoRows when not found
    • SetEmailVerified — marks user verified

handler package

EmailVerificationHandler (new file) — two public endpoints:

  • SendVerification (POST) — generates 32-byte random token, stores hash, calls SendEmail(ctx, to, plaintext). Always returns 200 regardless of whether the address is registered.
  • VerifyEmail (GET ?token=…) — re-hashes token, consumes record, checks expiry, calls SetEmailVerified.

AuthHandler changes:

  • RequireVerification bool — when set, Login returns 403 for unverified users.
  • UserDTO gains email_verified JSON field.

Usage sketch

verHandler := &handler.EmailVerificationHandler{
    Users:         userStore,
    Verifications: verificationStore,
    SendEmail: func(ctx context.Context, to, token string) error {
        link := "https://example.com/verify-email?token=" + token
        // format and send via smtp.Send(...)
    },
}

authHandler := &handler.AuthHandler{
    Users:               userStore,
    JWT:                 jwtManager,
    RequireVerification: true,
}

// Routes (router-agnostic):
// POST /verify-email/send  → verHandler.SendVerification
// GET  /verify-email       → verHandler.VerifyEmail

Agent-Logs-Url: https://github.com/amalgamated-tools/goauth/sessions/231b8073-f099-43f4-9313-9458cfdfb80e

Co-authored-by: veverkap <22348+veverkap@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an email verification flow to the auth/handler layers so applications can require users to verify their email before logging in.

Changes:

  • Introduces EmailVerificationHandler with endpoints to send and verify email verification tokens.
  • Extends auth.User / handler.UserDTO with EmailVerified and blocks login when AuthHandler.RequireVerification is enabled.
  • Adds EmailVerificationToken + EmailVerificationStore interface, plus new handler-level tests covering the flow.
Show a summary per file
File Description
handler/email_verification.go New HTTP endpoints for sending/consuming verification tokens and marking users verified.
handler/email_verification_test.go New tests for send/verify endpoints and RequireVerification login behavior.
handler/auth.go Adds RequireVerification gate in Login and exposes email_verified in UserDTO.
auth/types.go Adds EmailVerified, new sentinel error, and email verification store/token types.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 4/4 changed files
  • Comments generated: 4

Comment thread handler/email_verification.go Outdated
Comment thread handler/auth.go Outdated
Comment on lines +25 to +31
Users auth.UserStore
JWT *auth.JWTManager
CookieName string
SecureCookies bool
DisableSignup bool
RequireVerification bool
Verifications auth.EmailVerificationStore
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AuthHandler now includes an exported Verifications field that is not used anywhere in this file. Leaving unused exported fields increases API surface and (because this is a public struct) creates avoidable compatibility risk for any consumers using positional composite literals. Consider removing this field until it’s needed, or wiring it into behavior in this PR.

Suggested change
Users auth.UserStore
JWT *auth.JWTManager
CookieName string
SecureCookies bool
DisableSignup bool
RequireVerification bool
Verifications auth.EmailVerificationStore
Users auth.UserStore
JWT *auth.JWTManager
CookieName string
SecureCookies bool
DisableSignup bool
RequireVerification bool

Copilot uses AI. Check for mistakes.
Comment thread auth/types.go
Comment thread handler/email_verification_test.go
Resolved conflict in auth/types.go by combining email verification
errors/interfaces from this branch with TOTP and password reset
errors/interfaces from main.
@veverkap veverkap merged commit 756bc7e into main Apr 17, 2026
27 checks passed
@veverkap veverkap deleted the copilot/add-email-verification branch April 17, 2026 01:03
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.

3 participants