emailpassword

package
v0.27.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// PluginID is the unique string identifier for the EmailPassword plugin ("email-password").
	PluginID = "email-password"

	// CredentialProvider is the provider key used for password-based accounts ("credential").
	CredentialProvider = "credential"
)
View Source
const (
	// EventSignUpBefore is emitted right before persisting a new user record.
	// Event listeners can inspect and mutate parameters (e.g. payload.Params.Set("role", "admin")).
	// Payload: *SignUpEventPayload
	EventSignUpBefore = "emailpassword:signup:before"

	// EventSignUpAfter is emitted immediately after successfully registering a user and creating their credential account.
	// Useful for triggering welcome notifications or provisioning external tenant resources.
	// Payload: *SignUpEventPayload
	EventSignUpAfter = "emailpassword:signup:after"

	// EventSignInBefore is emitted before validating credentials during sign-in.
	// Payload: *SignInEventPayload
	EventSignInBefore = "emailpassword:signin:before"

	// EventSignInAfter is emitted after successfully verifying user credentials.
	// Useful for security audit logs, geo-IP notifications, or analytics tracking.
	// Payload: *SignInEventPayload
	EventSignInAfter = "emailpassword:signin:after"

	// EventPasswordChangeBefore is emitted before updating a user's password in storage.
	// Payload: *PasswordChangeEventPayload
	EventPasswordChangeBefore = "emailpassword:password_change:before"

	// EventPasswordChangeAfter is emitted after successfully updating a user's password in storage.
	// Payload: *PasswordChangeEventPayload
	EventPasswordChangeAfter = "emailpassword:password_change:after"

	// EventPasswordResetRequested is emitted when a secure password reset token is generated.
	// Essential for dispatching password reset emails containing the recovery token link.
	// Payload: *PasswordResetRequestedEventPayload
	EventPasswordResetRequested = "emailpassword:password_reset:requested"

	// EventPasswordResetCompleted is emitted after a password has been successfully reset using a valid token.
	// Useful for sending security confirmation alerts.
	// Payload: *PasswordResetCompletedEventPayload
	EventPasswordResetCompleted = "emailpassword:password_reset:completed"

	// EventEmailVerificationRequested is emitted when an email verification token is created.
	// Essential for dispatching verification emails with the activation link.
	// Payload: *EmailVerificationRequestedEventPayload
	EventEmailVerificationRequested = "emailpassword:email_verification:requested"

	// EventEmailVerified is emitted after an email verification token is successfully consumed and validated.
	// Useful for unlocking restricted user privileges.
	// Payload: *EmailVerifiedEventPayload
	EventEmailVerified = "emailpassword:email_verification:verified"
)
View Source
const (
	// ExtraKeyRole represents the user's assigned role during registration (e.g. "admin", "user").
	ExtraKeyRole = "role"

	// ExtraKeyOrganizationID represents the unique identifier of the organization to assign the user to.
	ExtraKeyOrganizationID = "organization_id"

	// ExtraKeyOrgID is a shorthand alias for ExtraKeyOrganizationID.
	ExtraKeyOrgID = "org_id"

	// ExtraKeyPhone represents the user's contact phone number.
	ExtraKeyPhone = "phone"

	// ExtraKeyPhoneNumber is an alias for ExtraKeyPhone.
	ExtraKeyPhoneNumber = "phone_number"

	// ExtraKeyAvatar represents the avatar image URL for the user.
	ExtraKeyAvatar = "avatar"

	// ExtraKeyLocale represents the preferred language/locale code of the user (e.g. "en-US", "es-ES").
	ExtraKeyLocale = "locale"

	// ExtraKeyPermissions represents initial permissions assigned to the user.
	ExtraKeyPermissions = "permissions"

	// ExtraKeyMetadata represents arbitrary structured user metadata.
	ExtraKeyMetadata = "metadata"

	// ExtraKeyIsAnonymous indicates whether the registered account is a temporary or anonymous account.
	ExtraKeyIsAnonymous = "is_anonymous"

	// ExtraKeyDeviceID represents the unique hardware or client installation identifier.
	ExtraKeyDeviceID = "device_id"

	// ExtraKeyIPAddress represents the client IP address initiating the authentication request.
	ExtraKeyIPAddress = "ip_address"

	// ExtraKeyUserAgent represents the User-Agent header of the client device.
	ExtraKeyUserAgent = "user_agent"

	// ExtraKeyCallbackURL represents the redirect or callback URL for verification or reset links.
	ExtraKeyCallbackURL = "callback_url"
)

