user

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 3, 2026 License: Apache-2.0, BSD-3-Clause, MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RoleUser      = "user"
	RoleAdmin     = "admin"
	RoleModerator = "moderator"
)

UserRole constants

View Source
const (
	// EmailTypeAccount is for security-related communications
	// Password reset, 2FA recovery, security alerts, login notifications
	EmailTypeAccount = "account"

	// EmailTypeNotification is for non-security communications
	// Newsletters, updates, marketing, general notifications
	EmailTypeNotification = "notification"
)

Email type constants for dual email system (per AI.md PART 31)

View Source
const (
	TokenTypeEmailVerify   = "email_verify"
	TokenTypePasswordReset = "password_reset"
)

Verification token types

View Source
const (
	EmailVerifyDuration   = 24 * time.Hour // 24 hours
	PasswordResetDuration = 1 * time.Hour  // 1 hour
)

Token durations

Variables

View Source
var (
	ErrEmailExists         = errors.New("email address already registered")
	ErrEmailNotFoundEM     = errors.New("email address not found")
	ErrEmailAlreadyPrimary = errors.New("email is already the primary address")
	ErrCannotRemovePrimary = errors.New("cannot remove primary email address")
	ErrVerificationExpired = errors.New("verification link has expired")
	ErrInvalidVerification = errors.New("invalid verification token")
	ErrMinimumOneEmail     = errors.New("user must have at least one email address")
)

Email errors

View Source
var (
	ErrPasskeyNotEnabled       = errors.New("passkeys are not enabled for this user")
	ErrPasskeyNotFound         = errors.New("passkey not found")
	ErrPasskeyAlreadyExists    = errors.New("passkey already registered")
	ErrPasskeyChallengeFailed  = errors.New("passkey challenge verification failed")
	ErrPasskeyChallengeExpired = errors.New("passkey challenge has expired")
	ErrPasskeyInvalidResponse  = errors.New("invalid passkey response")
	ErrPasskeySignCountInvalid = errors.New("passkey sign count invalid (possible cloned authenticator)")
)

Passkey errors

View Source
var (
	ErrNoRecoveryKeys      = errors.New("no recovery keys available")
	ErrInvalidRecoveryKey  = errors.New("invalid recovery key")
	ErrRecoveryKeyUsed     = errors.New("recovery key already used")
	ErrRecoveryKeyNotFound = errors.New("recovery key not found")
)

Recovery errors

View Source
var (
	ErrTokenNotFound  = errors.New("token not found")
	ErrTokenExpired   = errors.New("token expired")
	ErrTokenInvalid   = errors.New("invalid token")
	ErrTokenNameEmpty = errors.New("token name is required")
)

Token errors

View Source
var (
	ErrTOTPNotEnabled   = errors.New("2FA is not enabled for this user")
	ErrTOTPAlreadySetup = errors.New("2FA is already set up")
	ErrTOTPInvalidCode  = errors.New("invalid 2FA code")
	ErrTOTPNotVerified  = errors.New("2FA setup not verified")
	ErrEncryptionFailed = errors.New("encryption failed")
	ErrDecryptionFailed = errors.New("decryption failed")
)

2FA errors

View Source
var (
	ErrUsernameRequired     = errors.New("username is required")
	ErrUsernameTooShort     = errors.New("username must be at least 3 characters")
	ErrUsernameTooLong      = errors.New("username must be at most 32 characters")
	ErrUsernameInvalid      = errors.New("username can only contain lowercase letters, numbers, underscore, and hyphen")
	ErrUsernameReserved     = errors.New("this username is reserved")
	ErrEmailRequired        = errors.New("email is required")
	ErrEmailInvalid         = errors.New("invalid email address")
	ErrPasswordRequired     = errors.New("password is required")
	ErrPasswordTooShort     = errors.New("password must be at least 8 characters")
	ErrPasswordTooWeak      = errors.New("password must contain at least one uppercase letter, one lowercase letter, and one number")
	ErrPasswordWhitespace   = errors.New("password cannot start or end with whitespace")
	ErrUserNotFound         = errors.New("user not found")
	ErrInvalidCredentials   = errors.New("invalid username or password")
	ErrUserInactive         = errors.New("user account is inactive")
	ErrEmailNotVerified     = errors.New("email not verified")
	ErrUsernameTaken        = errors.New("username is already taken")
	ErrEmailTaken           = errors.New("email is already registered")
	ErrSessionExpired       = errors.New("session expired")
	ErrSessionNotFound      = errors.New("session not found")
	ErrRegistrationDisabled = errors.New("registration is currently disabled")
)

Validation errors

View Source
var (
	ErrVerificationTokenNotFound = errors.New("verification token not found")
	ErrVerificationTokenExpired  = errors.New("verification token expired")
	ErrVerificationTokenInvalid  = errors.New("invalid verification token")
)

Verification errors

View Source
var BlockedUsernames = map[string]bool{}/* 144 elements not displayed */

BlockedUsernames contains reserved usernames that cannot be registered Per AI.md specification - 100+ reserved words

View Source
var (
	ErrPreferencesNotFound = errors.New("preferences not found")
)

Preferences errors

Functions

func CheckPassword

func CheckPassword(password, encodedHash string) bool

CheckPassword compares a password with an Argon2id hash

func FormatRecoveryKey

