🎉 Initial Commit

This commit is contained in:
2024-01-07 01:56:32 +08:00
commit 632d614d1e
29 changed files with 1240 additions and 0 deletions

39
pkg/models/accounts.go Normal file
View File

@ -0,0 +1,39 @@
package models
import "time"
type AccountState = int8
const (
PendingAccountState = AccountState(iota)
ActiveAccountState
)
type Account struct {
BaseModel
Name string `json:"name" gorm:"uniqueIndex"`
Nick string `json:"nick"`
State AccountState `json:"state"`
Session []AuthSession `json:"sessions"`
Challenges []AuthChallenge `json:"challenges"`
Factors []AuthFactor `json:"factors"`
Contacts []AccountContact `json:"contacts"`
}
type AccountContactType = int8
const (
EmailAccountContact = AccountContactType(iota)
)
type AccountContact struct {
BaseModel
Type int8 `json:"type"`
Content string `json:"content" gorm:"uniqueIndex"`
IsPublic bool `json:"is_public"`
IsPrimary bool `json:"is_primary"`
VerifiedAt *time.Time `json:"verified_at"`
AccountID uint `json:"account_id"`
}

79
pkg/models/auth.go Normal file
View File

@ -0,0 +1,79 @@
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:"secret"`
Config JSONMap `json:"config"`
AccountID uint `json:"account_id"`
}
type AuthSession struct {
BaseModel
Claims datatypes.JSONSlice[string] `json:"claims"`
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"`
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)
FinishChallengeState
)
type AuthChallenge struct {
BaseModel
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
}

17
pkg/models/base.go Normal file
View File

@ -0,0 +1,17 @@
package models
import (
"time"
"gorm.io/datatypes"
"gorm.io/gorm"
)
type JSONMap = datatypes.JSONType[map[string]any]
type BaseModel struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}