package models import ( "time" "github.com/google/uuid" ) // User represents a user with full authentication support type User struct { ID uuid.UUID `json:"id" db:"id"` ExternalID *string `json:"external_id,omitempty" db:"external_id"` Email string `json:"email" db:"email"` PasswordHash *string `json:"-" db:"password_hash"` // Never exposed in JSON Name *string `json:"name,omitempty" db:"name"` Role string `json:"role" db:"role"` // 'user', 'admin', 'super_admin', 'data_protection_officer' EmailVerified bool `json:"email_verified" db:"email_verified"` EmailVerifiedAt *time.Time `json:"email_verified_at,omitempty" db:"email_verified_at"` AccountStatus string `json:"account_status" db:"account_status"` // 'active', 'suspended', 'locked' LastLoginAt *time.Time `json:"last_login_at,omitempty" db:"last_login_at"` FailedLoginAttempts int `json:"failed_login_attempts" db:"failed_login_attempts"` LockedUntil *time.Time `json:"locked_until,omitempty" db:"locked_until"` CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` } // EmailVerificationToken for email verification type EmailVerificationToken struct { ID uuid.UUID `json:"id" db:"id"` UserID uuid.UUID `json:"user_id" db:"user_id"` Token string `json:"token" db:"token"` ExpiresAt time.Time `json:"expires_at" db:"expires_at"` UsedAt *time.Time `json:"used_at,omitempty" db:"used_at"` CreatedAt time.Time `json:"created_at" db:"created_at"` } // PasswordResetToken for password reset type PasswordResetToken struct { ID uuid.UUID `json:"id" db:"id"` UserID uuid.UUID `json:"user_id" db:"user_id"` Token string `json:"token" db:"token"` ExpiresAt time.Time `json:"expires_at" db:"expires_at"` UsedAt *time.Time `json:"used_at,omitempty" db:"used_at"` IPAddress *string `json:"ip_address,omitempty" db:"ip_address"` CreatedAt time.Time `json:"created_at" db:"created_at"` } // UserSession for session management type UserSession struct { ID uuid.UUID `json:"id" db:"id"` UserID uuid.UUID `json:"user_id" db:"user_id"` TokenHash string `json:"-" db:"token_hash"` DeviceInfo *string `json:"device_info,omitempty" db:"device_info"` IPAddress *string `json:"ip_address,omitempty" db:"ip_address"` UserAgent *string `json:"user_agent,omitempty" db:"user_agent"` ExpiresAt time.Time `json:"expires_at" db:"expires_at"` RevokedAt *time.Time `json:"revoked_at,omitempty" db:"revoked_at"` CreatedAt time.Time `json:"created_at" db:"created_at"` LastActivityAt time.Time `json:"last_activity_at" db:"last_activity_at"` } // RegisterRequest for user registration type RegisterRequest struct { Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required,min=8"` Name *string `json:"name"` } // LoginRequest for user login type LoginRequest struct { Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required"` } // LoginResponse after successful login type LoginResponse struct { User User `json:"user"` AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` ExpiresIn int `json:"expires_in"` // seconds } // RefreshTokenRequest for token refresh type RefreshTokenRequest struct { RefreshToken string `json:"refresh_token" binding:"required"` } // VerifyEmailRequest for email verification type VerifyEmailRequest struct { Token string `json:"token" binding:"required"` } // ForgotPasswordRequest for password reset request type ForgotPasswordRequest struct { Email string `json:"email" binding:"required,email"` } // ResetPasswordRequest for password reset type ResetPasswordRequest struct { Token string `json:"token" binding:"required"` NewPassword string `json:"new_password" binding:"required,min=8"` } // ChangePasswordRequest for changing password type ChangePasswordRequest struct { CurrentPassword string `json:"current_password" binding:"required"` NewPassword string `json:"new_password" binding:"required,min=8"` } // UpdateProfileRequest for profile updates type UpdateProfileRequest struct { Name *string `json:"name"` } // ======================================== // Two-Factor Authentication (2FA/TOTP) // ======================================== // UserTOTP stores 2FA TOTP configuration for a user type UserTOTP struct { ID uuid.UUID `json:"id" db:"id"` UserID uuid.UUID `json:"user_id" db:"user_id"` Secret string `json:"-" db:"secret"` // Encrypted TOTP secret Verified bool `json:"verified" db:"verified"` // Has 2FA been verified/activated RecoveryCodes []string `json:"-" db:"recovery_codes"` // Encrypted backup codes EnabledAt *time.Time `json:"enabled_at,omitempty" db:"enabled_at"` LastUsedAt *time.Time `json:"last_used_at,omitempty" db:"last_used_at"` CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` } // TwoFactorChallenge represents a pending 2FA challenge during login type TwoFactorChallenge struct { ID uuid.UUID `json:"id" db:"id"` UserID uuid.UUID `json:"user_id" db:"user_id"` ChallengeID string `json:"challenge_id" db:"challenge_id"` // Temporary token IPAddress *string `json:"ip_address,omitempty" db:"ip_address"` UserAgent *string `json:"user_agent,omitempty" db:"user_agent"` ExpiresAt time.Time `json:"expires_at" db:"expires_at"` UsedAt *time.Time `json:"used_at,omitempty" db:"used_at"` CreatedAt time.Time `json:"created_at" db:"created_at"` } // Setup2FAResponse when initiating 2FA setup type Setup2FAResponse struct { Secret string `json:"secret"` // Base32 encoded secret for manual entry QRCodeDataURL string `json:"qr_code"` // Data URL for QR code image RecoveryCodes []string `json:"recovery_codes"` // One-time backup codes } // Verify2FARequest for verifying 2FA setup or login type Verify2FARequest struct { Code string `json:"code" binding:"required"` // 6-digit TOTP code ChallengeID string `json:"challenge_id,omitempty"` // For login flow } // TwoFactorLoginResponse when 2FA is required during login type TwoFactorLoginResponse struct { RequiresTwoFactor bool `json:"requires_two_factor"` ChallengeID string `json:"challenge_id"` // Use this to complete 2FA Message string `json:"message"` } // Complete2FALoginRequest to complete login with 2FA type Complete2FALoginRequest struct { ChallengeID string `json:"challenge_id" binding:"required"` Code string `json:"code" binding:"required"` // 6-digit TOTP or recovery code } // Disable2FARequest for disabling 2FA type Disable2FARequest struct { Password string `json:"password" binding:"required"` // Require password confirmation Code string `json:"code" binding:"required"` // Current TOTP code } // RecoveryCodeUseRequest for using a recovery code type RecoveryCodeUseRequest struct { ChallengeID string `json:"challenge_id" binding:"required"` RecoveryCode string `json:"recovery_code" binding:"required"` } // TwoFactorStatusResponse for checking 2FA status type TwoFactorStatusResponse struct { Enabled bool `json:"enabled"` Verified bool `json:"verified"` EnabledAt *time.Time `json:"enabled_at,omitempty"` RecoveryCodesCount int `json:"recovery_codes_count"` } // Verify2FAChallengeRequest for verifying a 2FA challenge during login type Verify2FAChallengeRequest struct { ChallengeID string `json:"challenge_id" binding:"required"` Code string `json:"code,omitempty"` // 6-digit TOTP code RecoveryCode string `json:"recovery_code,omitempty"` // Alternative: recovery code }