:building:设置二步验证

This commit is contained in:
sunxiaolong
2023-12-24 22:50:58 +08:00
parent 8363bd8add
commit 1bb17833cc
24 changed files with 464 additions and 81 deletions

View File

@@ -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))

View File

@@ -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()
}

View File

@@ -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
View 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
View File

@@ -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
View File

@@ -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=

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
View 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))
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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();

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
View 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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>