|
|
|
|
//
|
|
|
|
|
// login.go
|
|
|
|
|
// Copyright (C) 2025 veypi <i@veypi.com>
|
|
|
|
|
// 2025-05-12 17:35
|
|
|
|
|
// Distributed under terms of the MIT license.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
package user
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
|
|
|
"github.com/veypi/OneAuth/cfg"
|
|
|
|
|
"github.com/veypi/OneAuth/libs/auth"
|
|
|
|
|
"github.com/veypi/OneAuth/models"
|
|
|
|
|
"github.com/veypi/OneBD/rest"
|
|
|
|
|
"github.com/veypi/utils"
|
|
|
|
|
"github.com/veypi/utils/logv"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var _ = Router.Post("/login", userLogin)
|
|
|
|
|
|
|
|
|
|
type loginOpts struct {
|
|
|
|
|
UserName string `json:"username" parse:"json"`
|
|
|
|
|
Code string `json:"code" parse:"json"`
|
|
|
|
|
Phone *string `json:"phone" parse:"json"`
|
|
|
|
|
Email *string `json:"email" parse:"json"`
|
|
|
|
|
Type *string `json:"type" parse:"json"`
|
|
|
|
|
AppID *string `json:"app_id" parse:"json"`
|
|
|
|
|
Device *string `json:"device" parse:"json"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func userLogin(x *rest.X) (any, error) {
|
|
|
|
|
// Implement login logic here
|
|
|
|
|
// For example, validate user credentials and return a token
|
|
|
|
|
opts := &loginOpts{}
|
|
|
|
|
err := x.Parse(opts)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
user := &models.User{}
|
|
|
|
|
query := cfg.DB()
|
|
|
|
|
typ := ""
|
|
|
|
|
if opts.Type != nil {
|
|
|
|
|
typ = *opts.Type
|
|
|
|
|
}
|
|
|
|
|
switch typ {
|
|
|
|
|
case "phone":
|
|
|
|
|
query = query.Where("phone = ?", opts.Phone)
|
|
|
|
|
case "email":
|
|
|
|
|
query = query.Where("email = ?", opts.Email)
|
|
|
|
|
default:
|
|
|
|
|
query = query.Where("username = ?", opts.UserName)
|
|
|
|
|
}
|
|
|
|
|
err = query.First(user).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
logv.Info().Str("user", user.ID).Msg("login")
|
|
|
|
|
code, err := base64.URLEncoding.DecodeString(opts.Code)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, rest.ErrArgInvalid.WithArgs("code")
|
|
|
|
|
}
|
|
|
|
|
logv.Warn().Msgf("code: %s", code)
|
|
|
|
|
|
|
|
|
|
ncode, err := utils.AesDecrypt([]byte(user.Code), utils.PKCS7Padding(code, 32), []byte(user.Salt))
|
|
|
|
|
logv.Warn().Msgf("id: %s\n%s", ncode, user.ID)
|
|
|
|
|
if err != nil || string(ncode) != user.ID {
|
|
|
|
|
return nil, rest.ErrNotAuthorized
|
|
|
|
|
}
|
|
|
|
|
aid := cfg.Config.ID
|
|
|
|
|
if opts.AppID != nil && *opts.AppID != "" {
|
|
|
|
|
aid = *opts.AppID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data := &models.Token{}
|
|
|
|
|
|
|
|
|
|
data.UserID = user.ID
|
|
|
|
|
data.AppID = aid
|
|
|
|
|
data.ExpiredAt = time.Now().Add(time.Hour * 72)
|
|
|
|
|
if opts.Device != nil {
|
|
|
|
|
data.Device = *opts.Device
|
|
|
|
|
}
|
|
|
|
|
data.Ip = x.GetRemoteIp()
|
|
|
|
|
logv.AssertError(cfg.DB().Create(data).Error)
|
|
|
|
|
claim := &auth.Claims{}
|
|
|
|
|
claim.IssuedAt = jwt.NewNumericDate(time.Now())
|
|
|
|
|
claim.Issuer = cfg.Config.ID
|
|
|
|
|
claim.ID = data.ID
|
|
|
|
|
claim.AID = aid
|
|
|
|
|
claim.UID = user.ID
|
|
|
|
|
claim.Name = user.Username
|
|
|
|
|
claim.Icon = user.Icon
|
|
|
|
|
claim.ExpiresAt = jwt.NewNumericDate(data.ExpiredAt)
|
|
|
|
|
if user.Nickname != "" {
|
|
|
|
|
claim.Name = user.Nickname
|
|
|
|
|
}
|
|
|
|
|
return auth.GenJwt(claim)
|
|
|
|
|
}
|