You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
synctv/server/model/user.go

263 lines
6.2 KiB
Go

package model
import (
"errors"
"github.com/gin-gonic/gin"
json "github.com/json-iterator/go"
dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/provider"
)
var (
ErrEmptyUserID = errors.New("empty user id")
ErrEmptyUsername = errors.New("empty username")
ErrUsernameTooLong = errors.New("username too long")
ErrUsernameHasInvalidChar = errors.New("username has invalid char")
)
type SetUserPasswordReq struct {
Password string `json:"password"`
}
func (s *SetUserPasswordReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(s)
}
func (s *SetUserPasswordReq) Validate() error {
if s.Password == "" {
return FormatEmptyPasswordError("user")
} else if len(s.Password) > 32 {
return ErrPasswordTooLong
} else if !alnumPrintReg.MatchString(s.Password) {
return ErrPasswordHasInvalidChar
}
return nil
}
type LoginUserReq struct {
Username string `json:"username"`
Email string `json:"email"`
Password string `json:"password"`
}
func (l *LoginUserReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(l)
}
func (l *LoginUserReq) Validate() error {
if l.Username != "" && l.Email != "" {
return errors.New("only one of username or email should be provided")
}
if l.Username == "" && l.Email == "" {
return errors.New("either username or email is required")
}
if l.Username != "" {
if len(l.Username) > 32 {
return ErrUsernameTooLong
}
if !alnumPrintHanReg.MatchString(l.Username) {
return ErrUsernameHasInvalidChar
}
}
if l.Email != "" {
if !emailReg.MatchString(l.Email) {
return errors.New("invalid email format")
}
}
if l.Password == "" {
return FormatEmptyPasswordError("user")
} else if len(l.Password) > 32 {
return ErrPasswordTooLong
} else if !alnumPrintReg.MatchString(l.Password) {
return ErrPasswordHasInvalidChar
}
return nil
}
type UserSignupPasswordReq struct {
Username string `json:"username"`
Password string `json:"password"`
}
func (u *UserSignupPasswordReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(u)
}
func (u *UserSignupPasswordReq) Validate() error {
if u.Username == "" {
return errors.New("username is empty")
}
if len(u.Username) > 32 {
return ErrUsernameTooLong
}
if !alnumPrintHanReg.MatchString(u.Username) {
return ErrUsernameHasInvalidChar
}
if u.Password == "" {
return FormatEmptyPasswordError("user")
}
if len(u.Password) > 32 {
return ErrPasswordTooLong
}
if !alnumPrintReg.MatchString(u.Password) {
return ErrPasswordHasInvalidChar
}
return nil
}
type UserInfoResp struct {
ID string `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
CreatedAt int64 `json:"createdAt"`
Role dbModel.Role `json:"role"`
}
type SetUsernameReq struct {
Username string `json:"username"`
}
func (s *SetUsernameReq) Validate() error {
if s.Username == "" {
return errors.New("username is empty")
} else if len(s.Username) > 32 {
return ErrUsernameTooLong
} else if !alnumPrintHanReg.MatchString(s.Username) {
return ErrUsernameHasInvalidChar
}
return nil
}
func (s *SetUsernameReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(s)
}
type UserIDReq struct {
ID string `json:"id"`
}
func (u *UserIDReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(u)
}
func (u *UserIDReq) Validate() error {
if len(u.ID) != 32 {
return errors.New("id is required")
}
return nil
}
type UserBindProviderResp map[provider.OAuth2Provider]struct {
ProviderUserID string `json:"providerUserId"`
CreatedAt int64 `json:"createdAt"`
}
type GetUserBindEmailStep1CaptchaResp struct {
CaptchaID string `json:"captchaId"`
CaptchaBase64 string `json:"captchaBase64"`
}
type UserSendBindEmailCaptchaReq struct {
Email string `json:"email"`
CaptchaID string `json:"captchaId"`
Answer string `json:"answer"`
}
func (u *UserSendBindEmailCaptchaReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(u)
}
var (
ErrEmailTooLong = errors.New("email is too long")
ErrInvalidEmail = errors.New("invalid email")
)
func (u *UserSendBindEmailCaptchaReq) Validate() error {
if u.Email == "" {
return errors.New("email is empty")
} else if len(u.Email) > 128 {
return ErrEmailTooLong
} else if !emailReg.MatchString(u.Email) {
return ErrInvalidEmail
}
if u.CaptchaID == "" {
return errors.New("captcha id is empty")
}
if u.Answer == "" {
return errors.New("answer is empty")
}
return nil
}
type UserBindEmailReq struct {
Email string `json:"email"`
Captcha string `json:"captcha"`
}
func (u *UserBindEmailReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(u)
}
func (u *UserBindEmailReq) Validate() error {
if u.Email == "" {
return errors.New("email is empty")
} else if len(u.Email) > 128 {
return ErrEmailTooLong
} else if !emailReg.MatchString(u.Email) {
return ErrInvalidEmail
}
if u.Captcha == "" {
return errors.New("captcha is empty")
}
return nil
}
type SendUserSignupEmailCaptchaReq = UserSendBindEmailCaptchaReq
type UserSignupEmailReq struct {
UserBindEmailReq
Password string `json:"password"`
}
func (u *UserSignupEmailReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(u)
}
func (u *UserSignupEmailReq) Validate() error {
if err := u.UserBindEmailReq.Validate(); err != nil {
return err
}
if u.Password == "" {
return FormatEmptyPasswordError("user")
} else if len(u.Password) > 32 {
return ErrPasswordTooLong
} else if !alnumPrintReg.MatchString(u.Password) {
return ErrPasswordHasInvalidChar
}
return nil
}
type SendUserRetrievePasswordEmailCaptchaReq = UserSendBindEmailCaptchaReq
type UserRetrievePasswordEmailReq struct {
Email string `json:"email"`
Captcha string `json:"captcha"`
Password string `json:"password"`
}
func (u *UserRetrievePasswordEmailReq) Decode(ctx *gin.Context) error {
return json.NewDecoder(ctx.Request.Body).Decode(u)
}
func (u *UserRetrievePasswordEmailReq) Validate() error {
if u.Captcha == "" {
return errors.New("captcha is empty")
}
return nil
}