package models import ( "fmt" "time" "gorm.io/datatypes" ) type AuthFactorType = int8 const ( PasswordAuthFactor = AuthFactorType(iota) EmailPasswordFactor ) type AuthFactor struct { BaseModel Type int8 `json:"type"` Secret string `json:"-"` Config JSONMap `json:"config"` AccountID uint `json:"account_id"` } type AuthSession struct { BaseModel Claims datatypes.JSONSlice[string] `json:"claims"` Audiences datatypes.JSONSlice[string] `json:"audiences"` Challenge AuthChallenge `json:"challenge" gorm:"foreignKey:SessionID"` GrantToken string `json:"grant_token"` AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` ExpiredAt *time.Time `json:"expired_at"` AvailableAt *time.Time `json:"available_at"` LastGrantAt *time.Time `json:"last_grant_at"` ClientID *uint `json:"client_id"` AccountID uint `json:"account_id"` } func (v AuthSession) IsAvailable() error { if v.AvailableAt != nil && time.Now().Unix() < v.AvailableAt.Unix() { return fmt.Errorf("session isn't available yet") } if v.ExpiredAt != nil && time.Now().Unix() > v.ExpiredAt.Unix() { return fmt.Errorf("session expired") } return nil } type AuthChallengeState = int8 const ( ActiveChallengeState = AuthChallengeState(iota) ExpiredChallengeState FinishChallengeState ) type AuthChallenge struct { BaseModel Location string `json:"location"` IpAddress string `json:"ip_address"` UserAgent string `json:"user_agent"` RiskLevel int `json:"risk_level"` Progress int `json:"progress"` Requirements int `json:"requirements"` BlacklistFactors datatypes.JSONType[[]uint] `json:"blacklist_factors"` State int8 `json:"state"` ExpiredAt time.Time `json:"expired_at"` SessionID *uint `json:"session_id"` AccountID uint `json:"account_id"` } func (v AuthChallenge) IsAvailable() error { if time.Now().Unix() > v.ExpiredAt.Unix() { return fmt.Errorf("challenge expired") } return nil }