func FormatRecoveryKey(key string) string

FormatRecoveryKey formats a recovery key for display

func GenerateSessionToken

func GenerateSessionToken() (string, error)

GenerateSessionToken generates a session token with ses_ prefix Per AI.md PART 23: Session token prefix must be "ses_"

func GenerateToken

func GenerateToken(length int) (string, error)

GenerateToken generates a secure random token

func HashPassword

func HashPassword(password string) (string, error)

HashPassword hashes a password using Argon2id (per AI.md - NEVER bcrypt)

func IsBlockedUsername

func IsBlockedUsername(username string) bool

IsBlockedUsername checks if a username is in the blocklist

func MaskEmail

func MaskEmail(email string) string

MaskEmail masks an email for display (j***n@e***.com format)

func NormalizeEmail

func NormalizeEmail(email string) string

NormalizeEmail normalizes an email (lowercase, trimmed)

func NormalizeUsername

func NormalizeUsername(username string) string

NormalizeUsername normalizes a username (lowercase, trimmed)

func SerializeOptions

func SerializeOptions(options interface{}) (string, error)

SerializeOptions serializes registration/authentication options to JSON

func ValidateEmail

func ValidateEmail(email string) error

ValidateEmail validates an email address

func ValidatePassword

func ValidatePassword(password string, minLength int) error

ValidatePassword validates a password Per AI.md: Passwords cannot start or end with whitespace

func ValidateUsername

func ValidateUsername(username string) error

ValidateUsername validates a username

Types

type AuthConfig

type AuthConfig struct {
	SessionDurationDays int
	CookieName          string
	CookieDomain        string
	CookieSecure        bool
}

AuthConfig contains authentication configuration

type AuthManager

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

AuthManager handles user authentication

func NewAuthManager

func NewAuthManager(db *sql.DB, config AuthConfig) *AuthManager

NewAuthManager creates a new authentication manager

func (*AuthManager) CleanupExpiredSessions

func (am *AuthManager) CleanupExpiredSessions(ctx context.Context) (int64, error)

CleanupExpiredSessions removes expired sessions

func (*AuthManager) ClearSessionCookie

func (am *AuthManager) ClearSessionCookie(w http.ResponseWriter)

ClearSessionCookie clears the session cookie

func (*AuthManager) GetSessionToken

func (am *AuthManager) GetSessionToken(r *http.Request) string

GetSessionToken extracts the session token from a request

func (*AuthManager) GetUserByEmail

func (am *AuthManager) GetUserByEmail(ctx context.Context, email string) (*User, error)

GetUserByEmail retrieves a user by email

func (*AuthManager) GetUserByID

func (am *AuthManager) GetUserByID(ctx context.Context, id int64) (*User, error)

GetUserByID retrieves a user by ID

func (*AuthManager) GetUserByUsername

func (am *AuthManager) GetUserByUsername(ctx context.Context, username string) (*User, error)

GetUserByUsername retrieves a user by username

func (*AuthManager) GetUserSessions

func (am *AuthManager) GetUserSessions(ctx context.Context, userID int64) ([]UserSession, error)

GetUserSessions retrieves all active sessions for a user

func (*AuthManager) Login

func (am *AuthManager) Login(ctx context.Context, usernameOrEmail, password, ipAddress, userAgent string) (*User, *UserSession, error)

Login authenticates a user and creates a session

func (*AuthManager) Logout

func (am *AuthManager) Logout(ctx context.Context, token string) error

Logout terminates a user session

func (*AuthManager) LogoutAll

func (am *AuthManager) LogoutAll(ctx context.Context, userID int64, exceptToken string) error

LogoutAll terminates all sessions for a user except the current one

func (*AuthManager) Register

func (am *AuthManager) Register(ctx context.Context, username, email, password string, minPasswordLength int) (*User, error)

Register creates a new user account

func (*AuthManager) RevokeSession

func (am *AuthManager) RevokeSession(ctx context.Context, userID, sessionID int64) error

RevokeSession revokes a specific session

func (*AuthManager) SetSessionCookie

func (am *AuthManager) SetSessionCookie(w http.ResponseWriter, token string)

SetSessionCookie sets the session cookie on the response

func (*AuthManager) SetUserActive

func (am *AuthManager) SetUserActive(ctx context.Context, userID int64, active bool) error

SetUserActive activates or deactivates a user

func (*AuthManager) SetUserRole

func (am *AuthManager) SetUserRole(ctx context.Context, userID int64, role string) error

SetUserRole sets a user's role

func (*AuthManager) UpdatePassword

func (am *AuthManager) UpdatePassword(ctx context.Context, userID int64, newPassword string, minPasswordLength int) error

UpdatePassword updates a user's password

func (*AuthManager) UpdateProfile

func (am *AuthManager) UpdateProfile(ctx context.Context, userID int64, displayName, bio, avatarURL string) error

UpdateProfile updates a user's profile

func (*AuthManager) ValidateSession

func (am *AuthManager) ValidateSession(ctx context.Context, token string) (*User, *UserSession, error)

ValidateSession validates a session token and returns the user

func (*AuthManager) VerifyEmail

func (am *AuthManager) VerifyEmail(ctx context.Context, userID int64) error

VerifyEmail marks a user's email as verified

type AuthenticationOptions