Standard Extra metadata keys that can be set or consumed in EmailPassword parameters and events (such as SignUpParams.Extra, SignInParams.Extra, and Event payloads).

View Source
const (
	// ContextKeyVerificationTokenPrefix is the prefix used when caching email verification tokens in plugin.Context.
	ContextKeyVerificationTokenPrefix = "emailpassword:verification_token:"

	// ContextKeyResetTokenPrefix is the prefix used when caching password reset tokens in plugin.Context.
	ContextKeyResetTokenPrefix = "emailpassword:reset_token:"
)

Shared plugin context keys stored in plugin.Context for transient state management.

Variables

View Source
var (
	// ErrUserAlreadyExists is returned when attempting to register an email address already bound to an existing user.
	ErrUserAlreadyExists = errors.New("emailpassword: user already exists")

	// ErrUserNotFound is returned by repository methods when no user record matches the queried identifier or email.
	ErrUserNotFound = errors.New("emailpassword: user not found")

	// ErrAccountNotFound is returned when credentials for the requested provider are missing in storage.
	ErrAccountNotFound = errors.New("emailpassword: credential account not found")

	// ErrInvalidToken is returned when a password reset or email verification token does not exist in storage.
	ErrInvalidToken = errors.New("emailpassword: verification token invalid")

	// ErrTokenExpired is returned when a submitted verification or reset token has passed its expiration time.
	ErrTokenExpired = errors.New("emailpassword: token has expired")

	// ErrInvalidCurrentPass is returned when the user provides an incorrect current password during a password change.
	ErrInvalidCurrentPass = errors.New("emailpassword: current password is incorrect")

	// ErrEmailNotVerified is returned when sign-in is attempted and email verification is strictly enforced.
	ErrEmailNotVerified = errors.New("emailpassword: email address has not been verified")

	// ErrPasswordTooShort is returned when a password does not satisfy the configured minimum length requirement.
	ErrPasswordTooShort = errors.New("emailpassword: password does not meet the minimum length requirement")

	// ErrPasswordTooLong is returned when a password exceeds the configured maximum length limit.
	ErrPasswordTooLong = errors.New("emailpassword: password exceeds the maximum allowed length")

	// ErrInvalidEmail is returned when an email format validation fails.
	ErrInvalidEmail = errors.New("emailpassword: invalid email address format")

	// ErrInvalidCredentials is returned when email lookup fails or password hash comparison does not match.
	ErrInvalidCredentials = errors.New("emailpassword: invalid credentials")

	// ErrInvalidParameter is returned when a required argument or parameter is missing or malformed.
	ErrInvalidParameter = errors.New("emailpassword: required parameter is missing or invalid")
)

Functions

func ResetTokenContextKey added in v0.7.0

func ResetTokenContextKey(token string) string

ResetTokenContextKey formats the context store key used to track a password reset token.

func VerificationTokenContextKey added in v0.7.0

func VerificationTokenContextKey(token string) string

VerificationTokenContextKey formats the context store key used to track an email verification token.

Types

type Config

type Config struct {
	// MinPasswordLength specifies the minimum acceptable length for user passwords (default: 8).
	MinPasswordLength int

	// MaxPasswordLength specifies the maximum acceptable length for user passwords (default: 128).
	MaxPasswordLength int

	// RequireEmailVerification enforces that user.EmailVerified must be true before sign-in succeeds (default: false).
	RequireEmailVerification bool

	// SendVerificationOnSignUp automatically generates and dispatches an email verification token upon registration (default: false).
	SendVerificationOnSignUp bool

	// ResetTokenExpiry specifies the duration for which password reset tokens remain valid (default: 15 minutes).
	ResetTokenExpiry time.Duration

	// VerificationTokenExpiry specifies the duration for which email verification tokens remain valid (default: 24 hours).
	VerificationTokenExpiry time.Duration

	// SendResetPasswordEmail is an optional callback invoked when a password reset token is requested.
	SendResetPasswordEmail SendEmailFunc

	// SendVerificationEmail is an optional callback invoked when an email verification token is requested.
	SendVerificationEmail SendEmailFunc
}

