Files
RenewCMS/internal/domain/user/userDomain.go
T

87 lines
3.1 KiB
Go

package user
import (
"errors"
"strings"
"time"
)
var ErrUserNotFound = errors.New("user not found")
var ErrInvalidCredentials = errors.New("invalid credentials")
var ErrRegistrationClosed = errors.New("registration closed")
var ErrInvalidVerificationCode = errors.New("invalid verification code")
var ErrVerificationCodeExpired = errors.New("verification code expired")
var ErrAlreadyVerified = errors.New("user already verified")
var ErrInvalidPasswordResetCode = errors.New("invalid password reset code")
var ErrPasswordResetCodeExpired = errors.New("password reset code expired")
var ErrInvalidDisplayName = errors.New("invalid display name")
var ErrUsernameTaken = errors.New("username taken")
var ErrInvalidLookup = errors.New("invalid user lookup")
var ErrVerificationEmailNotSent = errors.New("verification email not sent")
var ErrPasswordTooLong = errors.New("password too long")
var ErrRoleChanged = errors.New("user role changed concurrently")
var ErrInvalidTransfer = errors.New("invalid ownership transfer")
var ErrConfirmationMismatch = errors.New("confirmation email does not match")
var ErrWrongPassword = errors.New("wrong password")
var ErrSameEmail = errors.New("new email is the current email")
var ErrNoPendingEmailChange = errors.New("no pending email change")
var ErrInvalidEmailChangeCode = errors.New("invalid email change code")
var ErrEmailUnavailable = errors.New("email unavailable")
const MaxLookupIDs = 100
const EmailChangeLifetime = 2 * time.Hour
const MaxPasswordBytes = 72
func ValidatePassword(password string) error {
if len(password) > MaxPasswordBytes {
return ErrPasswordTooLong
}
return nil
}
type User struct {
ID uint32 `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
PasswordResetCode string `json:"password_reset_code"`
Email string `json:"email"`
DisplayName string `json:"display_name"`
IsVerified bool `json:"is_verified"`
RoleID uint32 `json:"role_id"`
RoleAssignedByID uint32 `json:"role_assigned_by_id"`
VerificationCode string `json:"verification_code"`
VerificationExpiration time.Time `json:"verification_expiration"`
PasswordResetExpiration time.Time `json:"password_reset_expiration"`
PendingEmail string `json:"pending_email"`
EmailChangeCode string `json:"email_change_code"`
EmailChangeExpiration time.Time `json:"email_change_expiration"`
TokenVersion uint32 `json:"token_version"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
const UnverifiedRetention = 7 * 24 * time.Hour
func (u User) IsStaleUnverifiedAt(now time.Time) bool {
if u.IsVerified {
return false
}
deadline := u.VerificationExpiration
if deadline.IsZero() {
deadline = u.CreatedAt
}
if deadline.IsZero() {
return false
}
return now.After(deadline.Add(UnverifiedRetention))
}
func (u User) NameOrUsername() string {
if trimmed := strings.TrimSpace(u.DisplayName); trimmed != "" {
return trimmed
}
return u.Username
}