Documentation
¶
Index ¶
- func AppendPasswordHistory(user *models.User, newHash string, keepCount int)
- func CheckPasswordHistory(newPassword string, user *models.User, historyCount int) error
- func IsPasswordExpired(user *models.User, maxAgeDays int) bool
- func ParseCSVImport(r io.Reader) ([]dto.UserImportRow, []dto.UserImportRowError)
- func ParseJSONImport(r io.Reader) ([]dto.UserImportRow, []dto.UserImportRowError)
- func ResolveTokenTTLs(app *models.Application) (accessTTL, refreshTTL time.Duration)
- func ValidatePasswordPolicy(password string, app *models.Application) error
- type AssignDefaultRoleFunc
- type GroupLogoutFunc
- type Handler
- func (h *Handler) DeleteAccount(c *gin.Context)
- func (h *Handler) ForgotPassword(c *gin.Context)
- func (h *Handler) GetProfile(c *gin.Context)
- func (h *Handler) Login(c *gin.Context)
- func (h *Handler) Logout(c *gin.Context)
- func (h *Handler) RefreshToken(c *gin.Context)
- func (h *Handler) Register(c *gin.Context)
- func (h *Handler) RequestMagicLink(c *gin.Context)
- func (h *Handler) ResendVerification(c *gin.Context)
- func (h *Handler) ResetPassword(c *gin.Context)
- func (h *Handler) SetPassword(c *gin.Context)
- func (h *Handler) UpdateEmail(c *gin.Context)
- func (h *Handler) UpdatePassword(c *gin.Context)
- func (h *Handler) UpdateProfile(c *gin.Context)
- func (h *Handler) ValidateToken(c *gin.Context)
- func (h *Handler) VerifyEmail(c *gin.Context)
- func (h *Handler) VerifyMagicLink(c *gin.Context)
- type LoginResult
- type Repository
- func (r *Repository) ClearBackupEmail(userID string) error
- func (r *Repository) ClearLockout(userID string) error
- func (r *Repository) ClearPhone(userID string) error
- func (r *Repository) CreateUser(user *models.User) error
- func (r *Repository) DeleteUser(userID string) error
- func (r *Repository) Disable2FA(userID string) error
- func (r *Repository) Enable2FA(userID, secret, recoveryCodes string) error
- func (r *Repository) Enable2FAWithMethod(userID, secret, recoveryCodes, method string) error
- func (r *Repository) GetUserByEmail(appID, email string) (*models.User, error)
- func (r *Repository) GetUserByID(id string) (*models.User, error)
- func (r *Repository) RestorePreviousTwoFAMethod(userID string) error
- func (r *Repository) SaveAndSwitchToBackupEmail2FA(userID, previousMethod, previousSecret, recoveryCodes string) error
- func (r *Repository) SetBackupEmail(userID, backupEmail string) error
- func (r *Repository) SetPhoneNumber(userID, phone string) error
- func (r *Repository) UpdateRecoveryCodes(userID, recoveryCodes string) error
- func (r *Repository) UpdateUser(user *models.User) error
- func (r *Repository) UpdateUserEmail(userID, newEmail string) error
- func (r *Repository) UpdateUserEmailVerified(userID string, verified bool) error
- func (r *Repository) UpdateUserPassword(userID, hashedPassword string) error
- func (r *Repository) UpdateUserPasswordWithHistory(userID, hashedPassword string, history []byte) error
- func (r *Repository) UpdateUserProfile(userID string, updates map[string]interface{}) error
- func (r *Repository) VerifyBackupEmail(userID string) error
- func (r *Repository) VerifyPhoneNumber(userID string) error
- type RoleLookupFunc
- type Service
- func (s *Service) ConfirmPasswordReset(appID uuid.UUID, token, newPassword string) (uuid.UUID, *errors.AppError)
- func (s *Service) CreateSessionForUser(appID, userID uuid.UUID, ip, userAgent string) (accessToken, refreshToken string, appErr *errors.AppError)
- func (s *Service) DeleteUserAccount(appID uuid.UUID, userID string, req dto.DeleteAccountRequest) *errors.AppError
- func (s *Service) LoginUser(appID uuid.UUID, email, password, ip, userAgent string) (*LoginResult, *errors.AppError)
- func (s *Service) LogoutUser(appID, userID, sessionID, refreshToken, accessToken string) *errors.AppError
- func (s *Service) RefreshUserToken(refreshToken string, accessTTL, refreshTTL time.Duration) (string, string, string, *errors.AppError)
- func (s *Service) RegisterUser(appID uuid.UUID, email, password string) (uuid.UUID, *errors.AppError)
- func (s *Service) RequestMagicLink(appID uuid.UUID, email string) *errors.AppError
- func (s *Service) RequestPasswordReset(appID uuid.UUID, email string) *errors.AppError
- func (s *Service) ResendVerificationEmail(appID uuid.UUID, email string) *errors.AppError
- func (s *Service) RevokeAllUserTokens(appID, userID string) *errors.AppError
- func (s *Service) SetInitialPassword(appID uuid.UUID, userID string, newPassword string) *errors.AppError
- func (s *Service) UpdateUserEmail(appID uuid.UUID, userID string, req dto.UpdateEmailRequest) *errors.AppError
- func (s *Service) UpdateUserPassword(appID uuid.UUID, userID string, req dto.UpdatePasswordRequest) *errors.AppError
- func (s *Service) UpdateUserProfile(userID string, req dto.UpdateProfileRequest) *errors.AppError
- func (s *Service) VerifyEmail(appID uuid.UUID, token string) (uuid.UUID, *errors.AppError)
- func (s *Service) VerifyMagicLink(appID uuid.UUID, token, ip, userAgent string) (*LoginResult, *errors.AppError)
- type TrustedDeviceValidateFunc
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AppendPasswordHistory ¶
AppendPasswordHistory prepends the new bcrypt hash to the user's password history JSONB array and trims the array to at most keepCount entries. If keepCount is 0 the function is a no-op.
func CheckPasswordHistory ¶
CheckPasswordHistory verifies that the new plaintext password has not been used recently. It compares against the last `historyCount` hashes stored on the user record. Returns an error if the password was recently used. Returns nil when historyCount is 0 (feature disabled).
func IsPasswordExpired ¶
IsPasswordExpired reports whether the user's password has exceeded the application's maximum age. Returns false when maxAgeDays is 0 (disabled) or when PasswordChangedAt is nil (password was never explicitly changed — treat as never expired to avoid locking out legacy accounts on first deploy).
func ParseCSVImport ¶
func ParseCSVImport(r io.Reader) ([]dto.UserImportRow, []dto.UserImportRowError)
ParseCSVImport reads a CSV from r and returns valid rows plus per-row errors.
Expected header row: email, name, first_name, last_name, locale (case-insensitive). Column order is flexible — unknown columns are ignored. The first row is always treated as the header. Rows with empty or invalid email are collected as errors and excluded from the returned rows slice.
func ParseJSONImport ¶
func ParseJSONImport(r io.Reader) ([]dto.UserImportRow, []dto.UserImportRowError)
ParseJSONImport reads a JSON payload from r and returns valid rows plus per-row errors.
Accepts two formats:
- Top-level array: [{...}, ...]
- Object with key: {"users": [{...}, ...]}
Each object must have at minimum an "email" field. Optional fields: name, first_name, last_name, locale.
func ResolveTokenTTLs ¶
func ResolveTokenTTLs(app *models.Application) (accessTTL, refreshTTL time.Duration)
ResolveTokenTTLs returns the effective access and refresh token TTLs for an application. When the app has non-zero per-app overrides those are used; otherwise the function falls back to the global jwt defaults.
func ValidatePasswordPolicy ¶
func ValidatePasswordPolicy(password string, app *models.Application) error
ValidatePasswordPolicy checks a plaintext password against the application's configured password policy. Returns a descriptive error if the password does not meet requirements, or nil if it is acceptable.
Types ¶
type AssignDefaultRoleFunc ¶
AssignDefaultRoleFunc is called after user registration to assign the default role.
type GroupLogoutFunc ¶
type GroupLogoutFunc func(appID, userEmail string)
GroupLogoutFunc is called (in a goroutine) after a successful logout when the app belongs to an SSO session group with GlobalLogout enabled. It is wired from cmd/api/main.go via adminRepo to avoid an import cycle.
type Handler ¶
type Handler struct {
Service *Service
IPRuleEvaluator *geoip.IPRuleEvaluator // IP access control evaluator (nil = no IP rules)
AnomalyDetector *log.AnomalyDetector // Anomaly detector for login monitoring (nil = disabled)
BruteForceService *bruteforce.Service // Brute-force protection service (lockout, delays, CAPTCHA)
ValidateTrustedDevice TrustedDeviceValidateFunc // Optional: skip 2FA when a valid trusted-device cookie is present
}
func NewHandler ¶
func (*Handler) DeleteAccount ¶
@Summary Delete user account @Description Delete authenticated user's account permanently. Password is required for password-based accounts; omit for social-only (OAuth) accounts. @Tags User @Security ApiKeyAuth @Accept json @Produce json @Param delete body dto.DeleteAccountRequest true "Account Deletion Data" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /profile [delete]
func (*Handler) ForgotPassword ¶
@Summary Request password reset @Description Initiate password reset process @Tags Auth @Accept json @Produce json @Param email body dto.ForgotPasswordRequest true "User Email" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 429 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /forgot-password [post]
func (*Handler) GetProfile ¶
@Summary Get user profile @Description Retrieve authenticated user's profile information @Tags User @Security ApiKeyAuth @Produce json @Success 200 {object} dto.UserResponse @Failure 401 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /profile [get]
func (*Handler) Login ¶
@Summary User login @Description Authenticate user and issue JWTs @Tags Auth @Accept json @Produce json @Param login body dto.LoginRequest true "User Login Data" @Success 200 {object} dto.LoginResponse @Success 202 {object} dto.TwoFARequiredResponse "2FA verification or setup required" @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse "May include retry_after (seconds) advisory field" @Failure 403 {object} dto.CaptchaRequiredResponse "CAPTCHA verification required" @Failure 423 {object} dto.AccountLockedResponse "Account is locked" @Failure 500 {object} dto.ErrorResponse @Router /login [post]
func (*Handler) Logout ¶
@Summary User logout @Description Logout user and revoke refresh token @Tags Auth @Security ApiKeyAuth @Accept json @Produce json @Param logout body dto.LogoutRequest true "Logout Data" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /logout [post]
func (*Handler) RefreshToken ¶
@Summary Refresh access token @Description Get new access token using refresh token @Tags Auth @Accept json @Produce json @Param refresh body dto.RefreshTokenRequest true "Refresh Token" @Success 200 {object} dto.LoginResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 429 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /refresh-token [post]
func (*Handler) Register ¶
@Summary Register a new user @Description Register a new user with email and password @Tags Auth @Accept json @Produce json @Param registration body dto.RegisterRequest true "User Registration Data" @Success 201 {object} dto.UserResponse @Failure 400 {object} dto.ErrorResponse @Failure 409 {object} dto.ErrorResponse @Failure 429 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /register [post]
func (*Handler) RequestMagicLink ¶
@Summary Request a magic link login email @Description Send a magic link to the user's email for passwordless authentication. Always returns 200 regardless of whether the email exists (to prevent enumeration). @Tags Auth @Accept json @Produce json @Param request body dto.MagicLinkRequest true "Magic Link Request Data" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 429 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /magic-link/request [post]
func (*Handler) ResendVerification ¶
@Summary Resend email verification @Description Resend verification email to user. Returns a generic success message regardless of whether the email exists or is already verified (to prevent email enumeration). @Tags Auth @Accept json @Produce json @Param request body dto.ResendVerificationRequest true "Email address" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 429 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /resend-verification [post]
func (*Handler) ResetPassword ¶
@Summary Reset password @Description Complete password reset process @Tags Auth @Accept json @Produce json @Param reset body dto.ResetPasswordRequest true "Reset Token and New Password" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 429 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /reset-password [post]
func (*Handler) SetPassword ¶
@Summary Set initial password for social-only users @Description Set a password for a user who registered via social login and has no password yet. Returns 409 if a password is already set. @Tags User @Security ApiKeyAuth @Accept json @Produce json @Param request body dto.SetPasswordRequest true "New password" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 409 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /profile/set-password [post]
func (*Handler) UpdateEmail ¶
@Summary Update user email @Description Update authenticated user's email address (requires password verification and email re-verification) @Tags User @Security ApiKeyAuth @Accept json @Produce json @Param email body dto.UpdateEmailRequest true "Email Update Data" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 409 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /profile/email [put]
func (*Handler) UpdatePassword ¶
@Summary Update user password @Description Update authenticated user's password (requires current password verification) @Tags User @Security ApiKeyAuth @Accept json @Produce json @Param password body dto.UpdatePasswordRequest true "Password Update Data" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /profile/password [put]
func (*Handler) UpdateProfile ¶
@Summary Update user profile @Description Update authenticated user's profile information (name, first_name, last_name, profile_picture, locale) @Tags User @Security ApiKeyAuth @Accept json @Produce json @Param profile body dto.UpdateProfileRequest true "Profile Update Data" @Success 200 {object} dto.UserResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /profile [put]
func (*Handler) ValidateToken ¶
ValidateToken godoc @Summary Validate JWT Token @Description Validates a JWT token and returns basic user info for external services @Tags auth @Security ApiKeyAuth @Produce json @Success 200 {object} map[string]interface{} @Failure 401 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /auth/validate [get]
func (*Handler) VerifyEmail ¶
@Summary Verify email @Description Verify user's email address @Tags Auth @Produce json @Param token query string true "Verification Token" @Success 200 {object} dto.MessageResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /verify-email [get]
func (*Handler) VerifyMagicLink ¶
@Summary Verify a magic link token and log in @Description Verify the magic link token from the email and return access/refresh tokens. The token is single-use and expires after 10 minutes. @Tags Auth @Accept json @Produce json @Param request body dto.MagicLinkVerifyRequest true "Magic Link Verification Data" @Success 200 {object} dto.LoginResponse @Failure 400 {object} dto.ErrorResponse @Failure 401 {object} dto.ErrorResponse @Failure 403 {object} dto.ErrorResponse @Failure 429 {object} dto.ErrorResponse @Failure 500 {object} dto.ErrorResponse @Router /magic-link/verify [post]
type LoginResult ¶
type LoginResult struct {
RequiresTwoFA bool
RequiresTwoFASetup bool
PasswordExpired bool // true when the password has exceeded its max age; no tokens are issued
UserID uuid.UUID
AccessToken string // #nosec G101,G117 -- This is a result field, not a hardcoded credential
RefreshToken string // #nosec G101,G117 -- This is a result field, not a hardcoded credential
SessionID string
TwoFAResponse *dto.TwoFARequiredResponse
TwoFASetupResponse *dto.TwoFASetupRequiredResponse
}
LoginResult represents the result of a login attempt
type Repository ¶
type Repository struct {
// contains filtered or unexported fields
}
func NewRepository ¶
func NewRepository(pool *pgxpool.Pool) *Repository
func (*Repository) ClearBackupEmail ¶
func (r *Repository) ClearBackupEmail(userID string) error
ClearBackupEmail removes the backup email and its verified status.
func (*Repository) ClearLockout ¶
func (r *Repository) ClearLockout(userID string) error
ClearLockout clears the lockout fields for a user (auto-unlock on expired lockout).
func (*Repository) ClearPhone ¶
func (r *Repository) ClearPhone(userID string) error
ClearPhone removes the phone number and its verified status.
func (*Repository) CreateUser ¶
func (r *Repository) CreateUser(user *models.User) error
func (*Repository) DeleteUser ¶
func (r *Repository) DeleteUser(userID string) error
DeleteUser deletes a user and all related data within a transaction. FK-constrained tables (social_accounts, user_roles) are deleted first to avoid "update or delete violates foreign key constraint" errors from NO ACTION constraints.
func (*Repository) Disable2FA ¶
func (r *Repository) Disable2FA(userID string) error
Disable2FA disables 2FA for a user
func (*Repository) Enable2FA ¶
func (r *Repository) Enable2FA(userID, secret, recoveryCodes string) error
Enable2FA enables 2FA for a user and stores the secret and recovery codes. Defaults to TOTP method for backward compatibility.
func (*Repository) Enable2FAWithMethod ¶
func (r *Repository) Enable2FAWithMethod(userID, secret, recoveryCodes, method string) error
Enable2FAWithMethod enables 2FA for a user with a specific method ("totp" or "email").
func (*Repository) GetUserByEmail ¶
func (r *Repository) GetUserByEmail(appID, email string) (*models.User, error)
func (*Repository) GetUserByID ¶
func (r *Repository) GetUserByID(id string) (*models.User, error)
func (*Repository) RestorePreviousTwoFAMethod ¶
func (r *Repository) RestorePreviousTwoFAMethod(userID string) error
RestorePreviousTwoFAMethod reverts a user from backup_email 2FA back to their prior method. It reads the previously saved method/secret, restores them, and clears the "previous" fields. If no prior method was saved the user ends up with 2FA disabled.
func (*Repository) SaveAndSwitchToBackupEmail2FA ¶
func (r *Repository) SaveAndSwitchToBackupEmail2FA(userID, previousMethod, previousSecret, recoveryCodes string) error
SaveAndSwitchToBackupEmail2FA atomically saves the user's current 2FA method/secret as "previous" fields and switches the active method to backup_email. This allows DisableBackupEmail2FAMethod to fully restore the prior configuration.
func (*Repository) SetBackupEmail ¶
func (r *Repository) SetBackupEmail(userID, backupEmail string) error
SetBackupEmail sets the pending backup email for a user (not yet verified).
func (*Repository) SetPhoneNumber ¶
func (r *Repository) SetPhoneNumber(userID, phone string) error
SetPhoneNumber sets the phone number for a user (not yet verified).
func (*Repository) UpdateRecoveryCodes ¶
func (r *Repository) UpdateRecoveryCodes(userID, recoveryCodes string) error
UpdateRecoveryCodes updates the recovery codes for a user
func (*Repository) UpdateUser ¶
func (r *Repository) UpdateUser(user *models.User) error
func (*Repository) UpdateUserEmail ¶
func (r *Repository) UpdateUserEmail(userID, newEmail string) error
UpdateUserEmail updates user email and sets email_verified to false
func (*Repository) UpdateUserEmailVerified ¶
func (r *Repository) UpdateUserEmailVerified(userID string, verified bool) error
func (*Repository) UpdateUserPassword ¶
func (r *Repository) UpdateUserPassword(userID, hashedPassword string) error
func (*Repository) UpdateUserPasswordWithHistory ¶
func (r *Repository) UpdateUserPasswordWithHistory(userID, hashedPassword string, history []byte) error
UpdateUserPasswordWithHistory sets password_hash, password_history, and password_changed_at atomically.
func (*Repository) UpdateUserProfile ¶
func (r *Repository) UpdateUserProfile(userID string, updates map[string]interface{}) error
UpdateUserProfile updates user profile fields (name, first_name, last_name, profile_picture, locale). Accepts a map for backward compatibility with the service layer's partial-update logic. Reads current values first, merges provided updates, then writes all profile fields.
func (*Repository) VerifyBackupEmail ¶
func (r *Repository) VerifyBackupEmail(userID string) error
VerifyBackupEmail marks the backup email as verified.
func (*Repository) VerifyPhoneNumber ¶
func (r *Repository) VerifyPhoneNumber(userID string) error
VerifyPhoneNumber marks the phone number as verified.
type RoleLookupFunc ¶
RoleLookupFunc is a function that returns role names for a user in an app. Used to populate JWT claims with roles without importing the rbac package directly.
type Service ¶
type Service struct {
Repo *Repository
EmailService *emailpkg.Service
AppLookup func(appID string) (*models.Application, error) // Resolves app config by ID (wired in main.go)
SessionService *session.Service // Session management for multi-device tracking
LookupRoles RoleLookupFunc // Optional: if nil, tokens are generated without roles
AssignDefaultRole AssignDefaultRoleFunc // Optional: if nil, no default role is assigned on registration
WebhookService *webhook.Service // Optional: if nil, webhook dispatch is skipped
SMSSender sms.Sender // Optional: if nil, SMS 2FA auto-send is skipped
GroupLogoutFunc GroupLogoutFunc // Optional: if non-nil, called after logout for SSO group propagation
}
func NewService ¶
func NewService(r *Repository, es *emailpkg.Service) *Service
func (*Service) ConfirmPasswordReset ¶
func (*Service) CreateSessionForUser ¶
func (s *Service) CreateSessionForUser(appID, userID uuid.UUID, ip, userAgent string) (accessToken, refreshToken string, appErr *errors.AppError)
CreateSessionForUser creates a new authenticated session for a user by app+userID. Used by the trusted-device bypass in the Login handler to issue tokens when 2FA is skipped.
func (*Service) DeleteUserAccount ¶
func (s *Service) DeleteUserAccount(appID uuid.UUID, userID string, req dto.DeleteAccountRequest) *errors.AppError
DeleteUserAccount deletes the user account after verifying password
func (*Service) LogoutUser ¶
func (s *Service) LogoutUser(appID, userID, sessionID, refreshToken, accessToken string) *errors.AppError
LogoutUser logs out a user by revoking their session and blacklisting their access token
func (*Service) RefreshUserToken ¶
func (*Service) RegisterUser ¶
func (*Service) RequestMagicLink ¶
RequestMagicLink generates a magic link token and sends it via email. Returns nil even if the user is not found (to prevent email enumeration).
func (*Service) RequestPasswordReset ¶
func (*Service) ResendVerificationEmail ¶
ResendVerificationEmail resends the email verification link for a user. Returns nil even if the user is not found or already verified (to prevent email enumeration).
func (*Service) RevokeAllUserTokens ¶
RevokeAllUserTokens revokes all access and refresh tokens for a user This is used for security events like password changes, account compromise, etc.
func (*Service) SetInitialPassword ¶
func (s *Service) SetInitialPassword(appID uuid.UUID, userID string, newPassword string) *errors.AppError
SetInitialPassword sets a password for a social-only user (no existing PasswordHash). Returns ErrConflict if the user already has a password — callers should use UpdateUserPassword instead in that case.
func (*Service) UpdateUserEmail ¶
func (s *Service) UpdateUserEmail(appID uuid.UUID, userID string, req dto.UpdateEmailRequest) *errors.AppError
UpdateUserEmail updates the user's email address after verifying password
func (*Service) UpdateUserPassword ¶
func (s *Service) UpdateUserPassword(appID uuid.UUID, userID string, req dto.UpdatePasswordRequest) *errors.AppError
UpdateUserPassword updates the user's password after verifying current password
func (*Service) UpdateUserProfile ¶
UpdateUserProfile updates the user profile information (name, first_name, last_name, profile_picture, locale)
func (*Service) VerifyEmail ¶
func (*Service) VerifyMagicLink ¶
func (s *Service) VerifyMagicLink(appID uuid.UUID, token, ip, userAgent string) (*LoginResult, *errors.AppError)
VerifyMagicLink verifies a magic link token and creates a session (passwordless login). 2FA is skipped since the magic link itself serves as email-based verification.
type TrustedDeviceValidateFunc ¶
TrustedDeviceValidateFunc validates a plain trusted-device token and returns the associated userID and appID on success. It is called during Login to skip 2FA when a valid trusted-device cookie is present. Wired from main.go to avoid an import cycle.