Config defines the configurable options and callbacks for the EmailPassword plugin.

func DefaultConfig added in v0.7.0

func DefaultConfig() Config

DefaultConfig returns the safe production default configuration values for the EmailPassword plugin.

type EmailVerificationRequestedEventPayload added in v0.7.0

type EmailVerificationRequestedEventPayload struct {
	// User is the target user entity requiring email verification.
	User *entity.User

	// Token is the secure random token generated for email verification.
	Token string

	// ExpiresAt specifies the expiration timestamp for the verification token.
	ExpiresAt time.Time

	// Extra holds dynamic request metadata.
	Extra map[string]any
}

EmailVerificationRequestedEventPayload contains details required to dispatch an email verification message.

type EmailVerifiedEventPayload added in v0.7.0

type EmailVerifiedEventPayload struct {
	// User is the user entity whose email was verified.
	User *entity.User

	// Extra holds dynamic request metadata.
	Extra map[string]any
}

EmailVerifiedEventPayload contains confirmation details after a user's email has been verified.

type Option

type Option func(*Config)

Option defines a functional option for configuring the EmailPassword plugin.

func WithMaxPasswordLength added in v0.7.0

func WithMaxPasswordLength(length int) Option

WithMaxPasswordLength sets the maximum allowed password length.

func WithMinPasswordLength

func WithMinPasswordLength(length int) Option

WithMinPasswordLength sets the minimum required password length during registration and password change operations.

func WithRequireEmailVerification

func WithRequireEmailVerification(require bool) Option

WithRequireEmailVerification defines whether email verification is strictly required before sign-in succeeds.

func WithResetTokenExpiry

func WithResetTokenExpiry(d time.Duration) Option

WithResetTokenExpiry sets the validity duration for generated password reset tokens.

func WithSendResetPasswordEmail added in v0.7.0

func WithSendResetPasswordEmail(fn SendEmailFunc) Option

WithSendResetPasswordEmail registers an email delivery callback invoked during password reset requests.

func WithSendVerificationEmail added in v0.7.0

func WithSendVerificationEmail(fn SendEmailFunc) Option

WithSendVerificationEmail registers an email delivery callback invoked during email verification requests.

func WithSendVerificationOnSignUp added in v0.7.0

func WithSendVerificationOnSignUp(send bool) Option

WithSendVerificationOnSignUp configures whether to automatically send a verification email upon user registration.

func WithVerificationTokenExpiry added in v0.7.0

func WithVerificationTokenExpiry(d time.Duration) Option

WithVerificationTokenExpiry sets the validity duration for generated email verification tokens.

type PasswordChangeEventPayload

type PasswordChangeEventPayload struct {
	// UserID identifies the user whose password is being modified.
	UserID string

	// Extra holds dynamic request metadata.
	Extra map[string]any
}

PasswordChangeEventPayload contains the user identifier for password change lifecycle events.

type PasswordResetCompletedEventPayload

type PasswordResetCompletedEventPayload struct {
	// UserID identifies the user whose password was reset.
	UserID string

	// Extra holds dynamic request metadata.
	Extra map[string]any
}

PasswordResetCompletedEventPayload contains confirmation details after a password reset has completed.

type PasswordResetRequestedEventPayload

type PasswordResetRequestedEventPayload struct {
	// User is the target user entity requesting the reset.
	User *entity.User

	// Token is the secure random token generated for the password reset request.
	Token string

	// ExpiresAt specifies the exact expiration time for the reset token.
	ExpiresAt time.Time

	// Extra holds dynamic request metadata.
	Extra map[string]any
}

