package logic import ( "fmt" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/wevent" "net/http" "time" "context" "fusenapi/server/auth/internal/svc" "fusenapi/server/auth/internal/types" "github.com/474420502/requests" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/rest/httpx" "gorm.io/gorm" ) type UserEmailConfirmationLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewUserEmailConfirmationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserEmailConfirmationLogic { return &UserEmailConfirmationLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // 处理进入前逻辑w,r // func (l *UserEmailConfirmationLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { // } func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth.RegisterToken) error { // 创建签证 jwtToken, err := auth.GenerateJwtTokenUint64( auth.StringToHash(*user.PasswordHash), svcCtx.Config.Auth.AccessExpire, time.Now().UTC().Unix(), user.Id, 0, ) if err != nil { return err } event := wevent.NewWebsocketEventSuccess(wevent.UserEmailRegister, token.TraceId) event.Data = wevent.DataEmailRegister{ JwtToken: jwtToken, } err = CommonNotify(svcCtx.Config.WebsocketAddr, token.Wid, event) if err != nil { // logx.Error(err, token.TraceId) return err } return nil } func CommonNotify(WebsocketAddr, wid string, event *wevent.WebsocketEvent) error { reqWebsocketAddr := fmt.Sprintf("%s/api/websocket/common_notify", WebsocketAddr) tp := requests.Post(reqWebsocketAddr) tp.SetBodyJson(requests.M{ "wid": wid, "data": event, }) wresp, err := tp.Execute() if err != nil { // logx.Error(err, token.TraceId) return err } result := wresp.Json() if !result.Get("code").Exists() { return fmt.Errorf("send %s is error", reqWebsocketAddr) } if result.Get("code").Int() != 200 { return fmt.Errorf("%s", result.String()) } return nil } func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEmailConfirmation, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null switch auth.OperateType(req.OpType) { case auth.OpTypeRegister: token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.Token) if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeOAuthRegisterTokenErr) } if time.Since(token.CreateAt) > 30*time.Minute { return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "Verification links expire after 30 minute.") } logx.Error(token.Platform) switch token.Platform { case string(auth.PLATFORM_GOOGLE): // 谷歌平台的注册流程 user, err := l.svcCtx.AllModels.FsUser.RegisterByGoogleOAuth(l.ctx, token) if err != nil { logx.Error(err, token.TraceId) return resp.SetStatus(basic.CodeDbSqlErr, err.Error()) } err = FinishRegister(l.svcCtx, user, token) if err != nil { logx.Error(err) } logx.Info("success", token.TraceId) case string(auth.PLATFORM_FACEBOOK): case string(auth.PLATFORM_FUSEN): // log.Println("aaaa", token) user, err := l.svcCtx.AllModels.FsUser.RegisterByFusen(l.ctx, token) if err != nil && err != gorm.ErrRecordNotFound { logx.Error(err) return resp.SetStatusWithMessage(basic.CodeDbSqlErr, err.Error()) } err = FinishRegister(l.svcCtx, user, token) if err != nil { logx.Error(err) } logx.Info("success:", token.TraceId) } case auth.OpTypeResetToken: rt, err := l.svcCtx.ResetTokenManger.Decrypt(req.Token) // ResetToken if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeOAuthResetTokenDecryptErr, err.Error()) } if time.Since(rt.CreateAt) > 30*time.Minute { return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "Verification links expire after 30 minute.") } // TODO: 存储 if rt.OperateType != auth.OpTypeResetToken { return resp.SetStatus(basic.CodeOAuthTypeErr, "error OperateType: rt.OperateType != auth.OpTypeResetToken") } err = l.svcCtx.AllModels.FsUser.Transaction(l.ctx, func(tx *gorm.DB) error { user := &gmodel.FsUser{Id: int64(rt.UserId)} err := tx.Take(user).Error if err != nil { return err } if *user.PasswordHash != rt.OldPassword { return fmt.Errorf("password had been reset") } return tx.Update("PasswordHash", rt.NewPassword).Error }) if err != nil { return resp.SetStatus(basic.CodeDbSqlErr, err.Error()) } event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId) err = CommonNotify(l.svcCtx.Config.MainAddress, rt.Wid, event) if err != nil { logx.Error(err, rt.TraceId) return resp.SetStatus(basic.CodeResetPasswordErr, err.Error()) } return resp.SetStatus(basic.CodeOK) default: return resp.SetStatus(basic.CodeOAuthRegisterTokenErr) } return resp.SetStatus(basic.CodeOK) } // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 func (l *UserEmailConfirmationLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { if resp.Code == 200 { successHtml := ` Registration Successful

Congratulations! Your registration is successful.

Thank you for registering on our website. Your account has been activated.

You can now login using your email address and password to enjoy full services and features on our website.

Thanks again for your trust and support. If you have any questions, please feel free to contact us.

We wish you a pleasant experience!

` w.Write([]byte(successHtml)) httpx.Ok(w) } else { errorHtml := ` Failed to register

%s

` errorHtml = fmt.Sprintf(errorHtml, resp.Message) w.Write([]byte(errorHtml)) httpx.Ok(w) } }