package storage import ( "time" "github.com/go-webauthn/webauthn/webauthn" "github.com/google/uuid" "gorm.io/gorm" ) // Database representation of a user account // This can be a bot, remote or not // If remote, this is used for caching the account type User struct { ID string `gorm:"primarykey"` // ID is a uuid for this account Handle string // Handle is the full handle, eg @max@example.com CreatedAt time.Time // When this entry was created UpdatedAt time.Time // When this account was last updated. Will also be used for refreshing remote accounts // When this entry was deleted (for soft deletions) // Soft delete means that this entry still exists in the db, but gorm won't include it anymore unless specifically told to // If not null, this entry is marked as deleted DeletedAt gorm.DeletedAt `gorm:"index"` Remote bool // Whether the account is a local or remote one Server string // The url of the server this account is from DisplayName string // The display name of the user. Can be different from the handle CustomFields []uint `gorm:"serializer:json"` // IDs to the custom fields a user has Description string // The description of a user account Tags []string `gorm:"serializer:json"` // Hashtags IsBot bool // Whether to mark this account as a script controlled one Follows []string `gorm:"serializer:json"` // List of handles this account follows Followers []string `gorm:"serializer:json"` // List of handles that follow this account Icon string // ID of a media file used as icon Background string // ID of a media file used as background image Banner string // ID of a media file used as banner Indexable bool // Whether this account can be found by crawlers PublicKeyPem *string // The public key of the account // Whether this account restricts following // If true, the owner must approve of a follow request first RestrictedFollow bool // List of things the owner identifies as // Example [cat human robot] means that the owner probably identifies as // a cyborg-catgirl/boy/human IdentifiesAs []Being // List of pronouns the owner identifies with // An unordered list since the owner can freely set it // Examples: [she her], [it they its them] Gender []string // --- And internal account stuff --- // Still public fields since they wouldn't be able to be stored in the db otherwise PasswordHash []byte // Hash of the user's password TotpToken []byte // Token for totp verification // All the registered passkeys, name of passkey to credentials // Could this be exported to another table? Yes // Would it make sense? Probably not // Will just take the performance hit of json conversion // Access should be rare enough anyway Passkeys map[string]webauthn.Credential `gorm:"serializer:json"` PrivateKeyPem *string // The private key of the account. Nil if remote user } func NewEmptyUser() *User { return &User{ ID: uuid.NewString(), Handle: "placeholder", Remote: false, Server: "placeholder", DisplayName: "placeholder", CustomFields: []uint{}, Description: "placeholder", Tags: []string{}, IsBot: true, Follows: []string{}, Followers: []string{}, Icon: "placeholder", Background: "placeholder", Banner: "placeholder", Indexable: false, PublicKeyPem: nil, RestrictedFollow: false, IdentifiesAs: []Being{BEING_ROBOT}, Gender: []string{"it", "its"}, PasswordHash: []byte("placeholder"), TotpToken: []byte("placeholder"), Passkeys: map[string]webauthn.Credential{}, PrivateKeyPem: nil, } } func placeholderUser() *User { tmp := NewEmptyUser() tmp.ID = "placeholder" return tmp }