PasswordResetRequestedEventPayload contains details required to dispatch a password reset email to a user.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin implements the modular authentication Plugin interface for credential-based email and password workflows.

func New

func New(repo Repository, opts ...Option) *Plugin

New creates and initializes a new EmailPassword plugin instance with the specified repository and functional options.

Arguments:

  • repo: Implementation of the emailpassword.Repository storage interface.
  • opts: Optional functional configuration options (WithMinPasswordLength, WithRequireEmailVerification, etc.).

Returns:

  • *Plugin: The configured EmailPassword plugin instance ready for registration in auth.New.

func (*Plugin) ChangePassword

func (p *Plugin) ChangePassword(ctx context.Context, input dto.ChangePasswordParams) error

ChangePassword updates an existing authenticated user's password after verifying their current password.

Brief Explanation:

Verifies the current password against stored credentials to prevent unauthorized modification,
enforces password length requirements, computes the new password hash, updates storage,
and emits EventPasswordChangeBefore and EventPasswordChangeAfter.

Function:

User settings and self-service password update workflow.

Arguments:

  • ctx: Request cancellation context.
  • input: dto.ChangePasswordParams containing:
  • UserID (string, required): Authenticated user's unique identifier.
  • CurrentPassword (string, required): Current password for authorization.
  • NewPassword (string, required): New password to set.
  • Extra (map[string]any, optional): Dynamic metadata.

Returns:

  • error: ErrPasswordTooShort, ErrPasswordTooLong, ErrAccountNotFound, ErrInvalidCurrentPass, or database error.

Example:

err := epPlugin.ChangePassword(ctx, dto.ChangePasswordParams{
	UserID:          "usr_12345",
	CurrentPassword: "OldPassword123!",
	NewPassword:     "NewBrandPassword456!",
})
if err != nil {
	log.Fatalf("Password change failed: %v", err)
}

func (*Plugin) ForgotPassword

func (p *Plugin) ForgotPassword(ctx context.Context, input dto.ForgotPasswordParams) (*entity.VerificationToken, error)

ForgotPassword initiates a tokenized password recovery workflow for a user.

Brief Explanation:

Finds the user by email, generates a 32-byte cryptographically secure random token, persists the token
with an expiration timestamp, invokes the SendResetPasswordEmail callback (if configured), and publishes EventPasswordResetRequested.

Function:

Initial step of forgot-password and account recovery.

Arguments:

  • ctx: Request cancellation context.
  • input: dto.ForgotPasswordParams containing:
  • Email (string, required): User email address requesting reset.
  • Extra (map[string]any, optional): Dynamic metadata.

Returns:

  • *entity.VerificationToken: The generated verification token entity (containing Token string and ExpiresAt).
  • error: ErrInvalidEmail, ErrUserNotFound, or database error.

Example:

token, err := epPlugin.ForgotPassword(ctx, dto.ForgotPasswordParams{
	Email: "john.doe@example.com",
})
if err != nil {
	log.Fatalf("Forgot password failed: %v", err)
}
fmt.Printf("Reset token generated: %s (expires at %v)\n", token.Token, token.ExpiresAt)

func (*Plugin) ID

func (p *Plugin) ID() string

ID returns the unique identifier for the plugin ("email-password").

func (*Plugin) Init

func (p *Plugin) Init(ctx *plugin.Context) error

Init initializes the plugin within the global GoModularAuth runtime context.

func (*Plugin) ResetPassword

func (p *Plugin) ResetPassword(ctx context.Context, input dto.ResetPasswordParams) error

ResetPassword completes a password reset by consuming a single-use token and setting a new password.

Brief Explanation:

Validates token existence and expiry, hashes the new password, updates the user's credential account,
atomically deletes the consumed token to guarantee single-use safety, and emits EventPasswordResetCompleted.

Function:

Final step of forgot-password and recovery verification.

Arguments:

  • ctx: Request cancellation context.
  • input: dto.ResetPasswordParams containing:
  • Token (string, required): Single-use recovery token from email.
  • NewPassword (string, required): New password to set.
  • Extra (map[string]any, optional): Dynamic metadata.

