:building:设置二步验证
This commit is contained in:
@@ -16,9 +16,11 @@ import (
|
||||
"github.com/dchest/captcha"
|
||||
"merchant/config"
|
||||
"merchant/models/merchant"
|
||||
"merchant/models/user"
|
||||
"merchant/sys"
|
||||
"merchant/sys/enum"
|
||||
"merchant/utils"
|
||||
"merchant/utils/mfa"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@@ -33,9 +35,11 @@ type Login struct {
|
||||
func (c *Login) UserLogin() {
|
||||
captchaCode := c.GetString("captchaCode")
|
||||
captchaId := c.GetString("captchaId")
|
||||
totpCode := c.GetString("totpCode")
|
||||
userName := strings.TrimSpace(c.GetString("userName"))
|
||||
password := c.GetString("Password")
|
||||
|
||||
otpSecret := true
|
||||
userList := user.GetAllUser()
|
||||
var (
|
||||
flag = enum.FailedFlag
|
||||
msg = ""
|
||||
@@ -48,46 +52,50 @@ func (c *Login) UserLogin() {
|
||||
verify bool
|
||||
u merchant.MerchantInfo
|
||||
)
|
||||
|
||||
us := c.GetSession(enum.UserSession)
|
||||
if us != nil {
|
||||
url = enum.DoMainUrl
|
||||
flag = enum.SuccessFlag
|
||||
goto stopRun
|
||||
}
|
||||
|
||||
if userName == "" || password == "" {
|
||||
msg = "登录账号或密码不能为空!"
|
||||
goto stopRun
|
||||
}
|
||||
|
||||
verify = captcha.VerifyString(captchaId, captchaCode)
|
||||
if !verify {
|
||||
url = strconv.Itoa(enum.FailedFlag)
|
||||
msg = "验证码不正确!"
|
||||
goto stopRun
|
||||
}
|
||||
|
||||
u = merchant.GetMerchantByPhone(userName)
|
||||
if u.LoginPassword == "" {
|
||||
msg = "账户信息错误,请联系管理人员!"
|
||||
goto stopRun
|
||||
}
|
||||
|
||||
if u.OtpSecret != "" && !mfa.ValidCode(totpCode, u.OtpSecret) {
|
||||
msg = "二步验证错误!"
|
||||
otpSecret = false
|
||||
}
|
||||
for _, userInfo := range userList {
|
||||
if userInfo.OtpSecret != "" && mfa.ValidCode(totpCode, userInfo.OtpSecret) {
|
||||
otpSecret = true
|
||||
}
|
||||
}
|
||||
if !otpSecret {
|
||||
goto stopRun
|
||||
}
|
||||
if strings.Compare(enum.ACTIVE, u.Status) != 0 {
|
||||
msg = "登录账号或密码错误!"
|
||||
goto stopRun
|
||||
}
|
||||
|
||||
//验证密码
|
||||
pwdMd5 = encrypt.EncodeMd5([]byte(password))
|
||||
if strings.Compare(strings.ToUpper(pwdMd5), u.LoginPassword) != 0 {
|
||||
msg = "登录账号或密码错误!"
|
||||
goto stopRun
|
||||
}
|
||||
|
||||
c.SetSession(enum.UserSession, u)
|
||||
|
||||
// 设置客户端用户信息有效保存时间
|
||||
ran = pubMethod.RandomString(46)
|
||||
ranMd5 = encrypt.EncodeMd5([]byte(ran))
|
||||
|
||||
@@ -11,9 +11,13 @@ package controllers
|
||||
****************************************************/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"merchant/datas"
|
||||
"merchant/models/merchant"
|
||||
"merchant/service"
|
||||
"merchant/sys/enum"
|
||||
"merchant/utils/mfa"
|
||||
"merchant/utils/response"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -36,6 +40,32 @@ func (c *UserInfo) ShowModifyUserInfoUI() {
|
||||
c.TplName = "modify_userInfo.html"
|
||||
}
|
||||
|
||||
func (c *UserInfo) ShowTotpUI() {
|
||||
us := c.GetSession(enum.UserSession)
|
||||
u := us.(merchant.MerchantInfo)
|
||||
if u.MerchantUid == "" {
|
||||
c.Data["json"] = datas.BaseDataJSON{
|
||||
Code: -1,
|
||||
Msg: "当前用户不存在",
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
otp, err := mfa.GetOtp(u.LoginAccount, fmt.Sprintf("商户 %s", u.MerchantName))
|
||||
if err != nil {
|
||||
c.Data["json"] = datas.BaseDataJSON{
|
||||
Code: -1,
|
||||
Msg: "当前用户不存在",
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
c.Data["showTotp"] = u.OtpSecret == ""
|
||||
c.Data["totpImage"] = template.URL(otp.QrImage)
|
||||
c.Data["totpSecret"] = otp.Secret
|
||||
c.TplName = "totp.html"
|
||||
}
|
||||
|
||||
// ModifyUserInfo 修改用户信息
|
||||
func (c *UserInfo) ModifyUserInfo() {
|
||||
or_pwd := strings.TrimSpace(c.GetString("or_pwd"))
|
||||
@@ -102,22 +132,18 @@ stopRun:
|
||||
// ConfirmOriginPwd 验证原始密码
|
||||
func (c *UserInfo) ConfirmOriginPwd() {
|
||||
ori := strings.TrimSpace(c.GetString("c"))
|
||||
|
||||
us := c.GetSession(enum.UserSession)
|
||||
u := us.(merchant.MerchantInfo)
|
||||
|
||||
var (
|
||||
msg = enum.FailedString
|
||||
flag = enum.FailedFlag
|
||||
)
|
||||
|
||||
pwdMd5 := encrypt.EncodeMd5([]byte(ori))
|
||||
if strings.Compare(strings.ToUpper(pwdMd5), u.LoginPassword) != 0 {
|
||||
msg = "原始密码错误!"
|
||||
} else {
|
||||
flag = enum.SuccessFlag
|
||||
}
|
||||
|
||||
c.Data["json"] = pubMethod.JsonFormat(flag, "", msg, "")
|
||||
c.ServeJSON()
|
||||
c.StopRun()
|
||||
@@ -127,7 +153,6 @@ func (c *UserInfo) ConfirmOriginPwd() {
|
||||
func (c *UserInfo) ShowUserInfoUI() {
|
||||
us := c.GetSession(enum.UserSession)
|
||||
u := us.(merchant.MerchantInfo)
|
||||
|
||||
c.Data["userName"] = u.MerchantName
|
||||
c.Data["mobile"] = u.LoginAccount
|
||||
c.Data["email"] = u.LoginAccount
|
||||
@@ -141,7 +166,6 @@ func (c *UserInfo) ShowUserInfoUI() {
|
||||
func (c *UserInfo) QueryAllowedMM() {
|
||||
us := c.GetSession(enum.UserSession)
|
||||
u := us.(merchant.MerchantInfo)
|
||||
|
||||
if u.Id == 0 {
|
||||
c.Data["json"] = response.CommonRes{
|
||||
Msg: "获取用户失败",
|
||||
@@ -150,9 +174,7 @@ func (c *UserInfo) QueryAllowedMM() {
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
result := service.QueryAllowedDeployInfoMM(u.MerchantUid, "CARD_DH")
|
||||
|
||||
c.Data["json"] = response.CommonResWithData{
|
||||
CommonRes: response.CommonRes{
|
||||
Msg: "成功",
|
||||
@@ -161,5 +183,75 @@ func (c *UserInfo) QueryAllowedMM() {
|
||||
Data: result,
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
|
||||
}
|
||||
|
||||
func (c *UserInfo) SaveTotp() {
|
||||
code := c.GetString("totpCode")
|
||||
secret := c.GetString("totpSecret")
|
||||
if code == "" || secret == "" {
|
||||
c.Data["json"] = datas.BaseDataJSON{
|
||||
Code: -1,
|
||||
Msg: "未填写验证码",
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
us := c.GetSession(enum.UserSession)
|
||||
u := us.(merchant.MerchantInfo)
|
||||
ok := mfa.ValidCode(code, secret)
|
||||
if !ok {
|
||||
c.Data["json"] = datas.KeyDataJSON{
|
||||
Code: -1,
|
||||
Msg: "验证码验证错误",
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
err2 := merchant.UpdateOtpByUserID(u.MerchantUid, secret)
|
||||
if err2 != nil {
|
||||
c.Data["json"] = datas.BaseDataJSON{
|
||||
Code: -1,
|
||||
Msg: "更新二步验证失败",
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
c.Data["json"] = datas.KeyDataJSON{
|
||||
Code: 0,
|
||||
Msg: "success",
|
||||
}
|
||||
u.OtpSecret = secret
|
||||
_ = c.SetSession(enum.UserSession, u)
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *UserInfo) ResetTotp() {
|
||||
us := c.GetSession(enum.UserSession)
|
||||
u := us.(merchant.MerchantInfo)
|
||||
code := c.GetString("totpCode")
|
||||
ok := mfa.ValidCode(code, u.OtpSecret)
|
||||
if !ok {
|
||||
c.Data["json"] = datas.KeyDataJSON{
|
||||
Code: -1,
|
||||
Msg: "验证码错误",
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
err := merchant.UpdateOtpByUserID(u.MerchantUid, "")
|
||||
if err != nil {
|
||||
c.Data["json"] = datas.BaseDataJSON{
|
||||
Code: -1,
|
||||
Msg: "更新二步验证失败",
|
||||
}
|
||||
_ = c.ServeJSON()
|
||||
return
|
||||
}
|
||||
c.Data["json"] = datas.KeyDataJSON{
|
||||
Code: 0,
|
||||
Msg: "success",
|
||||
}
|
||||
u.OtpSecret = ""
|
||||
_ = c.SetSession(enum.UserSession, u)
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
/***************************************************
|
||||
** @Desc : This file for 代付申请和记录
|
||||
** @Time : 19.12.4 10:50
|
||||
** @Author : Joker
|
||||
** @File : withdraw
|
||||
** @Last Modified by : Joker
|
||||
** @Last Modified time: 19.12.4 10:50
|
||||
** @Software: GoLand
|
||||
****************************************************/
|
||||
package controllers
|
||||
|
||||
import (
|
||||
|
||||
17
datas/datas.go
Normal file
17
datas/datas.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package datas
|
||||
|
||||
type BaseDataJSON struct {
|
||||
Msg string
|
||||
Code int
|
||||
}
|
||||
|
||||
type KeyDataJSON struct {
|
||||
Msg string
|
||||
Code int
|
||||
Key string
|
||||
}
|
||||
|
||||
type KeyDataJSON2 struct {
|
||||
KeyDataJSON
|
||||
Data interface{}
|
||||
}
|
||||
2
go.mod
2
go.mod
@@ -8,6 +8,8 @@ require (
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/rs/xid v1.3.0
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/smartystreets/goconvey v1.6.4
|
||||
github.com/tealeg/xlsx v1.0.5
|
||||
github.com/xlzd/gotp v0.1.0
|
||||
)
|
||||
|
||||
4
go.sum
4
go.sum
@@ -155,6 +155,8 @@ github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKz
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
@@ -172,6 +174,8 @@ github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
|
||||
github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
|
||||
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||
github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
|
||||
github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
|
||||
go.etcd.io/etcd v3.3.25+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
|
||||
|
||||
@@ -11,7 +11,7 @@ package merchant
|
||||
****************************************************/
|
||||
|
||||
import (
|
||||
"github.com/beego/beego/v2/adapter/orm"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
)
|
||||
|
||||
@@ -37,6 +37,7 @@ type MerchantInfo struct {
|
||||
PayforFee float64
|
||||
UpdateTime string
|
||||
CreateTime string
|
||||
OtpSecret string
|
||||
}
|
||||
|
||||
const MERCHANT_INFO = "merchant_info"
|
||||
@@ -204,3 +205,14 @@ func DeleteMerchantByUid(merchantUid string) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func UpdateOtpByUserID(merchantUid, otpSecret string) error {
|
||||
o := orm.NewOrm()
|
||||
_, err := o.QueryTable(MERCHANT_INFO).
|
||||
Filter("merchant_uid", merchantUid).
|
||||
Update(orm.Params{"otp_secret": otpSecret})
|
||||
if err != nil {
|
||||
logs.Error("更新totp失败", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ type UserInfo struct {
|
||||
Status string
|
||||
Role string
|
||||
RoleName string
|
||||
OtpSecret string
|
||||
CreateTime string
|
||||
UpdateTime string
|
||||
}
|
||||
@@ -53,7 +54,6 @@ func GetOperatorByMap(params map[string]string, displayCount, offset int) []User
|
||||
}
|
||||
}
|
||||
_, err := qs.Exclude("status", "delete").Limit(displayCount, offset).OrderBy("-update_time").All(&userInfo)
|
||||
|
||||
if err != nil {
|
||||
logs.Error("get operator by map fail: ", err)
|
||||
}
|
||||
@@ -145,3 +145,14 @@ func DeleteUserByUserId(userId string) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetAllUser() []UserInfo {
|
||||
o := orm.NewOrm()
|
||||
var userInfo []UserInfo
|
||||
qs := o.QueryTable(USERINFO)
|
||||
_, err := qs.Exclude("status", "delete").All(&userInfo)
|
||||
if err != nil {
|
||||
logs.Error("get operator by map fail: ", err)
|
||||
}
|
||||
return userInfo
|
||||
}
|
||||
|
||||
@@ -43,9 +43,12 @@ func init() {
|
||||
beego.Router("/trade/complaint/?:params", &controllers.TradeRecord{}, "*:ComplaintQueryAndListPage")
|
||||
|
||||
beego.Router("/user_info/show_modify_ui", &controllers.UserInfo{}, "*:ShowModifyUserInfoUI")
|
||||
beego.Router("/user_info/show_totp_ui", &controllers.UserInfo{}, "*:ShowTotpUI")
|
||||
beego.Router("/user_info/modify_userInfo/?:params", &controllers.UserInfo{}, "*:ModifyUserInfo")
|
||||
beego.Router("/user_info/confirm_pwd/?:params", &controllers.UserInfo{}, "*:ConfirmOriginPwd")
|
||||
beego.Router("/user_info/show_ui", &controllers.UserInfo{}, "*:ShowUserInfoUI")
|
||||
beego.Router("/user_info/submitTotp", &controllers.UserInfo{}, "*:SaveTotp")
|
||||
beego.Router("/user_info/resetTotp", &controllers.UserInfo{}, "*:ResetTotp")
|
||||
beego.Router("/userInfo/queryAllowedMM", &controllers.UserInfo{}, "*:QueryAllowedMM")
|
||||
|
||||
beego.Router("/withdraw/show_ui", &controllers.Withdraw{}, "*:ShowWithdrawUI")
|
||||
@@ -56,5 +59,4 @@ func init() {
|
||||
beego.Router("/withdraw/list_record/?:params", &controllers.Withdraw{}, "*:WithdrawQueryAndListPage")
|
||||
|
||||
beego.Router("/gen_link/gen_link", &controllers.GenLink{}, "*:ShowGenLinkUI")
|
||||
|
||||
}
|
||||
|
||||
45
utils/mfa/mfa.go
Normal file
45
utils/mfa/mfa.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package mfa
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/skip2/go-qrcode"
|
||||
"github.com/xlzd/gotp"
|
||||
)
|
||||
|
||||
const secretLength = 16
|
||||
|
||||
type Otp struct {
|
||||
Secret string `json:"secret"`
|
||||
QrImage string `json:"qrImage"`
|
||||
}
|
||||
|
||||
func GetOtp(userId, username string) (otp Otp, err error) {
|
||||
secret := gotp.RandomSecret(secretLength)
|
||||
otp.Secret = secret
|
||||
totp := gotp.NewTOTP(secret, 6, 30, nil)
|
||||
uri := totp.ProvisioningUri(userId, "卡销平台 "+username)
|
||||
uri, err = url.PathUnescape(uri)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
subImg, err := qrcode.Encode(uri, qrcode.Medium, 256)
|
||||
dist := make([]byte, 3000)
|
||||
base64.StdEncoding.Encode(dist, subImg)
|
||||
index := bytes.IndexByte(dist, 0)
|
||||
baseImage := dist[0:index]
|
||||
otp.QrImage = "data:image/png;base64," + string(baseImage)
|
||||
return
|
||||
}
|
||||
|
||||
func ValidCode(code string, secret string) bool {
|
||||
totp := gotp.NewDefaultTOTP(secret)
|
||||
now := time.Now().Unix()
|
||||
strInt64 := strconv.FormatInt(now, 10)
|
||||
id16, _ := strconv.Atoi(strInt64)
|
||||
return totp.Verify(code, int64(id16))
|
||||
}
|
||||
@@ -34,6 +34,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -58,12 +58,16 @@
|
||||
<input id="Password" type="password" name="Password" required
|
||||
data-msg="请输入您的密码" class="input-material" placeholder="密码">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input id="totpCode" type="text" name="totpCode"
|
||||
data-msg="请输入您的二步验证(如没设置则不需要输入)" class="input-material"
|
||||
placeholder="二步验证(未设置则不需要)">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input id="captchaCode" style="float: left;width: 55%" type="text"
|
||||
name="captchaCode" required
|
||||
data-msg="请输入验证码" class="input-material"
|
||||
placeholder="验证码">
|
||||
|
||||
<img src="/img.do/{{.CaptchaId}}.png"
|
||||
style="float: right;width: 40%;max-height: 45px;"
|
||||
id="rcCaptcha-img" alt="验证码过期,请刷新页面!"
|
||||
@@ -98,12 +102,6 @@
|
||||
|
||||
<script type="application/javascript">
|
||||
$(function () {
|
||||
//验证码
|
||||
// $("#captchaCode").blur(function () {
|
||||
// login.verifyCaptchaId();
|
||||
// });
|
||||
|
||||
//提交回车键
|
||||
$(document).keydown(function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
$("#btn_submit").click();
|
||||
|
||||
@@ -31,15 +31,16 @@
|
||||
<li><a href="/index/ui/"> <i class="icon-home"></i>首页 </a></li>
|
||||
<li>
|
||||
<a href="#exampledropdownDropdown" aria-expanded="true" data-toggle="collapse"> <i
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class=" list-unstyled ">
|
||||
<li class="active"><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#exampledropdownDropdown1" aria-expanded="false" data-toggle="collapse"> <i
|
||||
class="icon icon-presentation"></i>订单管理 </a>
|
||||
class="icon icon-presentation"></i>订单管理 </a>
|
||||
<ul id="exampledropdownDropdown1" class="collapse list-unstyled ">
|
||||
<li><a href="/trade/show_ui">订单记录</a></li>
|
||||
<li><a href="/trade/show_complaint_ui">投诉列表</a></li>
|
||||
@@ -47,12 +48,14 @@
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#exampledropdownDropdown2" aria-expanded="false" data-toggle="collapse"> <i
|
||||
class="icon icon-bill"></i>财务管理 </a>
|
||||
class="icon icon-bill"></i>财务管理 </a>
|
||||
<ul id="exampledropdownDropdown2" class="collapse list-unstyled ">
|
||||
<li><a href="/withdraw/show_ui">申请提现</a></li>
|
||||
<li><a href="/multi_withdraw/show_multi_ui">批量申请提现</a></li>
|
||||
<li><a href="/withdraw/show_list_ui">提现记录</a></li>
|
||||
{{/* <li><a href="/recharge/show_recharge_list_ui">自定义记录</a></li>*/}}
|
||||
{{/*
|
||||
<li><a href="/recharge/show_recharge_list_ui">自定义记录</a></li>
|
||||
*/}}
|
||||
<li><a href="/history/show_history_list_ui">资产变动明细</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -67,18 +70,18 @@
|
||||
</div>
|
||||
</header>
|
||||
<!-- Breadcrumb-->
|
||||
<div class="breadcrumb-holder container-fluid">
|
||||
<ul class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/index/ui/">首页</a></li>
|
||||
<li class="breadcrumb-item active">修改登录密码</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Forms Section-->
|
||||
<section class="forms">
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid">
|
||||
<div class="breadcrumb-holder container-fluid">
|
||||
<ul class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/index/ui/">首页</a></li>
|
||||
<li class="breadcrumb-item active">修改登录密码</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Forms Section-->
|
||||
<section class="forms" style="margin-top: 20px">
|
||||
<div class="row">
|
||||
<!-- Basic Form-->
|
||||
<div class="col-lg-6">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form id="modify_userInfo">
|
||||
@@ -109,8 +112,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li class="active"><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -31,15 +31,16 @@
|
||||
<li><a href="/index/ui/"> <i class="icon-home"></i>首页 </a></li>
|
||||
<li>
|
||||
<a href="#exampledropdownDropdown" aria-expanded="true" data-toggle="collapse"> <i
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class=" list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li class="active"><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#exampledropdownDropdown1" aria-expanded="false" data-toggle="collapse"> <i
|
||||
class="icon icon-presentation"></i>订单管理 </a>
|
||||
class="icon icon-presentation"></i>订单管理 </a>
|
||||
<ul id="exampledropdownDropdown1" class="collapse list-unstyled ">
|
||||
<li><a href="/trade/show_ui">订单记录</a></li>
|
||||
<li><a href="/trade/show_complaint_ui">投诉列表</a></li>
|
||||
@@ -47,12 +48,14 @@
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#exampledropdownDropdown2" aria-expanded="false" data-toggle="collapse"> <i
|
||||
class="icon icon-bill"></i>财务管理 </a>
|
||||
class="icon icon-bill"></i>财务管理 </a>
|
||||
<ul id="exampledropdownDropdown2" class="collapse list-unstyled ">
|
||||
<li><a href="/withdraw/show_ui">申请提现</a></li>
|
||||
<li><a href="/multi_withdraw/show_multi_ui">批量申请提现</a></li>
|
||||
<li><a href="/withdraw/show_list_ui">提现记录</a></li>
|
||||
{{/*<li><a href="/recharge/show_recharge_list_ui">自定义记录</a></li>*/}}
|
||||
{{/*
|
||||
<li><a href="/recharge/show_recharge_list_ui">自定义记录</a></li>
|
||||
*/}}
|
||||
<li><a href="/history/show_history_list_ui">资产变动明细</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -67,18 +70,19 @@
|
||||
</div>
|
||||
</header>
|
||||
<!-- Breadcrumb-->
|
||||
<div class="breadcrumb-holder container-fluid">
|
||||
<ul class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/index/ui/">首页</a></li>
|
||||
<li class="breadcrumb-item active">账户资料</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Forms Section-->
|
||||
<section class="forms">
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid">
|
||||
<div class="breadcrumb-holder container-fluid">
|
||||
<ul class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/index/ui/">首页</a></li>
|
||||
<li class="breadcrumb-item active">账户资料</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Forms Section-->
|
||||
<section class="forms" style="margin-top: 20px">
|
||||
|
||||
<div class="row">
|
||||
<!-- Basic Form-->
|
||||
<div class="col-lg-6">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form id="modify_userInfo">
|
||||
@@ -105,25 +109,31 @@
|
||||
value="T+{{.riskDay}}"
|
||||
class="form-control" readonly>
|
||||
</div>
|
||||
{{/* <div class="form-group">*/}}
|
||||
{{/* <label class="form-control-label">payKey</label>*/}}
|
||||
{{/* <input type="text" id="confirm_pwd" name="confirm_pwd"*/}}
|
||||
{{/* value="{{.key}}"*/}}
|
||||
{{/* class="form-control" readonly>*/}}
|
||||
{{/* </div>*/}}
|
||||
{{/* <div class="form-group">*/}}
|
||||
{{/* <label class="form-control-label">paySecret</label>*/}}
|
||||
{{/* <input type="text" id="confirm_pwd" name="confirm_pwd"*/}}
|
||||
{{/* value="{{.secret}}"*/}}
|
||||
{{/* class="form-control" readonly>*/}}
|
||||
{{/* </div>*/}}
|
||||
{{/*
|
||||
<div class="form-group">*/}}
|
||||
{{/* <label class="form-control-label">payKey</label>*/}}
|
||||
{{/* <input type="text" id="confirm_pwd" name="confirm_pwd" */}}
|
||||
{{/* value="{{.key}}"*/}}
|
||||
{{/* class="form-control" readonly>*/}}
|
||||
{{/*
|
||||
</div>
|
||||
*/}}
|
||||
{{/*
|
||||
<div class="form-group">*/}}
|
||||
{{/* <label class="form-control-label">paySecret</label>*/}}
|
||||
{{/* <input type="text" id="confirm_pwd" name="confirm_pwd" */}}
|
||||
{{/* value="{{.secret}}"*/}}
|
||||
{{/* class="form-control" readonly>*/}}
|
||||
{{/*
|
||||
</div>
|
||||
*/}}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
178
views/totp.html
Normal file
178
views/totp.html
Normal file
@@ -0,0 +1,178 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{{template "template/css.html"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<!-- Main Navbar-->
|
||||
{{template "template/header.html"}}
|
||||
<div class="page-content d-flex align-items-stretch">
|
||||
<!-- Side Navbar -->
|
||||
<nav class="side-navbar">
|
||||
<!-- Sidebar Header-->
|
||||
<div class="sidebar-header d-flex align-items-center">
|
||||
<a href="/index/ui/">
|
||||
<div class="avatar">
|
||||
<img src="../../static/img/avatar-1.jpg" alt="..."
|
||||
class="img-fluid rounded-circle">
|
||||
</div>
|
||||
</a>
|
||||
<a href="#">
|
||||
<div class="title">
|
||||
<h1 class="h4">{{.userName}}</h1>
|
||||
<p>欢迎您!</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Sidebar Navidation Menus--><span class="heading">主菜单</span>
|
||||
<ul class="list-unstyled">
|
||||
<li><a href="/index/ui/"> <i class="icon-home"></i>首页 </a></li>
|
||||
<li>
|
||||
<a href="#exampledropdownDropdown" aria-expanded="true" data-toggle="collapse"> <i
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class=" list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li class="active"><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#exampledropdownDropdown1" aria-expanded="false" data-toggle="collapse"> <i
|
||||
class="icon icon-presentation"></i>订单管理 </a>
|
||||
<ul id="exampledropdownDropdown1" class="collapse list-unstyled ">
|
||||
<li><a href="/trade/show_ui">订单记录</a></li>
|
||||
<li><a href="/trade/show_complaint_ui">投诉列表</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#exampledropdownDropdown2" aria-expanded="false" data-toggle="collapse"> <i
|
||||
class="icon icon-bill"></i>财务管理</a>
|
||||
<ul id="exampledropdownDropdown2" class="collapse list-unstyled ">
|
||||
<li><a href="/withdraw/show_ui">申请提现</a></li>
|
||||
<li><a href="/multi_withdraw/show_multi_ui">批量申请提现</a></li>
|
||||
<li><a href="/withdraw/show_list_ui">提现记录</a></li>
|
||||
{{/*
|
||||
<li><a href="/recharge/show_recharge_list_ui">自定义记录</a></li>
|
||||
*/}}
|
||||
<li><a href="/history/show_history_list_ui">资产变动明细</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/gen_link/gen_link">测试链接</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="content-inner">
|
||||
<!-- Page Header-->
|
||||
<header class="page-header">
|
||||
<div class="container-fluid">
|
||||
<h2 class="no-margin-bottom">修改二步验证</h2>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Breadcrumb-->
|
||||
<div class="container-fluid">
|
||||
<div class="breadcrumb-holder container-fluid">
|
||||
<ul class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/index/ui/">首页</a></li>
|
||||
<li class="breadcrumb-item active">修改二步验证</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Forms Section-->
|
||||
<section class="forms" style="margin-top: 20px">
|
||||
<div class="row">
|
||||
<!-- Basic Form-->
|
||||
{{if .showTotp}}
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="totp-image">
|
||||
<img src="{{.totpImage}}" alt="二步验证">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input id="totpSecret" name="totpSecret" value="{{.totpSecret}}" hidden>
|
||||
<label class="form-control-label">请输入二步验证
|
||||
<input id="totpCode" name="totpCode" value="">
|
||||
</label>
|
||||
</div>
|
||||
<p class="warning">注意:保存新的二步验证后,旧的验证将不可用</p>
|
||||
<button class="btn-primary" onclick="submitTotp()">提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div>
|
||||
<p class="warning">重置二步验证将导致现有的二步验证不可用!</p>
|
||||
<label>
|
||||
二步验证码:
|
||||
<input value="" id="secondTotp" name="secondTotp"
|
||||
placeholder="请输入二步验证">
|
||||
</label>
|
||||
<button class="btn-warning" onclick="resetTotp()">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- JavaScript files-->
|
||||
{{template "template/js.html"}}
|
||||
</body>
|
||||
<script>
|
||||
function submitTotp() {
|
||||
$.ajax({
|
||||
url: "/user_info/submitTotp",
|
||||
method: "POST",
|
||||
data: {
|
||||
"totpSecret": $("#totpSecret").val(),
|
||||
"totpCode": $("#totpCode").val()
|
||||
},
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
if (res.Code === 0) {
|
||||
alert("设置totp成功")
|
||||
location.reload()
|
||||
} else {
|
||||
alert(`设置失败,原因:${res.Msg}`)
|
||||
}
|
||||
},
|
||||
error: (e) => {
|
||||
alert("设置totp失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function resetTotp() {
|
||||
$.ajax({
|
||||
url: "/user_info/resetTotp",
|
||||
method: "POST",
|
||||
data: {
|
||||
"totpCode": $("#secondTotp").val()
|
||||
},
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
if (res.Code === 0) {
|
||||
alert("重置totp成功")
|
||||
location.reload()
|
||||
} else {
|
||||
alert(`设置失败,原因:${res.Msg}`)
|
||||
}
|
||||
},
|
||||
error: (e) => {
|
||||
alert("设置totp失败")
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.warning {
|
||||
color: red !important;
|
||||
}
|
||||
</style>
|
||||
</html>
|
||||
@@ -33,6 +33,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
class="icon icon-user"></i>账户管理 </a>
|
||||
<ul id="exampledropdownDropdown" class="collapse list-unstyled ">
|
||||
<li><a href="/user_info/show_modify_ui">修改密码</a></li>
|
||||
<li><a href="/user_info/show_totp_ui">二步验证</a></li>
|
||||
<li><a href="/user_info/show_ui">账户资料</a></li>
|
||||
<li><a href="/index/show_pay_way_ui">通道配置</a></li>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user