mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2026-04-26 23:55:18 +08:00
[系统用户]增加OTP动态密码二次认证
This commit is contained in:
@@ -52,7 +52,7 @@ tbody {
|
||||
}
|
||||
p.comment,
|
||||
div.comment {
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
padding-top: 0.4em;
|
||||
}
|
||||
p.comment em,
|
||||
|
||||
@@ -56,7 +56,7 @@ tbody {
|
||||
}
|
||||
|
||||
p.comment, div.comment {
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
padding-top: 0.4em;
|
||||
}
|
||||
|
||||
|
||||
6
web/views/@default/admins/@admin_menu.html
Normal file
6
web/views/@default/admins/@admin_menu.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<first-menu>
|
||||
<menu-item href="/admins">系统用户</menu-item>
|
||||
<span class="item">|</span>
|
||||
<menu-item :href="'/admins/admin?adminId=' + admin.id" code="index">"{{admin.fullname}}" 详情</menu-item>
|
||||
<menu-item :href="'/admins/update?adminId=' + admin.id" code="update">修改</menu-item>
|
||||
</first-menu>
|
||||
7
web/views/@default/admins/admin.css
Normal file
7
web/views/@default/admins/admin.css
Normal file
@@ -0,0 +1,7 @@
|
||||
.modules-box .module-box {
|
||||
float: left;
|
||||
width: 9em;
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
/*# sourceMappingURL=admin.css.map */
|
||||
1
web/views/@default/admins/admin.css.map
Normal file
1
web/views/@default/admins/admin.css.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["admin.less"],"names":[],"mappings":"AAAA,YACC;EACC,WAAA;EACA,UAAA;EACA,iBAAA;EACA,oBAAA","file":"admin.css"}
|
||||
66
web/views/@default/admins/admin.html
Normal file
66
web/views/@default/admins/admin.html
Normal file
@@ -0,0 +1,66 @@
|
||||
{$layout}
|
||||
{$template "admin_menu"}
|
||||
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">全名</td>
|
||||
<td>
|
||||
{{admin.fullname}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>状态</td>
|
||||
<td>
|
||||
<label-on :v-is-on="admin.isOn"></label-on>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>登录用户名</td>
|
||||
<td>
|
||||
{{admin.username}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否为超级管理员</td>
|
||||
<td>
|
||||
<span v-if="admin.isSuper" class="green">Y</span>
|
||||
<span v-else class="disabled">N</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="!admin.isSuper">
|
||||
<td>权限</td>
|
||||
<td>
|
||||
<div class="modules-box" v-if="modules.length > 0">
|
||||
<div class="module-box" v-for="module in modules">
|
||||
<i class="icon circle small grey"></i> {{module.name}}
|
||||
</div>
|
||||
</div>
|
||||
<span v-else class="disabled">暂时还没有可以管理的模块。</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>OTP认证</h3>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">状态</td>
|
||||
<td>
|
||||
<span v-if="otp != null && otp.isOn" class="green">已启用</span>
|
||||
<span v-else class="disabled">未启用</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="otp != null && otp.isOn">
|
||||
<td colspan="2"><more-options-indicator>更多信息</more-options-indicator></td>
|
||||
</tr>
|
||||
<tr v-if="otp != null && otp.isOn && moreOptionsVisible">
|
||||
<td>认证二维码</td>
|
||||
<td>
|
||||
<img :src="'/admins/otpQrcode?adminId=' + admin.id"/>
|
||||
<p class="comment">可以通过二维码快速添加OTP认证信息到App中。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="otp != null && otp.isOn && moreOptionsVisible">
|
||||
<td>密钥</td>
|
||||
<td>{{otp.params.secret}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
8
web/views/@default/admins/admin.less
Normal file
8
web/views/@default/admins/admin.less
Normal file
@@ -0,0 +1,8 @@
|
||||
.modules-box {
|
||||
.module-box {
|
||||
float: left;
|
||||
width: 9em;
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,13 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>OTP认证</td>
|
||||
<td>
|
||||
<checkbox name="otpOn">启用OTP</checkbox>
|
||||
<p class="comment">启用OTP认证后,在用户登录的时候需要同时填写OTP动态密码。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<tr>
|
||||
<th>用户名</th>
|
||||
<th>全名</th>
|
||||
<th>创建时间</th>
|
||||
<th>OTP认证</th>
|
||||
<th class="center width10">状态</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
@@ -18,12 +18,15 @@
|
||||
</div>
|
||||
</td>
|
||||
<td :class="{disabled:!admin.isOn}">{{admin.fullname}}</td>
|
||||
<td :class="{disabled:!admin.isOn}">{{admin.createdTime}}</td>
|
||||
<td>
|
||||
<span v-if="admin.otpLoginIsOn" class="green">Y</span>
|
||||
<span v-else class="disabled">N</span>
|
||||
</td>
|
||||
<td class="center">
|
||||
<label-on :v-is-on="admin.isOn"></label-on>
|
||||
</td>
|
||||
<td>
|
||||
<a href="" @click.prevent="updateAdmin(admin.id)">修改</a> <a href="" @click.prevent="deleteAdmin(admin.id)">删除</a>
|
||||
<a :href="'/admins/admin?adminId=' + admin.id">详情</a> <a href="" @click.prevent="deleteAdmin(admin.id)">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -21,15 +21,4 @@ Tea.context(function () {
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
this.updateAdmin = function (adminId) {
|
||||
teaweb.popup("/admins/updatePopup?adminId=" + adminId, {
|
||||
height: "22em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -4,4 +4,4 @@
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
/*# sourceMappingURL=updatePopup.css.map */
|
||||
/*# sourceMappingURL=update.css.map */
|
||||
1
web/views/@default/admins/update.css.map
Normal file
1
web/views/@default/admins/update.css.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["update.less"],"names":[],"mappings":"AAAA,YACC;EACC,WAAA;EACA,WAAA;EACA,iBAAA;EACA,oBAAA","file":"update.css"}
|
||||
68
web/views/@default/admins/update.html
Normal file
68
web/views/@default/admins/update.html
Normal file
@@ -0,0 +1,68 @@
|
||||
{$layout}
|
||||
{$template "admin_menu"}
|
||||
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="adminId" :value="admin.id"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">全名 *</td>
|
||||
<td>
|
||||
<input type="text" name="fullname" maxlength="100" ref="focus" v-model="admin.fullname"/>
|
||||
<p class="comment">可以输入姓名、公司名等容易识别的名称。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>登录用户名 *</td>
|
||||
<td>
|
||||
<input type="text" name="username" maxlength="100" v-model="admin.username"/>
|
||||
<p class="comment">用户名只能英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>登录密码</td>
|
||||
<td>
|
||||
<input type="password" name="pass1" maxlength="100"/>
|
||||
<p class="comment">留空表示不修改。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>确认登录密码</td>
|
||||
<td>
|
||||
<input type="password" name="pass2" maxlength="100"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否为超级管理员</td>
|
||||
<td>
|
||||
<checkbox name="isSuper" v-model="admin.isSuper"></checkbox>
|
||||
<p class="comment">超级管理员自动拥有所有的管理权限。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="!admin.isSuper">
|
||||
<td>权限</td>
|
||||
<td>
|
||||
<div class="modules-box">
|
||||
<div class="module-box" v-for="module in modules">
|
||||
<checkbox name="moduleCodes" :v-value="module.code" v-model="module.isChecked">{{module.name}}</checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>OTP认证</td>
|
||||
<td>
|
||||
<checkbox name="otpOn" v-model="admin.otpLoginIsOn">启用OTP</checkbox>
|
||||
<p class="comment">启用OTP认证后,在用户登录的时候需要同时填写OTP动态密码。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否启用</td>
|
||||
<td>
|
||||
<checkbox name="isOn" v-model="admin.isOn"></checkbox>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
3
web/views/@default/admins/update.js
Normal file
3
web/views/@default/admins/update.js
Normal file
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifySuccess("保存成功", "/admins/admin?adminId=" + this.admin.id)
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["updatePopup.less"],"names":[],"mappings":"AAAA,YACC;EACC,WAAA;EACA,WAAA;EACA,iBAAA;EACA,oBAAA","file":"updatePopup.css"}
|
||||
@@ -1,64 +0,0 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>修改系统用户</h3>
|
||||
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
|
||||
<input type="hidden" name="adminId" :value="admin.id"/>
|
||||
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">全名 *</td>
|
||||
<td>
|
||||
<input type="text" name="fullname" maxlength="100" ref="focus" v-model="admin.fullname"/>
|
||||
<p class="comment">可以输入姓名、公司名等容易识别的名称。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>登录用户名 *</td>
|
||||
<td>
|
||||
<input type="text" name="username" maxlength="100" v-model="admin.username"/>
|
||||
<p class="comment">用户名只能英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>登录密码</td>
|
||||
<td>
|
||||
<input type="password" name="pass1" maxlength="100"/>
|
||||
<p class="comment">留空表示不修改。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>确认登录密码</td>
|
||||
<td>
|
||||
<input type="password" name="pass2" maxlength="100"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否为超级管理员</td>
|
||||
<td>
|
||||
<checkbox name="isSuper" v-model="admin.isSuper"></checkbox>
|
||||
<p class="comment">超级管理员自动拥有所有的管理权限。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="!admin.isSuper">
|
||||
<td>权限</td>
|
||||
<td>
|
||||
<div class="modules-box">
|
||||
<div class="module-box" v-for="module in modules">
|
||||
<checkbox name="moduleCodes" :v-value="module.code" v-model="module.isChecked">{{module.name}}</checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否启用</td>
|
||||
<td>
|
||||
<checkbox name="isOn" v-model="admin.isOn"></checkbox>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
@@ -1,6 +1,6 @@
|
||||
.form-box {
|
||||
position: fixed;
|
||||
top: 2.5em;
|
||||
top: 2em;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA;EACI,eAAA;EACA,UAAA;EACA,SAAA;EACA,OAAA;EACA,QAAA;;AAGJ;EACI,eAAA;EACA,WAAA;EACA,QAAA;EACA,SAAA;EACA,kBAAA;EACA,iBAAA;;AANJ,IAQC;EACC,kBAAA;EACA,yBAAA;;AAVF,IAaC;EACC,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,mBAAA;EACA,UAAA;;AAlBF,IAqBC;EACC,iBAAA;EACA,cAAA;EACA,WAAA;;AASD,mBALoC;EACjC;IACI,UAAA;IACA,iBAAA","file":"index.css"}
|
||||
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA;EACI,eAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,QAAA;;AAGJ;EACI,eAAA;EACA,WAAA;EACA,QAAA;EACA,SAAA;EACA,kBAAA;EACA,iBAAA;;AANJ,IAQC;EACC,kBAAA;EACA,yBAAA;;AAVF,IAaC;EACC,gBAAA;EACA,iBAAA;EACA,gBAAA;EACA,mBAAA;EACA,UAAA;;AAlBF,IAqBC;EACC,iBAAA;EACA,cAAA;EACA,WAAA;;AASD,mBALoC;EACjC;IACI,UAAA;IACA,iBAAA","file":"index.css"}
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="ui field">
|
||||
<div class="ui left icon input">
|
||||
<i class="ui user icon"></i>
|
||||
<input type="text" name="username" v-model="username" placeholder="请输入用户名" maxlength="200" ref="usernameRef"/>
|
||||
<input type="text" name="username" v-model="username" placeholder="请输入用户名" maxlength="200" ref="usernameRef" @input="changeUsername"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
@@ -37,6 +37,12 @@
|
||||
<input type="password" v-model="password" placeholder="请输入密码" maxlength="200" @input="changePassword()" ref="passwordRef"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui field" v-show="showOTP">
|
||||
<div class="ui left icon input">
|
||||
<i class="ui barcode icon"></i>
|
||||
<input type="text" name="otpCode" placeholder="请输入OTP动态密码" maxlength="6"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<a href="" @click.prevent="showMoreOptions()">更多选项 <i class="icon angle" :class="{down:!moreOptionsVisible, up:moreOptionsVisible}"></i> </a>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
Tea.context(function () {
|
||||
this.username = "";
|
||||
this.password = "";
|
||||
this.passwordMd5 = "";
|
||||
this.encodedFrom = window.encodeURIComponent(this.from);
|
||||
this.username = ""
|
||||
this.password = ""
|
||||
this.passwordMd5 = ""
|
||||
this.encodedFrom = window.encodeURIComponent(this.from)
|
||||
|
||||
this.isSubmitting = false;
|
||||
this.showOTP = false
|
||||
|
||||
this.isSubmitting = false
|
||||
|
||||
this.$delay(function () {
|
||||
this.$find("form input[name='username']").focus();
|
||||
this.changePassword();
|
||||
this.$find("form input[name='username']").focus()
|
||||
this.changePassword()
|
||||
});
|
||||
|
||||
this.changeUsername = function () {
|
||||
this.$post("/checkOTP")
|
||||
.params({
|
||||
username: this.username
|
||||
})
|
||||
.success(function (resp) {
|
||||
this.showOTP = resp.data.requireOTP
|
||||
})
|
||||
}
|
||||
|
||||
this.changePassword = function () {
|
||||
this.passwordMd5 = md5(this.password.trim());
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.form-box {
|
||||
position: fixed;
|
||||
top: 2.5em;
|
||||
top: 2em;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
Reference in New Issue
Block a user