Returns:

  • error: ErrInvalidParameter, ErrPasswordTooShort, ErrPasswordTooLong, ErrInvalidToken, ErrTokenExpired, ErrUserNotFound, or database error.

Example:

err := epPlugin.ResetPassword(ctx, dto.ResetPasswordParams{
	Token:       "9a8b7c6d5e4f3a2b1c0d",
	NewPassword: "BrandNewSecurePassword123!",
})
if err != nil {
	log.Fatalf("Password reset failed: %v", err)
}

func (*Plugin) SendVerificationEmail added in v0.7.0

func (p *Plugin) SendVerificationEmail(ctx context.Context, input dto.SendVerificationEmailParams) (*entity.VerificationToken, error)

SendVerificationEmail generates and dispatches an email verification token to the user.

Brief Explanation:

Looks up the user by email, generates a cryptographically secure verification token with expiration,
persists it in storage, executes the SendVerificationEmail callback (if registered), and emits EventEmailVerificationRequested.

Function:

Initiates the email verification workflow.

Arguments:

  • ctx: Request cancellation context.
  • input: dto.SendVerificationEmailParams containing:
  • Email (string, required): Target user email address.
  • Extra (map[string]any, optional): Dynamic metadata.

Returns:

  • *entity.VerificationToken: The generated verification token entity.
  • error: ErrInvalidEmail, ErrUserNotFound, or database error.

Example:

token, err := epPlugin.SendVerificationEmail(ctx, dto.SendVerificationEmailParams{
	Email: "john.doe@example.com",
})
if err != nil {
	log.Fatalf("Send verification failed: %v", err)
}
fmt.Printf("Verification token: %s\n", token.Token)

func (*Plugin) SignIn

func (p *Plugin) SignIn(ctx context.Context, input dto.SignInParams) (*entity.User, error)

SignIn authenticates user credentials by verifying email existence and comparing the password hash.

Brief Explanation:

Fetches the user and corresponding credentials account, securely verifies the password using constant-time
comparison, checks email verification prerequisites (if configured), and publishes EventSignInBefore and EventSignInAfter.
Mitigates timing attacks and user enumeration by executing a constant-time fake password hash if the user does not exist.

Function:

Primary entry point for user login authentication.

Arguments:

  • ctx: Request cancellation context.
  • input: dto.SignInParams containing:
  • Email (string, required): User email address.
  • Password (string, required): Plaintext password to compare against stored hash.
  • Extra (map[string]any, optional): Dynamic metadata passed through event interceptors.

Returns:

  • *entity.User: The authenticated user profile.
  • error: ErrInvalidCredentials, ErrEmailNotVerified, or database error.

Example:

user, err := epPlugin.SignIn(ctx, dto.SignInParams{
	Email:    "john.doe@example.com",
	Password: "SuperSecretPassword123!",
})
if err != nil {
	log.Fatalf("Authentication failed: %v", err)
}
fmt.Printf("Authenticated as: %s\n", user.Name)

func (*Plugin) SignUp

func (p *Plugin) SignUp(ctx context.Context, input dto.SignUpParams) (*entity.User, error)

SignUp registers a new user with email and password credentials.

Brief Explanation:

Validates email and password constraints, ensures email uniqueness, securely hashes the password,
publishes the EventSignUpBefore event (enabling listeners to mutate parameters or inject dynamic metadata),
persists both the user entity and credential account, optionally dispatches email verification, and publishes EventSignUpAfter.

Function:

Primary entry point for user registration.

Arguments:

  • ctx: Request cancellation context.
  • input: dto.SignUpParams containing:
  • Name (string, required): Display name of the user.
  • Email (string, required): User's primary email address.
  • Password (string, required): Plaintext password to hash and validate.
  • Extra (map[string]any, optional): Dynamic metadata (e.g. role, organization, phone).

Returns:

  • *entity.User: The persisted user entity containing generated ID and timestamps.
  • error: ErrInvalidEmail, ErrPasswordTooShort, ErrPasswordTooLong, ErrUserAlreadyExists, or database error.