type AuthenticationOptions struct {
	Challenge        string                          `json:"challenge"`
	Timeout          int                             `json:"timeout"`
	RpId             string                          `json:"rpId"`
	AllowCredentials []PublicKeyCredentialDescriptor `json:"allowCredentials,omitempty"`
	UserVerification string                          `json:"userVerification"`
}

AuthenticationOptions represents WebAuthn authentication options

type AuthenticationResponse

type AuthenticationResponse struct {
	ID       string `json:"id"`
	RawID    string `json:"rawId"`
	Type     string `json:"type"`
	Response struct {
		AuthenticatorData string `json:"authenticatorData"`
		ClientDataJSON    string `json:"clientDataJSON"`
		Signature         string `json:"signature"`
		UserHandle        string `json:"userHandle,omitempty"`
	} `json:"response"`
}

AuthenticationResponse represents the client's authentication response

type AuthenticatorSelection

type AuthenticatorSelection struct {
	AuthenticatorAttachment string `json:"authenticatorAttachment,omitempty"`
	ResidentKey             string `json:"residentKey"`
	RequireResidentKey      bool   `json:"requireResidentKey"`
	UserVerification        string `json:"userVerification"`
}

AuthenticatorSelection represents authenticator selection criteria

type CreateTokenRequest

type CreateTokenRequest struct {
	Name        string
	Permissions []string
	ExpiresIn   time.Duration // 0 for no expiration
}

CreateTokenRequest represents a request to create a new token

type CreateTokenResponse

type CreateTokenResponse struct {
	Token  string     `json:"token"`
	ID     int64      `json:"id"`
	Name   string     `json:"name"`
	Prefix string     `json:"prefix"`
	Expiry *time.Time `json:"expiry,omitempty"`
}

CreateTokenResponse contains the newly created token (only returned once)

type EmailInfo

type EmailInfo struct {
	AccountEmail              string `json:"account_email"`
	AccountEmailVerified      bool   `json:"account_email_verified"`
	NotificationEmail         string `json:"notification_email,omitempty"`
	NotificationEmailVerified bool   `json:"notification_email_verified"`
	UsingSeparateNotification bool   `json:"using_separate_notification"`
}

EmailInfo provides information about user's email configuration

type EmailManager

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

EmailManager handles user email operations per AI.md PART 31 Account email: Security & account recovery (password reset, 2FA recovery, security alerts) Notification email: Non-security communications (newsletters, updates, general notifications)

func NewEmailManager

func NewEmailManager(db *sql.DB) *EmailManager

NewEmailManager creates a new email manager

func (*EmailManager) AddEmail

func (em *EmailManager) AddEmail(ctx context.Context, userID, email string) (*UserEmail, string, error)

AddEmail adds a new email address for a user

func (*EmailManager) ClearNotificationEmail

func (em *EmailManager) ClearNotificationEmail(ctx context.Context, userID string) error

ClearNotificationEmail removes the notification email designation

func (*EmailManager) GetAccountEmail

func (em *EmailManager) GetAccountEmail(ctx context.Context, userID string) (string, error)

GetAccountEmail returns the account (primary) email for a user

func (*EmailManager) GetEmailForType

func (em *EmailManager) GetEmailForType(ctx context.Context, userID string, emailType string) (string, error)

GetEmailForType returns the appropriate email for the given type

func (*EmailManager) GetEmails

func (em *EmailManager) GetEmails(ctx context.Context, userID string) ([]*UserEmail, error)

GetEmails returns all email addresses for a user

func (*EmailManager) GetNotificationEmail

func (em *EmailManager) GetNotificationEmail(ctx context.Context, userID string) (string, error)

GetNotificationEmail returns the notification email for a user Falls back to account email if no notification email is set

func (*EmailManager) RemoveEmail

func (em *EmailManager) RemoveEmail(ctx context.Context, userID, emailID string) error

RemoveEmail removes an email address

func (*EmailManager) ResendVerification

func (em *EmailManager) ResendVerification(ctx context.Context, emailID string) (string, error)

ResendVerification resends a verification email

func (*EmailManager) SetAsNotificationEmail

func (em *EmailManager) SetAsNotificationEmail(ctx context.Context, userID, emailID string) error

SetAsNotificationEmail sets an email as the notification email

func (*EmailManager) VerifyEmail

func (em *EmailManager) VerifyEmail(ctx context.Context, token string) (*UserEmail, error)

VerifyEmail verifies an email address using a token

type Passkey

type Passkey struct {
	ID              string     `json:"id" db:"id"`
	UserID          string     `json:"user_id" db:"user_id"`
	CredentialID    string     `json:"credential_id" db:"credential_id"`
	PublicKey       string     `json:"public_key" db:"public_key"`
	AttestationType string     `json:"attestation_type" db:"attestation_type"`
	Transport       string     `json:"transport" db:"transport"`
	AAGUID          string     `json:"aaguid" db:"aaguid"`
	SignCount       uint32     `json:"sign_count" db:"sign_count"`
	Name            string     `json:"name" db:"name"`
	CreatedAt       time.Time  `json:"created_at" db:"created_at"`
	LastUsedAt      *time.Time `json:"last_used_at,omitempty" db:"last_used_at"`
}

Passkey represents a stored WebAuthn credential

func (*Passkey) ToInfo

