mirror of https://github.com/veypi/OneAuth.git
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.
109 lines
2.7 KiB
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"
|
|
"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
|
|
}
|