Example:

user, err := epPlugin.SignUp(ctx, dto.SignUpParams{
	Name:     "John Doe",
	Email:    "john.doe@example.com",
	Password: "SuperSecretPassword123!",
})
if err != nil {
	log.Fatalf("Sign up failed: %v", err)
}
fmt.Printf("Created user with ID: %s\n", user.ID)

func (*Plugin) VerifyEmail added in v0.7.0

func (p *Plugin) VerifyEmail(ctx context.Context, input dto.VerifyEmailParams) (*entity.User, error)

VerifyEmail completes the email confirmation process by consuming a valid verification token.

Brief Explanation:

Validates token existence and expiry, marks user.EmailVerified as true in persistent storage,
deletes the consumed single-use token, and emits EventEmailVerified.

Function:

Completes the email confirmation process.

Arguments:

  • ctx: Request cancellation context.
  • input: dto.VerifyEmailParams containing:
  • Token (string, required): Single-use verification token from email link.
  • Extra (map[string]any, optional): Dynamic metadata.

Returns:

  • *entity.User: The updated user entity with EmailVerified set to true.
  • error: ErrInvalidParameter, ErrInvalidToken, ErrTokenExpired, ErrUserNotFound, or database error.

Example:

verifiedUser, err := epPlugin.VerifyEmail(ctx, dto.VerifyEmailParams{
	Token: "abc123token456",
})
if err != nil {
	log.Fatalf("Email verification failed: %v", err)
}
fmt.Printf("User %s email verified: %v\n", verifiedUser.Email, verifiedUser.EmailVerified)

func (*Plugin) VerifyPassword added in v0.7.0

func (p *Plugin) VerifyPassword(ctx context.Context, input dto.VerifyPasswordParams) (bool, error)

VerifyPassword validates whether the provided password matches the user's stored credential password.

Brief Explanation:

Fetches the user's credential account and performs constant-time password comparison.
Useful for high-security operations (e.g. 2FA enrollment, modifying sensitive account settings).

Function:

Credential verification and re-authentication check.

Arguments:

  • ctx: Request cancellation context.
  • input: dto.VerifyPasswordParams containing:
  • UserID (string, required): User ID to verify.
  • Password (string, required): Plaintext password to check.
  • Extra (map[string]any, optional): Dynamic metadata.

Returns:

  • bool: True if password matches, false otherwise.
  • error: ErrInvalidParameter, ErrAccountNotFound, or database error.

Example:

valid, err := epPlugin.VerifyPassword(ctx, dto.VerifyPasswordParams{
	UserID:   "usr_12345",
	Password: "CurrentPassword123!",
})
if err != nil || !valid {
	log.Println("Password verification failed")
}

type Repository

