feat(auth): 用户账户 - 完善个人资料与登录日志 (#752)
Co-authored-by: wuligao <1247662379@qq.com>
This commit is contained in:
@@ -10,6 +10,9 @@ type User struct {
|
||||
EmailVerifiedAt *time.Time `json:"emailVerifiedAt,omitempty"`
|
||||
PhoneVerifiedAt *time.Time `json:"phoneVerifiedAt,omitempty"`
|
||||
DisplayName string `json:"displayName" gorm:"size:80"`
|
||||
AvatarMode string `json:"avatarMode" gorm:"size:16"`
|
||||
AvatarPreset string `json:"avatarPreset,omitempty" gorm:"size:16"`
|
||||
AvatarVersion string `json:"-" gorm:"size:36"`
|
||||
Role UserRole `json:"role" gorm:"index;size:24"`
|
||||
Status UserStatus `json:"status" gorm:"index;size:24"`
|
||||
PasswordHash string `json:"-"`
|
||||
@@ -19,12 +22,13 @@ type User struct {
|
||||
}
|
||||
|
||||
type AuthSession struct {
|
||||
ID string `json:"id" gorm:"primaryKey;size:36"`
|
||||
UserID string `json:"userId" gorm:"index;size:36"`
|
||||
TokenHash string `json:"-"`
|
||||
ExpiresAt time.Time `json:"expiresAt" gorm:"index"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReauthenticatedAt *time.Time `json:"-"`
|
||||
ID string `json:"id" gorm:"primaryKey;size:36"`
|
||||
UserID string `json:"userId" gorm:"index;size:36"`
|
||||
TokenHash string `json:"-"`
|
||||
ExpiresAt time.Time `json:"expiresAt" gorm:"index"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type UserIdentity struct {
|
||||
@@ -39,15 +43,17 @@ type UserIdentity struct {
|
||||
}
|
||||
|
||||
type OAuthState struct {
|
||||
ID string `json:"id" gorm:"primaryKey;size:36"`
|
||||
Provider string `json:"provider" gorm:"index;size:32"`
|
||||
StateHash string `json:"-" gorm:"uniqueIndex;size:64"`
|
||||
CodeVerifier string `json:"-" gorm:"size:160"`
|
||||
NextPath string `json:"nextPath"`
|
||||
AcceptedTerms bool `json:"acceptedTerms" gorm:"not null;default:false"`
|
||||
ExpiresAt time.Time `json:"expiresAt" gorm:"index"`
|
||||
UsedAt *time.Time `json:"usedAt" gorm:"index"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
ReauthUserID string `json:"-" gorm:"size:36"`
|
||||
ReauthSessionID string `json:"-" gorm:"size:36"`
|
||||
ID string `json:"id" gorm:"primaryKey;size:36"`
|
||||
Provider string `json:"provider" gorm:"index;size:32"`
|
||||
StateHash string `json:"-" gorm:"uniqueIndex;size:64"`
|
||||
CodeVerifier string `json:"-" gorm:"size:160"`
|
||||
NextPath string `json:"nextPath"`
|
||||
AcceptedTerms bool `json:"acceptedTerms" gorm:"not null;default:false"`
|
||||
ExpiresAt time.Time `json:"expiresAt" gorm:"index"`
|
||||
UsedAt *time.Time `json:"usedAt" gorm:"index"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
type EmailVerificationCode struct {
|
||||
|
||||
22
backend/internal/model/models_login_log.go
Normal file
22
backend/internal/model/models_login_log.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// LoginLog 保存事件时的用户快照,不随账号改名或会话清理改写历史。
|
||||
type LoginLog struct {
|
||||
ID string `json:"id" gorm:"primaryKey;size:36"`
|
||||
UserID *string `json:"userId" gorm:"index;size:36"`
|
||||
Username string `json:"username" gorm:"size:80"`
|
||||
DisplayName string `json:"displayName" gorm:"size:80"`
|
||||
Account string `json:"account" gorm:"size:160"`
|
||||
Event string `json:"event" gorm:"index;size:16"`
|
||||
Method string `json:"method" gorm:"index;size:24"`
|
||||
Source string `json:"source" gorm:"size:24"`
|
||||
Result string `json:"result" gorm:"index;size:16"`
|
||||
IP string `json:"ip" gorm:"index;size:64"`
|
||||
UserAgent string `json:"userAgent" gorm:"size:512"`
|
||||
SessionRef string `json:"sessionRef" gorm:"index;size:64"`
|
||||
Reason string `json:"reason" gorm:"size:64"`
|
||||
Message string `json:"message" gorm:"size:500"`
|
||||
CreatedAt time.Time `json:"createdAt" gorm:"index"`
|
||||
}
|
||||
@@ -43,21 +43,23 @@ type SMSRecord struct {
|
||||
// Verification tickets are immutable, short-lived and purpose/target bound.
|
||||
// Only code HMACs and the hash of the high-entropy client ticket are persisted.
|
||||
type AuthVerification struct {
|
||||
ID string `gorm:"primaryKey;size:36"`
|
||||
TokenHash string `gorm:"size:64"`
|
||||
Purpose string `gorm:"size:24"`
|
||||
Method string `gorm:"size:24"`
|
||||
UserID string `gorm:"size:36"`
|
||||
Email string `gorm:"size:160"`
|
||||
Phone string `gorm:"size:24"`
|
||||
EmailHash string `gorm:"size:64"`
|
||||
PhoneHash string `gorm:"size:64"`
|
||||
PolicyHash string `gorm:"size:64"`
|
||||
Ready bool
|
||||
Attempts int
|
||||
ExpiresAt time.Time `gorm:"index"`
|
||||
UsedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
SessionID string `json:"-" gorm:"size:36"`
|
||||
CredentialHash string `json:"-" gorm:"size:64"`
|
||||
ID string `gorm:"primaryKey;size:36"`
|
||||
TokenHash string `gorm:"size:64"`
|
||||
Purpose string `gorm:"size:24"`
|
||||
Method string `gorm:"size:24"`
|
||||
UserID string `gorm:"size:36"`
|
||||
Email string `gorm:"size:160"`
|
||||
Phone string `gorm:"size:24"`
|
||||
EmailHash string `gorm:"size:64"`
|
||||
PhoneHash string `gorm:"size:64"`
|
||||
PolicyHash string `gorm:"size:64"`
|
||||
Ready bool
|
||||
Attempts int
|
||||
ExpiresAt time.Time `gorm:"index"`
|
||||
UsedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// Fixed window quotas and per-recipient cooldowns are shared by all instances.
|
||||
|
||||
10
backend/internal/model/models_user_avatar.go
Normal file
10
backend/internal/model/models_user_avatar.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// UserAvatar keeps the bounded image payload out of ordinary user queries.
|
||||
type UserAvatar struct {
|
||||
UserID string `gorm:"primaryKey;size:36" json:"userId"`
|
||||
Data []byte `gorm:"not null" json:"-"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
Reference in New Issue
Block a user