add checkout verify code

This commit is contained in:
daniel.w 2024-08-26 16:34:31 +08:00
parent ff1a4be702
commit 475d78b11c
5 changed files with 112 additions and 33 deletions

3
go.mod
View File

@ -4,13 +4,12 @@ go 1.22.3
require ( require (
code.30cm.net/digimon/library-go/errors v1.0.1 code.30cm.net/digimon/library-go/errors v1.0.1
code.30cm.net/digimon/proto-all v0.0.0-20240826070029-4a87e93fd2cf
github.com/gogo/protobuf v1.3.2 github.com/gogo/protobuf v1.3.2
github.com/matcornic/hermes/v2 v2.1.0 github.com/matcornic/hermes/v2 v2.1.0
github.com/zeromicro/go-zero v1.7.0 github.com/zeromicro/go-zero v1.7.0
) )
require code.30cm.net/digimon/proto-all v0.0.0-20240826014806-3899ef10d82f
require ( require (
github.com/Masterminds/semver v1.4.2 // indirect github.com/Masterminds/semver v1.4.2 // indirect
github.com/Masterminds/sprig v2.16.0+incompatible // indirect github.com/Masterminds/sprig v2.16.0+incompatible // indirect

View File

@ -16,3 +16,7 @@ func (g GrantType) ToString() string {
const ( const (
GrantTypeClientCredentials GrantType = "client_credentials" GrantTypeClientCredentials GrantType = "client_credentials"
) )
const (
SendVerifyCodeTypeForgetPassword = 3
)

View File

@ -1,10 +1,13 @@
package member package member
import ( import (
"context" "app-cloudep-portal-api-gateway/internal/domain"
"app-cloudep-portal-api-gateway/internal/svc" "app-cloudep-portal-api-gateway/internal/svc"
"app-cloudep-portal-api-gateway/internal/types" "app-cloudep-portal-api-gateway/internal/types"
ers "code.30cm.net/digimon/library-go/errors"
accountRpc "code.30cm.net/digimon/proto-all/pkg/member"
"context"
"fmt"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
@ -24,6 +27,23 @@ func NewCheckVerifyCodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *C
} }
func (l *CheckVerifyCodeLogic) CheckVerifyCode(req *types.CheckoutVerifyReq) (resp *types.BaseResponse, err error) { func (l *CheckVerifyCodeLogic) CheckVerifyCode(req *types.CheckoutVerifyReq) (resp *types.BaseResponse, err error) {
// 驗證碼
_, err = l.svcCtx.AccountRpc.CheckRefreshCode(l.ctx, &accountRpc.VerifyRefreshCodeReq{
Account: req.Account,
CodeType: domain.SendVerifyCodeTypeForgetPassword,
VerifyCode: req.VerifyCode,
})
if err != nil {
fmt.Println(err)
// 表使沒有這驗證碼
return nil, ers.Forbidden("failed to get verify code")
}
return // 返回成功響應
return &types.BaseResponse{
Status: types.Status{
Code: domain.SuccessCode,
Message: domain.SuccessMsg,
},
}, nil
} }

View File

@ -6,7 +6,6 @@ import (
"app-cloudep-portal-api-gateway/internal/types" "app-cloudep-portal-api-gateway/internal/types"
ers "code.30cm.net/digimon/library-go/errors" ers "code.30cm.net/digimon/library-go/errors"
accountRpc "code.30cm.net/digimon/proto-all/pkg/member" accountRpc "code.30cm.net/digimon/proto-all/pkg/member"
notificationRpc "code.30cm.net/digimon/proto-all/pkg/notification"
"context" "context"
"fmt" "fmt"
"github.com/matcornic/hermes/v2" "github.com/matcornic/hermes/v2"
@ -30,11 +29,7 @@ func NewForgetPasswordCodeLogic(ctx context.Context, svcCtx *svc.ServiceContext)
func (l *ForgetPasswordCodeLogic) ForgetPasswordCode(req *types.ForgetPasswordCodeReq) (*types.BaseResponse, error) { func (l *ForgetPasswordCodeLogic) ForgetPasswordCode(req *types.ForgetPasswordCodeReq) (*types.BaseResponse, error) {
// 限制三分鐘內只可以發送一次 // 限制三分鐘內只可以發送一次
accountType := req.AccountType rk := domain.GenerateVerifyCodeRedisKey.With(fmt.Sprintf("%s-%d", req.Account, domain.SendVerifyCodeTypeForgetPassword)).ToString()
// TODO 目前只可以給信箱驗證,其餘的自動轉換成信箱
accountType = 2
rk := domain.GenerateVerifyCodeRedisKey.With(fmt.Sprintf("%s-%d", req.Account, accountType)).ToString()
get, err := l.svcCtx.Redis.Get(rk) get, err := l.svcCtx.Redis.Get(rk)
if err != nil { if err != nil {
// Redis 錯誤,給予適當的提示(可以視情況返回錯誤或繼續) // Redis 錯誤,給予適當的提示(可以視情況返回錯誤或繼續)
@ -56,7 +51,7 @@ func (l *ForgetPasswordCodeLogic) ForgetPasswordCode(req *types.ForgetPasswordCo
// 生成重置密碼驗證碼 // 生成重置密碼驗證碼
code, err := l.svcCtx.AccountRpc.GenerateRefreshCode(l.ctx, &accountRpc.GenerateRefreshCodeReq{ code, err := l.svcCtx.AccountRpc.GenerateRefreshCode(l.ctx, &accountRpc.GenerateRefreshCodeReq{
Account: req.Account, Account: req.Account,
CodeType: accountType, CodeType: domain.SendVerifyCodeTypeForgetPassword,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -67,27 +62,28 @@ func (l *ForgetPasswordCodeLogic) ForgetPasswordCode(req *types.ForgetPasswordCo
if err != nil { if err != nil {
return nil, err return nil, err
} }
fmt.Println(info)
// 準備驗證碼郵件 // // 準備驗證碼郵件
nickName := info.Data.Uid // nickName := info.Data.Uid
if info.Data.NickName != nil { // if info.Data.NickName != nil {
nickName = *info.Data.NickName // nickName = *info.Data.NickName
} // }
mailContent, title, err := ForgerZHTW(nickName, code.Data.VerifyCode) // mailContent, title, err := ForgerZHTW(nickName, code.Data.VerifyCode)
if err != nil { // if err != nil {
return nil, ers.InvalidFormat("failed to generate mail content: ", err.Error()) // return nil, ers.InvalidFormat("failed to generate mail content: ", err.Error())
} // }
// 發送郵件 // // 發送郵件
_, err = l.svcCtx.NotificationRpc.SendMail(l.ctx, &notificationRpc.SendMailReq{ // _, err = l.svcCtx.NotificationRpc.SendMail(l.ctx, &notificationRpc.SendMailReq{
Body: mailContent, // Body: mailContent,
Subject: title, // Subject: title,
To: req.Account, // To: req.Account,
From: l.svcCtx.Config.MailSender, // From: l.svcCtx.Config.MailSender,
}) // })
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
// 設置 Redis 鍵,並設置 3 分鐘的過期時間 // 設置 Redis 鍵,並設置 3 分鐘的過期時間
err = l.svcCtx.Redis.Set(rk, code.Data.VerifyCode) err = l.svcCtx.Redis.Set(rk, code.Data.VerifyCode)

View File

@ -1,7 +1,12 @@
package member package member
import ( import (
"app-cloudep-portal-api-gateway/internal/domain"
ers "code.30cm.net/digimon/library-go/errors"
accountRpc "code.30cm.net/digimon/proto-all/pkg/member"
permissionRpc "code.30cm.net/digimon/proto-all/pkg/permission"
"context" "context"
"fmt"
"app-cloudep-portal-api-gateway/internal/svc" "app-cloudep-portal-api-gateway/internal/svc"
"app-cloudep-portal-api-gateway/internal/types" "app-cloudep-portal-api-gateway/internal/types"
@ -24,7 +29,62 @@ func NewUpadtePasswordLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Up
} }
func (l *UpadtePasswordLogic) UpadtePassword(req *types.UpdatePasswordReq) (resp *types.BaseResponse, err error) { func (l *UpadtePasswordLogic) UpadtePassword(req *types.UpdatePasswordReq) (resp *types.BaseResponse, err error) {
// todo: add your logic here and delete this line // 驗證密碼,兩次密碼要一致
if req.Token != req.TokenCheck {
return nil, ers.InvalidFormat("password confirmation does not match")
}
return // 驗證碼
_, err = l.svcCtx.AccountRpc.VerifyRefreshCode(l.ctx, &accountRpc.VerifyRefreshCodeReq{
Account: req.Account,
CodeType: domain.SendVerifyCodeTypeForgetPassword,
VerifyCode: req.VerifyCode,
})
if err != nil {
// 表使沒有這驗證碼
return nil, ers.Forbidden("failed to get verify code")
}
info, err := l.svcCtx.AccountRpc.GetUserAccountInfo(l.ctx, &accountRpc.GetUIDByAccountReq{Account: req.Account})
if err != nil {
return nil, err
}
if info.Data.Platform != domain.PlatformDigimon.ToInt64() {
return nil, ers.Forbidden("invalid platform")
}
// 更新
_, err = l.svcCtx.AccountRpc.UpdateUserToken(l.ctx, &accountRpc.UpdateTokenReq{
Account: req.Account,
Token: req.Token,
Platform: int64(domain.PlatformDigimon),
})
if err != nil {
return nil, err
}
// 刪除 key
rk := domain.GenerateVerifyCodeRedisKey.With(fmt.Sprintf("%s-%d", req.Account, domain.SendVerifyCodeTypeForgetPassword)).ToString()
_, err = l.svcCtx.Redis.Del(rk)
if err != nil {
return nil, ers.ArkInternal(err.Error())
}
// 取消所有Token
ac, err := l.svcCtx.AccountRpc.GetUidByAccount(l.ctx, &accountRpc.GetUIDByAccountReq{Account: req.Account})
if err != nil {
return nil, err
}
_, err = l.svcCtx.TokenRpc.CancelTokens(l.ctx, &permissionRpc.DoTokenByUIDReq{Uid: ac.Uid})
if err != nil {
return nil, err
}
// 返回成功響應
return &types.BaseResponse{
Status: types.Status{
Code: domain.SuccessCode,
Message: domain.SuccessMsg,
},
}, nil
} }