type Repository interface {
	// GetUserByEmail retrieves a user entity matching the provided unique email address.
	//
	// Function:
	//   Used during SignUp, SignIn, ForgotPassword, and SendVerificationEmail to check user existence and fetch profile details.
	//
	// Storage:
	//   Database (GORM / SQL) - Relational user entity query by email.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - email: The normalized email address to query.
	//
	// Returns:
	//   - *entity.User: The matching user entity if found.
	//   - error: ErrUserNotFound if no record matches, or database error.
	//
	// Example SQL:
	//   SELECT id, email, name, email_verified, created_at, updated_at FROM users WHERE email = $1 LIMIT 1;
	GetUserByEmail(ctx context.Context, email string) (*entity.User, error)

	// GetUserByID retrieves a user entity matching the given unique identifier.
	//
	// Function:
	//   Used during ChangePassword, ResetPassword, VerifyPassword, and VerifyEmail flows.
	//
	// Storage:
	//   Database (GORM / SQL) - Primary key user lookup.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - id: The unique primary key identifier of the user (e.g. UUID).
	//
	// Returns:
	//   - *entity.User: The matching user entity.
	//   - error: ErrUserNotFound if no record matches, or database error.
	//
	// Example SQL:
	//   SELECT id, email, name, email_verified, created_at, updated_at FROM users WHERE id = $1 LIMIT 1;
	GetUserByID(ctx context.Context, id string) (*entity.User, error)

	// CreateUser persists a new user record generated from the provided registration parameters.
	//
	// Function:
	//   Called during SignUp to persist the primary user entity. Plugins may inspect or modify
	//   params.Extra before this method is called via EventSignUpBefore.
	//
	// Storage:
	//   Database (GORM / SQL) - User domain entity creation.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - params: Pointer to CreateUserParams containing Email, Name, PasswordHash, and Extra metadata.
	//
	// Returns:
	//   - *entity.User: The newly created user entity with populated ID and timestamps.
	//   - error: ErrUserAlreadyExists on unique constraint violation, or database error.
	//
	// Example SQL:
	//   INSERT INTO users (id, email, name, password_hash, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6);
	CreateUser(ctx context.Context, params *dto.CreateUserParams) (*entity.User, error)

	// UpdateUser updates an existing user profile record in storage.
	//
	// Function:
	//   Used when updating user metadata, email verification state (email_verified = true), or profile attributes.
	//
	// Storage:
	//   Database (GORM / SQL) - User record update.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - user: The updated user entity to persist.
	//
	// Returns:
	//   - error: Nil on success, ErrUserNotFound if the record is missing, or database error.
	//
	// Example SQL:
	//   UPDATE users SET email = $1, name = $2, email_verified = $3, updated_at = $4 WHERE id = $5;
	UpdateUser(ctx context.Context, user *entity.User) error

	// GetAccountByUserIDAndProvider retrieves the credential account associated with a user and authentication provider.
	//
	// Function:
	//   Used during SignIn, ChangePassword, and VerifyPassword to retrieve stored hashed passwords (provider: "credential").
	//
	// Storage:
	//   Database (GORM / SQL) - Account credentials query.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - userID: The target user's ID.
	//   - provider: The authentication provider identifier (typically "credential").
	//
	// Returns:
	//   - *entity.Account: The matching credentials account containing the password hash.
	//   - error: ErrAccountNotFound if no record matches, or database error.
	//
	// Example SQL:
	//   SELECT id, user_id, provider, password, created_at FROM accounts WHERE user_id = $1 AND provider = $2 LIMIT 1;
	GetAccountByUserIDAndProvider(ctx context.Context, userID, provider string) (*entity.Account, error)

	// CreateAccount persists a new provider credentials record associated with a user.
	//
	// Function:
	//   Called immediately after CreateUser during SignUp to link credential passwords to the user.
	//
	// Storage:
	//   Database (GORM / SQL) - Account record creation.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - account: The credentials account entity to insert.
	//
	// Returns:
	//   - error: Nil on success, or database error on failure.
	//
	// Example SQL:
	//   INSERT INTO accounts (id, user_id, provider, password, created_at) VALUES ($1, $2, $3, $4, $5);
	CreateAccount(ctx context.Context, account *entity.Account) error

	// UpdateAccountPassword updates the hashed password for a specific account record.
	//
	// Function:
	//   Called during ChangePassword and ResetPassword to overwrite the stored password hash.
	//
	// Storage:
	//   Database (GORM / SQL) - Password hash update.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - accountID: Primary key ID of the account record to update.
	//   - hashedPassword: The newly computed password hash.
	//
	// Returns:
	//   - error: Nil on success, ErrAccountNotFound if missing, or database error.
	//
	// Example SQL:
	//   UPDATE accounts SET password = $1, updated_at = $2 WHERE id = $3;
	UpdateAccountPassword(ctx context.Context, accountID, hashedPassword string) error

	// CreateVerificationToken persists a short-lived token record for password resets or email confirmations.
	//
	// Function:
	//   Called during ForgotPassword and SendVerificationEmail to save the generated token and expiration timestamp.
	//
	// Storage:
	//   Cache (Redis / In-Memory TTL) - Short-lived verification token.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - token: The VerificationToken entity (Identifier/Email, Token, ExpiresAt).
	//
	// Returns:
	//   - error: Nil on success, or database error on failure.
	//
	// Example SQL:
	//   INSERT INTO verification_tokens (identifier, token, expires_at) VALUES ($1, $2, $3);
	//
	// Example Cache (Redis):
	//   err := rdb.Set(ctx, "reset_token:" + token.Token, token.Identifier, ttl).Err()
	CreateVerificationToken(ctx context.Context, token *entity.VerificationToken) error

	// GetVerificationToken retrieves an active token record by its token string.
	//
	// Function:
	//   Called during ResetPassword and VerifyEmail to validate token existence and verify whether it has expired.
	//
	// Storage:
	//   Cache (Redis / In-Memory TTL) - Verification token lookup.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - token: The raw token string submitted by the user.
	//
	// Returns:
	//   - *entity.VerificationToken: The matching token entity with its expiration timestamp.
	//   - error: ErrInvalidToken if no record is found, or database error.
	//
	// Example SQL:
	//   SELECT identifier, token, expires_at FROM verification_tokens WHERE token = $1 LIMIT 1;
	//
	// Example Cache (Redis):
	//   val, err := rdb.Get(ctx, "reset_token:" + token).Bytes()
	GetVerificationToken(ctx context.Context, token string) (*entity.VerificationToken, error)

	// DeleteVerificationToken removes a consumed or invalidated token from storage.
	//
	// Function:
	//   Called immediately upon successful password reset or email verification to guarantee single-use token consumption.
	//
	// Storage:
	//   Cache (Redis / In-Memory TTL) - Verification token key eviction.
	//
	// Arguments:
	//   - ctx: Request cancellation and deadline context.
	//   - token: The token string to delete.
	//
	// Returns:
	//   - error: Nil on success, or database error on failure.
	//
	// Example SQL:
	//   DELETE FROM verification_tokens WHERE token = $1;
	//
	// Example Cache (Redis):
	//   err := rdb.Del(ctx, "reset_token:" + token).Err()
	DeleteVerificationToken(ctx context.Context, token string) error
}

