user.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package model
  2. import (
  3. "github.com/0xJacky/Nginx-UI/internal/crypto"
  4. "github.com/go-webauthn/webauthn/webauthn"
  5. "github.com/spf13/cast"
  6. "gorm.io/gorm"
  7. "gorm.io/gorm/schema"
  8. )
  9. func init() {
  10. schema.RegisterSerializer("json[aes]", crypto.JSONAesSerializer{})
  11. }
  12. type RecoveryCode struct {
  13. Code string `json:"code"`
  14. UsedTime *int64 `json:"used_time,omitempty" gorm:"type:datetime;default:null"`
  15. }
  16. type RecoveryCodes struct {
  17. Codes []*RecoveryCode `json:"codes"`
  18. LastViewed *int64 `json:"last_viewed,omitempty" gorm:"serializer:unixtime;type:datetime;default:null"`
  19. LastDownloaded *int64 `json:"last_downloaded,omitempty" gorm:"serializer:unixtime;type:datetime;default:null"`
  20. }
  21. type User struct {
  22. Model
  23. Name string `json:"name" cosy:"add:max=20;update:omitempty,max=20;list:fussy;db_unique"`
  24. Password string `json:"-" cosy:"json:password;add:required,max=20;update:omitempty,max=20"`
  25. Status bool `json:"status" gorm:"default:1"`
  26. OTPSecret []byte `json:"-" gorm:"type:blob"`
  27. RecoveryCodes RecoveryCodes `json:"-" gorm:"serializer:json[aes]"`
  28. EnabledTwoFA bool `json:"enabled_2fa" gorm:"-"`
  29. Language string `json:"language" gorm:"default:en"`
  30. }
  31. type AuthToken struct {
  32. UserID uint64 `json:"user_id"`
  33. Token string `json:"token"`
  34. ExpiredAt int64 `json:"expired_at" gorm:"default:0"`
  35. }
  36. func (u *User) TableName() string {
  37. return "users"
  38. }
  39. func (u *User) AfterFind(_ *gorm.DB) error {
  40. u.EnabledTwoFA = u.Enabled2FA()
  41. return nil
  42. }
  43. func (u *User) EnabledOTP() bool {
  44. return len(u.OTPSecret) != 0
  45. }
  46. func (u *User) RecoveryCodeGenerated() bool {
  47. return len(u.RecoveryCodes.Codes) > 0
  48. }
  49. func (u *User) RecoveryCodeViewed() bool {
  50. return u.RecoveryCodes.LastViewed != nil
  51. }
  52. func (u *User) EnabledPasskey() bool {
  53. var passkeys Passkey
  54. db.Where("user_id", u.ID).Limit(1).Find(&passkeys)
  55. return passkeys.ID != 0
  56. }
  57. func (u *User) Enabled2FA() bool {
  58. return u.EnabledOTP() || u.EnabledPasskey()
  59. }
  60. func (u *User) WebAuthnID() []byte {
  61. return []byte(cast.ToString(u.ID))
  62. }
  63. func (u *User) WebAuthnName() string {
  64. return u.Name
  65. }
  66. func (u *User) WebAuthnDisplayName() string {
  67. return u.Name
  68. }
  69. func (u *User) WebAuthnCredentials() (credentials []webauthn.Credential) {
  70. var passkeys []Passkey
  71. db.Where("user_id", u.ID).Find(&passkeys)
  72. for _, passkey := range passkeys {
  73. credentials = append(credentials, *passkey.Credential)
  74. }
  75. return
  76. }