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/login.go

102 lines
2.5 KiB
Go

//
// 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"
6 months ago
"github.com/veypi/OneAuth/cfg"
"github.com/veypi/OneAuth/libs/auth"
"github.com/veypi/OneAuth/libs/utils"
6 months ago
"github.com/veypi/OneAuth/models"
"github.com/vyes/vigo"
"github.com/vyes/vigo/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 *vigo.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, vigo.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, vigo.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)
}