// // create.go // Copyright (C) 2025 veypi // 2025-05-06 15:05 // Distributed under terms of the MIT license. // package user import ( "encoding/base64" "fmt" "strings" "time" "math/rand" "github.com/google/uuid" "github.com/veypi/OneAuth/cfg" "github.com/veypi/OneAuth/models" "github.com/veypi/OneBD/rest" "github.com/veypi/utils" "gorm.io/gorm" ) var _ = Router.Post("/", userPost) type postOpts struct { Username string `json:"username" gorm:"varchar(100);unique;default:not null" parse:"json"` Code string `json:"code" gorm:"varchar(128)" parse:"json"` Nickname *string `json:"nickname" parse:"json"` Icon *string `json:"icon" parse:"json"` Email *string `json:"email" gorm:"varchar(20);unique;default:null" parse:"json"` Phone *string `json:"phone" gorm:"varchar(50);unique;default:null" parse:"json"` } func userPost(x *rest.X) (any, error) { opts := &postOpts{} err := x.Parse(opts) if err != nil { return nil, err } data := &models.User{} data.ID = strings.ReplaceAll(uuid.New().String(), "-", "") data.Username = opts.Username data.Code = opts.Code data.Salt = utils.RandSeq(16) if len(data.Username) < 2 { return nil, rest.ErrArgInvalid.WithArgs("username length") } code, err := base64.URLEncoding.DecodeString(opts.Code) if err != nil || len(code) < 8 { return nil, rest.ErrArgInvalid.WithArgs("code") } code = utils.PKCS7Padding(code, 32) data.Code, err = utils.AesEncrypt([]byte(data.ID), code, []byte(data.Salt)) if err != nil { return nil, rest.ErrArgInvalid.WithArgs("code") } ncode, err := utils.AesDecrypt([]byte(data.Code), code, []byte(data.Salt)) if err != nil || ncode != data.ID { return nil, rest.ErrInternalServer.AppendString("code decrypt failed") } if opts.Nickname != nil { data.Nickname = *opts.Nickname } if opts.Icon != nil { data.Icon = *opts.Icon } else { data.Icon = fmt.Sprintf("https://public.veypi.com/img/avatar/%04d.jpg", rand.New(rand.NewSource(time.Now().UnixNano())).Intn(220)) } if opts.Email != nil { data.Email = *opts.Email } if opts.Phone != nil { data.Phone = *opts.Phone } data.Status = 1 err = cfg.DB().Transaction(func(tx *gorm.DB) error { err := tx.Create(data).Error if err != nil { return err } app := &models.App{} err = tx.Where("id = ?", cfg.Config.ID).First(app).Error if err != nil { return err } status := "ok" switch app.Typ { case "private": return rest.ErrNotPermitted.WithArgs("not enable register") case "apply": status = "applying" case "public": } if app.Typ != "public" { } return tx.Create(&models.AppUser{ UserID: data.ID, AppID: cfg.Config.ID, Status: status, }).Error }) return data, err }