// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn . package account import ( "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeUser/internal/configloaders" teaconst "github.com/TeaOSLab/EdgeUser/internal/const" "github.com/TeaOSLab/EdgeUser/internal/web/actions/actionutils" "github.com/iwind/TeaGo/actions" "regexp" "strings" ) type ResetAction struct { actionutils.ParentAction } func (this *ResetAction) Init() { this.Nav("", "", "") } func (this *ResetAction) RunGet(params struct{}) { // 界面 config, err := configloaders.LoadUIConfig() if err != nil { this.ErrorPage(err) return } this.Data["systemName"] = config.UserSystemName this.Data["showVersion"] = config.ShowVersion if len(config.Version) > 0 { this.Data["version"] = config.Version } else { this.Data["version"] = teaconst.Version } this.Data["faviconFileId"] = config.FaviconFileId // 密码强度 registerConfig, err := configloaders.LoadRegisterConfig() if err != nil { this.Fail("暂未开放注册功能") } this.Data["complexPassword"] = registerConfig.ComplexPassword this.Show() } func (this *ResetAction) RunPost(params struct { Action string UsernameOrEmail string Code string NewPass string NewPass2 string Must *actions.Must CSRF *actionutils.CSRF }) { // 检查用户名或邮箱是否存在 if len(params.UsernameOrEmail) == 0 { this.FailField("usernameOrEmail", "请输入用户名或已经绑定的邮箱") return } var email string if strings.Contains(params.UsernameOrEmail, "@") { // 邮箱 checkResp, err := this.RPC().UserRPC().CheckUserEmail(this.UserContext(), &pb.CheckUserEmailRequest{Email: params.UsernameOrEmail}) if err != nil { this.ErrorPage(err) return } if !checkResp.Exists { this.FailField("usernameOrEmail", "找不到和此邮箱绑定的用户") return } email = params.UsernameOrEmail } else { // 用户名 checkResp, err := this.RPC().UserRPC().CheckUserUsername(this.UserContext(), &pb.CheckUserUsernameRequest{ UserId: 0, Username: params.UsernameOrEmail, }) if err != nil { this.ErrorPage(err) return } if !checkResp.Exists { this.FailField("usernameOrEmail", "此用户名尚未注册") return } // 检查是否已绑定邮箱 emailResp, err := this.RPC().UserRPC().FindUserVerifiedEmailWithUsername(this.UserContext(), &pb.FindUserVerifiedEmailWithUsernameRequest{Username: params.UsernameOrEmail}) if err != nil { this.ErrorPage(err) return } if len(emailResp.Email) == 0 { this.FailField("usernameOrEmail", "此用户尚未绑定邮箱,不能通过邮箱找回密码") return } email = emailResp.Email } // 发送验证码 if params.Action == "send" { _, err := this.RPC().UserVerifyCodeRPC().SendUserVerifyCode(this.UserContext(), &pb.SendUserVerifyCodeRequest{ Type: "resetPassword", Email: email, Mobile: "", // TODO 将来实现通过手机号找回 }) if err != nil { this.ErrorPage(err) return } this.Data["email"] = email } // 修改密码 if params.Action == "update" { // 密码 params.Must. Field("newPass", params.NewPass). Require("请输入新登录密码"). MinLength(6, "登录密码长度不能小于6位") registerConfig, err := configloaders.LoadRegisterConfig() if err == nil { if registerConfig.ComplexPassword && (!regexp.MustCompile(`[a-z]`).MatchString(params.NewPass) || !regexp.MustCompile(`[A-Z]`).MatchString(params.NewPass)) { this.FailField("newPass", "为了您的账号安全,密码中必须包含大写和小写字母") return } } if params.NewPass != params.NewPass2 { this.FailField("newPass2", "两次输入的密码不一致") return } // 校验验证码 validateResp, err := this.RPC().UserVerifyCodeRPC().ValidateUserVerifyCode(this.UserContext(), &pb.ValidateUserVerifyCodeRequest{ Type: "resetPassword", Email: email, Mobile: "", // TODO 将来实现 Code: params.Code, NewPassword: params.NewPass, }) if err != nil { this.ErrorPage(err) return } if !validateResp.IsOk { this.Fail("验证失败:" + validateResp.ErrorMessage) return } } this.Success() }