2026-06-26 08:37:04 +00:00
|
|
|
package auth
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2026-07-07 14:02:41 +00:00
|
|
|
"crypto/rand"
|
|
|
|
|
"fmt"
|
|
|
|
|
"math/big"
|
|
|
|
|
"time"
|
2026-06-26 08:37:04 +00:00
|
|
|
|
2026-07-07 14:02:41 +00:00
|
|
|
"haixun-backend/internal/library/clock"
|
|
|
|
|
"haixun-backend/internal/logic/authz"
|
2026-06-26 08:37:04 +00:00
|
|
|
memberusecase "haixun-backend/internal/model/member/domain/usecase"
|
|
|
|
|
"haixun-backend/internal/svc"
|
|
|
|
|
"haixun-backend/internal/types"
|
2026-07-07 14:02:41 +00:00
|
|
|
|
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
2026-06-26 08:37:04 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type RegisterLogic struct {
|
|
|
|
|
ctx context.Context
|
|
|
|
|
svcCtx *svc.ServiceContext
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic {
|
|
|
|
|
return &RegisterLogic{ctx: ctx, svcCtx: svcCtx}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (l *RegisterLogic) Register(req *types.AuthRegisterReq) (*types.AuthTokenData, error) {
|
2026-07-07 14:02:41 +00:00
|
|
|
if err := authz.RequireAdmin(l.ctx, l.svcCtx); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
member, token, err := l.svcCtx.Member.Register(l.ctx, memberusecase.RegisterRequest{
|
2026-06-26 08:37:04 +00:00
|
|
|
TenantID: req.TenantID,
|
|
|
|
|
Email: req.Email,
|
|
|
|
|
Password: req.Password,
|
|
|
|
|
DisplayName: req.DisplayName,
|
|
|
|
|
Language: req.Language,
|
|
|
|
|
})
|
2026-07-07 14:02:41 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
verifyCode, err := newVerifyCode()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
expiresAt := clock.NowUnixNano() + int64(15*time.Minute)
|
|
|
|
|
if err := l.svcCtx.Member.SetEmailVerificationCode(l.ctx, member.TenantID, member.UID, verifyCode, expiresAt); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if l.svcCtx.Mailer != nil {
|
|
|
|
|
body := fmt.Sprintf("你的巡樓 Console 驗證碼是:%s\n\n此驗證碼 15 分鐘內有效。", verifyCode)
|
|
|
|
|
if err := l.svcCtx.Mailer.Send(l.ctx, member.Email, "巡樓 Console 帳號驗證碼", body); err != nil {
|
|
|
|
|
logx.WithContext(l.ctx).Errorf("send verification email failed: uid=%s err=%v", member.UID, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return toAuthTokenData(token), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newVerifyCode() (string, error) {
|
|
|
|
|
n, err := rand.Int(rand.Reader, big.NewInt(1000000))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
return fmt.Sprintf("%06d", n.Int64()), nil
|
2026-06-26 08:37:04 +00:00
|
|
|
}
|