func (pk *Passkey) ToInfo() PasskeyInfo

ToInfo converts a Passkey to PasskeyInfo for safe display

type PasskeyChallenge

type PasskeyChallenge struct {
	ID        string    `json:"id" db:"id"`
	UserID    string    `json:"user_id" db:"user_id"`
	Challenge string    `json:"challenge" db:"challenge"`
	Type      string    `json:"type" db:"type"`
	ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

PasskeyChallenge represents an active WebAuthn challenge

type PasskeyInfo

type PasskeyInfo struct {
	ID         string     `json:"id"`
	Name       string     `json:"name"`
	CreatedAt  time.Time  `json:"created_at"`
	LastUsedAt *time.Time `json:"last_used_at,omitempty"`
}

PasskeyInfo represents passkey info for display (without sensitive data)

type PasskeyListResponse

type PasskeyListResponse struct {
	Passkeys []PasskeyInfo `json:"passkeys"`
	Count    int           `json:"count"`
}

PasskeyListResponse represents a list of passkeys for API response

type PasskeyManager

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

PasskeyManager handles WebAuthn/FIDO2 passkey operations per AI.md PART 31

func NewPasskeyManager

func NewPasskeyManager(db *sql.DB, rpID, rpOrigin, rpName string) *PasskeyManager

NewPasskeyManager creates a new passkey manager

func (*PasskeyManager) BeginAuthentication

func (pm *PasskeyManager) BeginAuthentication(ctx context.Context, userID *int64) (*AuthenticationOptions, error)

BeginAuthentication starts the passkey authentication process

func (*PasskeyManager) BeginRegistration

func (pm *PasskeyManager) BeginRegistration(ctx context.Context, user *User) (*RegistrationOptions, error)

BeginRegistration starts the passkey registration process

func (*PasskeyManager) CleanupExpiredChallenges

func (pm *PasskeyManager) CleanupExpiredChallenges(ctx context.Context) error

CleanupExpiredChallenges removes expired challenges

func (*PasskeyManager) DeletePasskey

func (pm *PasskeyManager) DeletePasskey(ctx context.Context, userID int64, passkeyID string) error

DeletePasskey removes a passkey

func (*PasskeyManager) FinishAuthentication

func (pm *PasskeyManager) FinishAuthentication(ctx context.Context, response *AuthenticationResponse) (*Passkey, error)

FinishAuthentication completes the passkey authentication

func (*PasskeyManager) FinishRegistration

func (pm *PasskeyManager) FinishRegistration(ctx context.Context, userID int64, response *RegistrationResponse, name string) (*Passkey, error)

FinishRegistration completes the passkey registration

func (*PasskeyManager) GetPasskey

func (pm *PasskeyManager) GetPasskey(ctx context.Context, userID int64, passkeyID string) (*Passkey, error)

GetPasskey returns a specific passkey by ID

func (*PasskeyManager) GetPasskeyCount

func (pm *PasskeyManager) GetPasskeyCount(ctx context.Context, userID int64) (int, error)

GetPasskeyCount returns the number of passkeys for a user

func (*PasskeyManager) GetPasskeys

func (pm *PasskeyManager) GetPasskeys(ctx context.Context, userID int64) ([]*Passkey, error)

GetPasskeys returns all passkeys for a user

func (*PasskeyManager) GetStatus

func (pm *PasskeyManager) GetStatus(ctx context.Context, userID int64) PasskeyStatus

GetStatus returns the passkey status for a user

func (*PasskeyManager) HasPasskeys

func (pm *PasskeyManager) HasPasskeys(ctx context.Context, userID int64) bool

HasPasskeys checks if a user has any passkeys registered

func (*PasskeyManager) ListPasskeysForDisplay

func (pm *PasskeyManager) ListPasskeysForDisplay(ctx context.Context, userID int64) (*PasskeyListResponse, error)

ListPasskeysForDisplay returns passkeys formatted for display

func (*PasskeyManager) RenamePasskey

func (pm *PasskeyManager) RenamePasskey(ctx context.Context, userID int64, passkeyID, name string) error

RenamePasskey updates a passkey's name

type PasskeyStatus

type PasskeyStatus struct {
	Enabled bool `json:"enabled"`
	Count   int  `json:"count"`
}

PasskeyStatus represents the passkey status for display

type PreferencesManager

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

PreferencesManager handles user search preferences

func NewPreferencesManager

func NewPreferencesManager(db *sql.DB) *PreferencesManager

NewPreferencesManager creates a new preferences manager

func (*PreferencesManager) ClearCookie

func (pm *PreferencesManager) ClearCookie(w http.ResponseWriter)

ClearCookie clears the preferences cookie

func (*PreferencesManager) GetForUser

func (pm *PreferencesManager) GetForUser(ctx context.Context, userID int64) (*UserPreferences, error)

GetForUser retrieves preferences for a logged-in user

func (*PreferencesManager) GetFromCookie

func (pm *PreferencesManager) GetFromCookie(r *http.Request) *UserPreferences

GetFromCookie retrieves preferences from a cookie (for anonymous users)

func (*PreferencesManager) SaveForUser

func (pm *PreferencesManager) SaveForUser(ctx context.Context, userID int64, prefs *UserPreferences) error

SaveForUser saves preferences for a logged-in user

func (*PreferencesManager) SetCookie

func (pm *PreferencesManager) SetCookie(w http.ResponseWriter, prefs *UserPreferences) error

SetCookie sets preferences in a cookie (for anonymous users)

type PublicKeyCredentialDescriptor

type PublicKeyCredentialDescriptor struct {
	Type       string   `json:"type"`
	ID         string   `json:"id"`
	Transports []string `json:"transports,omitempty"`
}

PublicKeyCredentialDescriptor describes a credential

type PublicKeyCredentialParam

type PublicKeyCredentialParam struct {
	Type string `json:"type"`
	Alg  int    `json:"alg"`
}

PublicKeyCredentialParam represents a supported algorithm

type PublicKeyCredentialUser

type PublicKeyCredentialUser struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	DisplayName string `json:"displayName"`
}