Repository defines the persistent storage contract required by the EmailPassword plugin. Implement this interface on your custom database adapter (e.g. PostgreSQL, MySQL, SQLite, MongoDB, GORM).

Implementation Example (GORM / database/sql):

type GormAuthRepository struct {
	db *gorm.DB
}

func (r *GormAuthRepository) GetUserByEmail(ctx context.Context, email string) (*entity.User, error) {
	var m UserModel
	if err := r.db.WithContext(ctx).Where("email = ?", email).First(&m).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, emailpassword.ErrUserNotFound
		}
		return nil, err
	}
	return m.ToEntity(), nil
}

func (r *GormAuthRepository) CreateUser(ctx context.Context, params *dto.CreateUserParams) (*entity.User, error) {
	m := UserModel{
		ID:           uuid.NewString(),
		Email:        params.Email,
		Name:         params.Name,
		PasswordHash: params.PasswordHash,
		CreatedAt:    time.Now(),
		UpdatedAt:    time.Now(),
	}
	if err := r.db.WithContext(ctx).Create(&m).Error; err != nil {
		return nil, err
	}
	return m.ToEntity(), nil
}

type SendEmailFunc added in v0.7.0

type SendEmailFunc func(ctx context.Context, email string, token string, expiresAt time.Time, extra map[string]any) error

SendEmailFunc defines the callback signature used to dispatch transactional emails (e.g. password resets or verification).

type SignInEventPayload

type SignInEventPayload struct {
	// User is the authenticated user entity.
	User *entity.User

	// Extra holds dynamic request metadata.
	Extra map[string]any
}

SignInEventPayload contains the authenticated user entity associated with a sign-in event.

type SignUpEventPayload

type SignUpEventPayload struct {
	// Params holds mutable user creation parameters (including dynamic Extra metadata).
	Params *dto.CreateUserParams

	// User contains the persisted user entity (populated in EventSignUpAfter).
	User *entity.User

	// Extra holds dynamic request metadata.
	Extra map[string]any
}

SignUpEventPayload contains the parameter and entity data associated with a sign-up event.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL