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.
OneAuth/api/user/create.go

109 lines
2.7 KiB
Go

//
// create.go
// Copyright (C) 2025 veypi <i@veypi.com>
// 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"
6 months ago
"github.com/veypi/OneAuth/cfg"
"github.com/veypi/OneAuth/libs/utils"
6 months ago
"github.com/veypi/OneAuth/models"
"github.com/vyes/vigo"
"gorm.io/gorm"
)
var _ = Router.Post("/", vigo.SkipBefore, publicLimits, 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 *vigo.X) (any, error) {
opts := &postOpts{}
err := x.Parse(opts)
if err != nil {
return nil, err
}
6 months ago
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, vigo.ErrArgInvalid.WithArgs("username length")
}
code, err := base64.URLEncoding.DecodeString(opts.Code)
if err != nil || len(code) < 8 {
return nil, vigo.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, vigo.ErrArgInvalid.WithArgs("code")
}
ncode, err := utils.AesDecrypt([]byte(data.Code), code, []byte(data.Salt))
if err != nil || ncode != data.ID {
return nil, vigo.ErrInternalServer.WithString("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
}
6 months ago
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 vigo.ErrNotPermitted.WithArgs("not enable register")
case "apply":
status = "applying"
case "public":
}
if app.Typ != "public" {
}
6 months ago
return tx.Create(&models.AppUser{
UserID: data.ID,
AppID: cfg.Config.ID,
Status: status,
}).Error
})
return data, err
}