PublicKeyCredentialUser represents the user entity for WebAuthn

type PublicProfile

type PublicProfile struct {
	ID          int64     `json:"id"`
	Username    string    `json:"username"`
	DisplayName string    `json:"display_name,omitempty"`
	AvatarURL   string    `json:"avatar_url,omitempty"`
	Bio         string    `json:"bio,omitempty"`
	CreatedAt   time.Time `json:"created_at"`
}

PublicProfile returns a user's public profile data

type RecoveryKey

type RecoveryKey struct {
	ID        int64      `json:"id" db:"id"`
	UserID    int64      `json:"user_id" db:"user_id"`
	KeyHash   string     `json:"-" db:"key_hash"`
	Used      bool       `json:"used" db:"used"`
	CreatedAt time.Time  `json:"created_at" db:"created_at"`
	UsedAt    *time.Time `json:"used_at,omitempty" db:"used_at"`
}

RecoveryKey represents a recovery key record

type RecoveryKeyStats

type RecoveryKeyStats struct {
	Total     int `json:"total"`
	Used      int `json:"used"`
	Remaining int `json:"remaining"`
}

GetUsageStats returns recovery key usage statistics

type RecoveryManager

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

RecoveryManager handles recovery key generation and validation

func NewRecoveryManager

func NewRecoveryManager(db *sql.DB, keyCount int) *RecoveryManager

NewRecoveryManager creates a new recovery key manager

func (*RecoveryManager) Generate

func (rm *RecoveryManager) Generate(ctx context.Context, userID int64) ([]string, error)

Generate generates new recovery keys for a user This invalidates any existing recovery keys

func (*RecoveryManager) GetRemainingCount

func (rm *RecoveryManager) GetRemainingCount(ctx context.Context, userID int64) (int, error)

GetRemainingCount returns the number of unused recovery keys

func (*RecoveryManager) GetUsageStats

func (rm *RecoveryManager) GetUsageStats(ctx context.Context, userID int64) (*RecoveryKeyStats, error)

func (*RecoveryManager) HasRecoveryKeys

func (rm *RecoveryManager) HasRecoveryKeys(ctx context.Context, userID int64) bool

HasRecoveryKeys checks if a user has any unused recovery keys

func (*RecoveryManager) RevokeAll

func (rm *RecoveryManager) RevokeAll(ctx context.Context, userID int64) error

RevokeAll revokes all recovery keys for a user

func (*RecoveryManager) Validate

func (rm *RecoveryManager) Validate(ctx context.Context, userID int64, key string) error

Validate validates and consumes a recovery key

type RegistrationOptions

type RegistrationOptions struct {
	Challenge              string                          `json:"challenge"`
	RelyingParty           RelyingPartyEntity              `json:"rp"`
	User                   PublicKeyCredentialUser         `json:"user"`
	PubKeyCredParams       []PublicKeyCredentialParam      `json:"pubKeyCredParams"`
	Timeout                int                             `json:"timeout"`
	Attestation            string                          `json:"attestation"`
	AuthenticatorSelection AuthenticatorSelection          `json:"authenticatorSelection"`
	ExcludeCredentials     []PublicKeyCredentialDescriptor `json:"excludeCredentials,omitempty"`
}

RegistrationOptions represents WebAuthn registration options

type RegistrationResponse

type RegistrationResponse struct {
	ID       string `json:"id"`
	RawID    string `json:"rawId"`
	Type     string `json:"type"`
	Response struct {
		AttestationObject string `json:"attestationObject"`
		ClientDataJSON    string `json:"clientDataJSON"`
	} `json:"response"`
	AuthenticatorAttachment string `json:"authenticatorAttachment,omitempty"`
}

RegistrationResponse represents the client's registration response

type RelyingPartyEntity

type RelyingPartyEntity struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

RelyingPartyEntity represents the relying party for WebAuthn

type TOTPManager

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

TOTPManager handles two-factor authentication

func NewTOTPManager

func NewTOTPManager(db *sql.DB, issuer string, encryptionKey []byte) (*TOTPManager, error)

NewTOTPManager creates a new TOTP manager

func (*TOTPManager) Disable

func (tm *TOTPManager) Disable(ctx context.Context, userID int64) error

Disable disables 2FA for a user (requires password verification first)

func (*TOTPManager) GenerateBackupCodes

func (tm *TOTPManager) GenerateBackupCodes(count int) ([]string, error)

GenerateBackupCodes generates backup codes for 2FA recovery This is a simpler alternative to full recovery keys

func (*TOTPManager) Get2FA

func (tm *TOTPManager) Get2FA(ctx context.Context, userID int64) (*User2FA, error)

Get2FA retrieves the 2FA configuration for a user

func (*TOTPManager) GetStatus

func (tm *TOTPManager) GetStatus(ctx context.Context, userID int64) TOTPStatus

GetStatus returns the 2FA status for a user

func (*TOTPManager) Is2FAEnabled

func (tm *TOTPManager) Is2FAEnabled(ctx context.Context, userID int64) bool

Is2FAEnabled checks if 2FA is enabled for a user

func (*TOTPManager) Setup

func (tm *TOTPManager) Setup(ctx context.Context, user *User) (*TOTPSetupResponse, error)

Setup initiates 2FA setup for a user

func (*TOTPManager) Verify

func (tm *TOTPManager) Verify(ctx context.Context, userID int64, code string) error

Verify verifies a TOTP code for an enabled 2FA

func (*TOTPManager) VerifySetup

func (tm *TOTPManager) VerifySetup(ctx context.Context, userID int64, code string) error

VerifySetup verifies the initial 2FA setup with a code

type TOTPSetupResponse

type TOTPSetupResponse struct {
	Secret    string `json:"secret"`
	QRCodeURL string `json:"qr_code_url"`
	Issuer    string `json:"issuer"`
	Account   string `json:"account"`
}

TOTPSetupResponse contains data needed for 2FA setup

type TOTPStatus

type TOTPStatus struct {
	Enabled   bool       `json:"enabled"`
	Verified  bool       `json:"verified"`
	EnabledAt *time.Time `json:"enabled_at,omitempty"`
}

TOTPStatus represents the 2FA status for display

type TokenInfo

type TokenInfo struct {
	ID          int64      `json:"id"`
	Name        string     `json:"name"`
	Prefix      string     `json:"prefix"`
	Permissions []string   `json:"permissions,omitempty"`
	LastUsed    *time.Time `json:"last_used,omitempty"`
	ExpiresAt   *time.Time `json:"expires_at,omitempty"`
	CreatedAt   time.Time  `json:"created_at"`
	Expired     bool       `json:"expired"`
}

TokenInfo returns safe token info for display

type TokenManager

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

TokenManager handles user API token management

func NewTokenManager

func NewTokenManager(db *sql.DB) *TokenManager

NewTokenManager creates a new token manager

func (*TokenManager) CleanupExpired

func (tm *TokenManager) CleanupExpired(ctx context.Context) (int64, error)

CleanupExpired removes expired tokens

func (*TokenManager) Create

Create creates a new API token for a user

func (*TokenManager) List

func (tm *TokenManager) List(ctx context.Context, userID int64) ([]UserToken, error)

List lists all tokens for a user

func (*TokenManager) Revoke

func (tm *TokenManager) Revoke(ctx context.Context, userID, tokenID int64) error

Revoke revokes a specific token

func (*TokenManager) RevokeAll

func (tm *TokenManager) RevokeAll(ctx context.Context, userID int64) (int64, error)

RevokeAll revokes all tokens for a user

func (*TokenManager) Validate

func (tm *TokenManager) Validate(ctx context.Context, token string) (*User, *UserToken, error)

Validate validates a token and returns the associated user

type User

type User struct {
	ID            int64      `json:"id" db:"id"`
	Username      string     `json:"username" db:"username"`
	Email         string     `json:"email" db:"email"`
	PasswordHash  string     `json:"-" db:"password_hash"`
	DisplayName   string     `json:"display_name,omitempty" db:"display_name"`
	AvatarURL     string     `json:"avatar_url,omitempty" db:"avatar_url"`
	Bio           string     `json:"bio,omitempty" db:"bio"`
	Role          string     `json:"role" db:"role"`
	EmailVerified bool       `json:"email_verified" db:"email_verified"`
	Active        bool       `json:"active" db:"active"`
	CreatedAt     time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt     time.Time  `json:"updated_at" db:"updated_at"`
	LastLogin     *time.Time `json:"last_login,omitempty" db:"last_login"`

	// Notification email (per AI.md PART 31)
	// Optional separate email for non-security communications
	NotificationEmail         string `json:"notification_email,omitempty" db:"notification_email"`
	NotificationEmailVerified bool   `json:"notification_email_verified" db:"notification_email_verified"`
}

User represents a registered user Per AI.md PART 31: Account email vs Notification email - Email: Account email for security (password reset, 2FA, security alerts, login notifications) - NotificationEmail: Non-security communications (newsletters, updates, general notifications)

func NewUser

func NewUser(username, email, password string, minPasswordLength int) (*User, error)

NewUser creates a new user with validated and normalized fields

func (*User) CanLogin

func (u *User) CanLogin() bool

CanLogin checks if the user can log in

func (*User) ClearNotificationEmail

func (u *User) ClearNotificationEmail()

ClearNotificationEmail removes the separate notification email Notifications will fall back to the account email

func (*User) GetAccountEmail

func (u *User) GetAccountEmail() string

GetAccountEmail returns the user's account email (primary email for security) Per AI.md PART 31: Account email receives security-sensitive communications ONLY

func (*User) GetEmailForType

func (u *User) GetEmailForType(emailType string) string

GetEmailForType returns the appropriate email for the given email type Per AI.md PART 31: Account emails and notification emails have different purposes

func (*User) GetEmailInfo

func (u *User) GetEmailInfo() EmailInfo

GetEmailInfo returns detailed information about user's email configuration

func (*User) GetNotificationEmail

func (u *User) GetNotificationEmail() string

GetNotificationEmail returns the email to use for non-security notifications Per AI.md PART 31: If notification email is set and verified, use it Otherwise fall back to the account email

func (*User) HasSeparateNotificationEmail

func (u *User) HasSeparateNotificationEmail() bool

HasSeparateNotificationEmail checks if user has a verified separate notification email

func (*User) IsAdmin

func (u *User) IsAdmin() bool

IsAdmin checks if the user has admin role

func (*User) IsModerator

func (u *User) IsModerator() bool

IsModerator checks if the user has moderator role

func (*User) SetNotificationEmail

func (u *User) SetNotificationEmail(email string) error

SetNotificationEmail sets the notification email (requires verification before use)

func (*User) ToPublicProfile

func (u *User) ToPublicProfile() PublicProfile

ToPublicProfile converts a user to their public profile

func (*User) VerifyNotificationEmail

func (u *User) VerifyNotificationEmail()

VerifyNotificationEmail marks the notification email as verified

type User2FA

type User2FA struct {
	ID              int64      `json:"id" db:"id"`
	UserID          int64      `json:"user_id" db:"user_id"`
	SecretEncrypted string     `json:"-" db:"secret_encrypted"`
	Enabled         bool       `json:"enabled" db:"enabled"`
	Verified        bool       `json:"verified" db:"verified"`
	CreatedAt       time.Time  `json:"created_at" db:"created_at"`
	EnabledAt       *time.Time `json:"enabled_at,omitempty" db:"enabled_at"`
}

User2FA represents a user's 2FA configuration

type UserEmail

type UserEmail struct {
	ID                  string     `json:"id" db:"id"`
	UserID              string     `json:"user_id" db:"user_id"`
	Email               string     `json:"email" db:"email"`
	Verified            bool       `json:"verified" db:"verified"`
	IsPrimary           bool       `json:"is_primary" db:"is_primary"`
	IsNotification      bool       `json:"is_notification" db:"is_notification"`
	VerificationToken   string     `json:"-" db:"verification_token"`
	VerificationExpires *time.Time `json:"-" db:"verification_expires"`
	CreatedAt           time.Time  `json:"created_at" db:"created_at"`
	VerifiedAt          *time.Time `json:"verified_at,omitempty" db:"verified_at"`
}

UserEmail represents an email address associated with a user

func (*UserEmail) ToInfo

func (ue *UserEmail) ToInfo() UserEmailInfo

ToInfo converts UserEmail to UserEmailInfo for display

type UserEmailInfo

type UserEmailInfo struct {
	ID             string     `json:"id"`
	Email          string     `json:"email"`
	MaskedEmail    string     `json:"masked_email"`
	Verified       bool       `json:"verified"`
	IsPrimary      bool       `json:"is_primary"`
	IsNotification bool       `json:"is_notification"`
	CreatedAt      time.Time  `json:"created_at"`
	VerifiedAt     *time.Time `json:"verified_at,omitempty"`
}

UserEmailInfo represents user email info for display (different from User.EmailInfo)

type UserPreferences

type UserPreferences struct {
	// Display settings
	Theme          string `json:"theme"` // dark, light, auto
	ResultsPerPage int    `json:"results_per_page"`
	OpenInNewTab   bool   `json:"open_in_new_tab"`

	// Search defaults
	DefaultCategory string `json:"default_category"`
	DefaultLanguage string `json:"default_language"`
	DefaultRegion   string `json:"default_region"`
	SafeSearch      int    `json:"safe_search"`  // 0, 1, 2
	DefaultSort     string `json:"default_sort"` // relevance, date, popularity

	// Engine preferences
	EnabledEngines  []string `json:"enabled_engines,omitempty"`
	DisabledEngines []string `json:"disabled_engines,omitempty"`

	// UI preferences
	ShowThumbnails  bool `json:"show_thumbnails"`
	ShowEngineIcons bool `json:"show_engine_icons"`
	InfiniteScroll  bool `json:"infinite_scroll"`
	AutocompleteOn  bool `json:"autocomplete_on"`

	// Privacy
	SaveSearchHistory bool `json:"save_search_history"`
	AnonymizeResults  bool `json:"anonymize_results"` // Use proxy for images

	// Accessibility
	HighContrast bool `json:"high_contrast"`
	LargeFont    bool `json:"large_font"`
	ReduceMotion bool `json:"reduce_motion"`
}

UserPreferences represents user search preferences

func DefaultPreferences

func DefaultPreferences() *UserPreferences

DefaultPreferences returns default user preferences

func FromJSON

func FromJSON(data []byte) (*UserPreferences, error)

FromJSON parses preferences from JSON

func ParsePreferenceString

func ParsePreferenceString(s string) *UserPreferences

ParsePreferenceString decodes a preference string into UserPreferences

func (*UserPreferences) GetShareableURL

func (prefs *UserPreferences) GetShareableURL(baseURL string) string

GetShareableURL generates a shareable URL with the preference string

func (*UserPreferences) Merge

func (prefs *UserPreferences) Merge(updates *UserPreferences)

Merge merges new preferences with existing ones (only non-zero values)

func (*UserPreferences) ToJSON

func (prefs *UserPreferences) ToJSON() ([]byte, error)

ToJSON converts preferences to JSON

func (*UserPreferences) ToPreferenceString

func (prefs *UserPreferences) ToPreferenceString() string

ToPreferenceString encodes preferences to a compact URL-safe string

func (*UserPreferences) Validate

func (prefs *UserPreferences) Validate() error

Validate validates preference values

type UserSession

type UserSession struct {
	ID         int64     `json:"id" db:"id"`
	UserID     int64     `json:"user_id" db:"user_id"`
	Token      string    `json:"-" db:"token"`
	IPAddress  string    `json:"ip_address" db:"ip_address"`
	UserAgent  string    `json:"user_agent" db:"user_agent"`
	DeviceName string    `json:"device_name" db:"device_name"`
	CreatedAt  time.Time `json:"created_at" db:"created_at"`
	ExpiresAt  time.Time `json:"expires_at" db:"expires_at"`
	LastUsed   time.Time `json:"last_used" db:"last_used"`
}

UserSession represents an active user session

type UserToken

type UserToken struct {
	ID          int64      `json:"id" db:"id"`
	UserID      int64      `json:"user_id" db:"user_id"`
	Name        string     `json:"name" db:"name"`
	TokenHash   string     `json:"-" db:"token_hash"`
	TokenPrefix string     `json:"token_prefix" db:"token_prefix"`
	Permissions string     `json:"permissions,omitempty" db:"permissions"`
	LastUsed    *time.Time `json:"last_used,omitempty" db:"last_used"`
	ExpiresAt   *time.Time `json:"expires_at,omitempty" db:"expires_at"`
	CreatedAt   time.Time  `json:"created_at" db:"created_at"`
}

UserToken represents a user's API token

func (*UserToken) GetPermissions

func (ut *UserToken) GetPermissions() []string

GetPermissions parses the permissions string into a slice

func (*UserToken) HasPermission

func (ut *UserToken) HasPermission(permission string) bool

HasPermission checks if the token has a specific permission

func (*UserToken) IsExpired

func (ut *UserToken) IsExpired() bool

IsExpired checks if the token is expired

func (*UserToken) ToInfo

func (ut *UserToken) ToInfo() TokenInfo

ToInfo converts a token to safe display info

type VerificationManager

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

VerificationManager handles email verification and password reset tokens

func NewVerificationManager

func NewVerificationManager(db *sql.DB) *VerificationManager

NewVerificationManager creates a new verification manager

func (*VerificationManager) CleanupExpired

func (vm *VerificationManager) CleanupExpired(ctx context.Context) (int64, error)

CleanupExpired removes expired verification tokens

func (*VerificationManager) ConsumePasswordReset

func (vm *VerificationManager) ConsumePasswordReset(ctx context.Context, token string) (*User, error)

ConsumePasswordReset validates and consumes a password reset token

func (*VerificationManager) CreateEmailVerification

func (vm *VerificationManager) CreateEmailVerification(ctx context.Context, userID int64) (string, error)

CreateEmailVerification creates an email verification token

func (*VerificationManager) CreatePasswordReset

func (vm *VerificationManager) CreatePasswordReset(ctx context.Context, userID int64) (string, error)

CreatePasswordReset creates a password reset token

func (*VerificationManager) GetPendingVerification

func (vm *VerificationManager) GetPendingVerification(ctx context.Context, userID int64) (*VerificationToken, error)

GetPendingVerification checks if a user has a pending email verification

func (*VerificationManager) ValidatePasswordReset

func (vm *VerificationManager) ValidatePasswordReset(ctx context.Context, token string) (*User, error)

ValidatePasswordReset validates a password reset token and returns the user

func (*VerificationManager) VerifyEmail

func (vm *VerificationManager) VerifyEmail(ctx context.Context, token string) (*User, error)

VerifyEmail verifies an email verification token and marks the user's email as verified

type VerificationToken

type VerificationToken struct {
	ID        int64     `json:"id" db:"id"`
	UserID    int64     `json:"user_id" db:"user_id"`
	Token     string    `json:"token" db:"token"`
	Type      string    `json:"type" db:"type"`
	ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
}

VerificationToken represents a verification token

type WebAuthnAuthenticator

type WebAuthnAuthenticator struct {
	AAGUID       []byte
	SignCount    uint32
	CloneWarning bool
}

WebAuthnAuthenticator represents authenticator data

type WebAuthnCredential

type WebAuthnCredential struct {
	ID              []byte
	PublicKey       []byte
	AttestationType string
	Transport       []string
	Flags           WebAuthnCredentialFlags
	Authenticator   WebAuthnAuthenticator
}

WebAuthnCredential represents a WebAuthn credential for registration/authentication

type WebAuthnCredentialFlags

type WebAuthnCredentialFlags struct {
	UserPresent    bool
	UserVerified   bool
	BackupEligible bool
	BackupState    bool
}

WebAuthnCredentialFlags represents credential flags

type WebAuthnUser

type WebAuthnUser struct {
	ID          []byte
	Name        string
	DisplayName string
	Credentials []WebAuthnCredential
}

WebAuthnUser represents user data for WebAuthn operations

Jump to

Keyboard shortcuts

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