mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2024-11-24 02:37:05 +00:00
Reorganize TOTP in the control panel templates to allow adding multiple devices and disabling individual devices
This commit is contained in:
parent
113b7bd827
commit
30f067bc72
@ -1740,7 +1740,7 @@ paths:
|
|||||||
text/html:
|
text/html:
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
/mfa/totp/enable:
|
/mfa/enable/totp:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- MFA
|
- MFA
|
||||||
|
@ -468,7 +468,7 @@ def ssl_provision_certs():
|
|||||||
def mfa_get_status():
|
def mfa_get_status():
|
||||||
# Anyone accessing this route is an admin, and we permit them to
|
# Anyone accessing this route is an admin, and we permit them to
|
||||||
# see the MFA status for any user if they submit a 'user' form
|
# see the MFA status for any user if they submit a 'user' form
|
||||||
# field. But we don't include provisioning info since a user can
|
# field. But we don't always include provisioning info since a user can
|
||||||
# only provision for themselves.
|
# only provision for themselves.
|
||||||
email = request.form.get('user', request.user_email) # user field if given, otherwise the user making the request
|
email = request.form.get('user', request.user_email) # user field if given, otherwise the user making the request
|
||||||
try:
|
try:
|
||||||
@ -485,7 +485,7 @@ def mfa_get_status():
|
|||||||
return (str(e), 400)
|
return (str(e), 400)
|
||||||
return json_response(resp)
|
return json_response(resp)
|
||||||
|
|
||||||
@app.route('/mfa/totp/enable', methods=['POST'])
|
@app.route('/mfa/enable/totp', methods=['POST'])
|
||||||
@authorized_personnel_only
|
@authorized_personnel_only
|
||||||
def totp_post_enable():
|
def totp_post_enable():
|
||||||
secret = request.form.get('secret')
|
secret = request.form.get('secret')
|
||||||
|
@ -1,34 +1,10 @@
|
|||||||
<style>
|
<style>
|
||||||
.twofactor #totp-setup,
|
|
||||||
.twofactor #disable-2fa,
|
|
||||||
.twofactor #output-2fa {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.twofactor.loaded .loading-indicator {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.twofactor.disabled #disable-2fa,
|
|
||||||
.twofactor.enabled #totp-setup {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.twofactor.disabled #totp-setup,
|
|
||||||
.twofactor.enabled #disable-2fa {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.twofactor #totp-setup-qr img {
|
.twofactor #totp-setup-qr img {
|
||||||
display: block;
|
display: block;
|
||||||
width: 256px;
|
width: 256px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.twofactor #output-2fa.visible {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<h2>Two-Factor Authentication</h2>
|
<h2>Two-Factor Authentication</h2>
|
||||||
@ -51,10 +27,11 @@ and ensure every administrator account for this control panel does the same.</st
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="twofactor">
|
<div class="twofactor">
|
||||||
<div class="loading-indicator">Loading...</div>
|
<div id="mfa-devices">
|
||||||
|
</div>
|
||||||
|
|
||||||
<form id="totp-setup">
|
<form id="totp-setup" style="display: none">
|
||||||
<h3>Setup Instructions</h3>
|
<h3>Add a TOTP Device</h3>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<p>1. Install <a href="https://freeotp.github.io/">FreeOTP</a> or <a href="https://www.pcworld.com/article/3225913/what-is-two-factor-authentication-and-which-2fa-apps-are-best.html">any
|
<p>1. Install <a href="https://freeotp.github.io/">FreeOTP</a> or <a href="https://www.pcworld.com/article/3225913/what-is-two-factor-authentication-and-which-2fa-apps-are-best.html">any
|
||||||
@ -85,24 +62,24 @@ and ensure every administrator account for this control panel does the same.</st
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form id="disable-2fa">
|
|
||||||
<div class="form-group">
|
|
||||||
<p>Two-factor authentication is active for your account<span id="mfa-device-label"></span>.</p>
|
|
||||||
<p>You will have to log into the admin panel again after disabling two-factor authentication.</p>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn btn-danger">Disable Two-Factor Authentication</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div id="output-2fa" class="panel panel-danger">
|
<div id="output-2fa" class="panel panel-danger hidden">
|
||||||
<div class="panel-body"></div>
|
<div class="panel-body"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="mfa-device-templates" style="display: none">
|
||||||
|
<form class="totp" style="margin: 1em 0; border: 1px solid #AAA; padding: 10px;">
|
||||||
|
<p>Two-factor authentication is active for your account<span class="mfa-device-label"></span>.</p>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="btn btn-danger">Disable TOTP Device</button>
|
||||||
|
</div>
|
||||||
|
<p style="margin-bottom: 0">You will have to log into the admin panel again after disabling two-factor authentication.</p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var el = {
|
var el = {
|
||||||
disableForm: document.getElementById('disable-2fa'),
|
|
||||||
output: document.getElementById('output-2fa'),
|
output: document.getElementById('output-2fa'),
|
||||||
totpSetupForm: document.getElementById('totp-setup'),
|
totpSetupForm: document.getElementById('totp-setup'),
|
||||||
totpSetupToken: document.getElementById('totp-setup-token'),
|
totpSetupToken: document.getElementById('totp-setup-token'),
|
||||||
@ -130,6 +107,8 @@ and ensure every administrator account for this control panel does the same.</st
|
|||||||
}
|
}
|
||||||
|
|
||||||
function render_totp_setup(provisioned_totp) {
|
function render_totp_setup(provisioned_totp) {
|
||||||
|
$(el.totpSetupForm).show();
|
||||||
|
|
||||||
var img = document.createElement('img');
|
var img = document.createElement('img');
|
||||||
img.src = "data:image/png;base64," + provisioned_totp.qr_code_base64;
|
img.src = "data:image/png;base64," + provisioned_totp.qr_code_base64;
|
||||||
|
|
||||||
@ -148,35 +127,35 @@ and ensure every administrator account for this control panel does the same.</st
|
|||||||
}
|
}
|
||||||
|
|
||||||
function render_disable(mfa) {
|
function render_disable(mfa) {
|
||||||
el.disableForm.addEventListener('submit', do_disable);
|
var panel = $('#mfa-device-templates .' + mfa.type).clone();
|
||||||
el.wrapper.classList.add('enabled');
|
$('#mfa-devices').append(panel);
|
||||||
|
panel.attr('data-mfa-id', mfa.id);
|
||||||
|
panel.on('submit', do_disable);
|
||||||
if (mfa.label)
|
if (mfa.label)
|
||||||
$("#mfa-device-label").text(" on device '" + mfa.label + "'");
|
panel.find(".mfa-device-label").text(" on device '" + mfa.label + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide_error() {
|
function hide_error() {
|
||||||
el.output.querySelector('.panel-body').innerHTML = '';
|
el.output.querySelector('.panel-body').innerHTML = '';
|
||||||
el.output.classList.remove('visible');
|
el.output.classList.add('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
function render_error(msg) {
|
function render_error(msg) {
|
||||||
el.output.querySelector('.panel-body').innerHTML = msg;
|
el.output.querySelector('.panel-body').innerHTML = msg;
|
||||||
el.output.classList.add('visible');
|
el.output.classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset_view() {
|
function reset_view() {
|
||||||
el.wrapper.classList.remove('loaded', 'disabled', 'enabled');
|
el.wrapper.classList.remove('loaded', 'disabled', 'enabled');
|
||||||
|
$('#mfa-devices > *').remove();
|
||||||
el.disableForm.removeEventListener('submit', do_disable);
|
|
||||||
|
|
||||||
hide_error();
|
hide_error();
|
||||||
|
|
||||||
|
$(el.totpSetupForm).hide();
|
||||||
el.totpSetupForm.reset();
|
el.totpSetupForm.reset();
|
||||||
el.totpSetupForm.removeEventListener('submit', do_enable_totp);
|
el.totpSetupForm.removeEventListener('submit', do_enable_totp);
|
||||||
|
|
||||||
el.totpSetupSecret.setAttribute('value', '');
|
el.totpSetupSecret.setAttribute('value', '');
|
||||||
el.totpSetupToken.removeEventListener('input', update_setup_disabled);
|
el.totpSetupToken.removeEventListener('input', update_setup_disabled);
|
||||||
|
|
||||||
el.totpSetupSubmit.setAttribute('disabled', '');
|
el.totpSetupSubmit.setAttribute('disabled', '');
|
||||||
el.totpQr.innerHTML = '';
|
el.totpQr.innerHTML = '';
|
||||||
}
|
}
|
||||||
@ -191,15 +170,13 @@ and ensure every administrator account for this control panel does the same.</st
|
|||||||
function(res) {
|
function(res) {
|
||||||
el.wrapper.classList.add('loaded');
|
el.wrapper.classList.add('loaded');
|
||||||
|
|
||||||
var has_mfa = false;
|
|
||||||
res.enabled_mfa.forEach(function(mfa) {
|
res.enabled_mfa.forEach(function(mfa) {
|
||||||
if (mfa.type == "totp") {
|
if (mfa.type == "totp") {
|
||||||
render_disable(mfa);
|
render_disable(mfa);
|
||||||
has_mfa = true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!has_mfa)
|
if (res.new_mfa.totp)
|
||||||
render_totp_setup(res.new_mfa.totp);
|
render_totp_setup(res.new_mfa.totp);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -212,7 +189,7 @@ and ensure every administrator account for this control panel does the same.</st
|
|||||||
api(
|
api(
|
||||||
'/mfa/disable',
|
'/mfa/disable',
|
||||||
'POST',
|
'POST',
|
||||||
{ type: 'totp' },
|
{ id: $(this).attr('data-mfa-id') },
|
||||||
function() {
|
function() {
|
||||||
do_logout();
|
do_logout();
|
||||||
}
|
}
|
||||||
@ -226,7 +203,7 @@ and ensure every administrator account for this control panel does the same.</st
|
|||||||
hide_error();
|
hide_error();
|
||||||
|
|
||||||
api(
|
api(
|
||||||
'/mfa/totp/enable',
|
'/mfa/enable/totp',
|
||||||
'POST',
|
'POST',
|
||||||
{
|
{
|
||||||
token: $(el.totpSetupToken).val(),
|
token: $(el.totpSetupToken).val(),
|
||||||
|
Loading…
Reference in New Issue
Block a user