my_account_2fa.mako
134 lines
| 5.3 KiB
| application/x-mako
|
MakoHtmlLexer
r5360 | <%namespace name="base" file="/base/base.mako"/> | |||
<div class="panel panel-default"> | ||||
<div class="panel-heading"> | ||||
<h3 class="panel-title">${_('Enable/Disable 2FA for your account')}</h3> | ||||
</div> | ||||
r5368 | ${h.secure_form(h.route_path('my_account_configure_2fa_update'), request=request)} | |||
r5360 | <div class="panel-body"> | |||
<div class="form"> | ||||
<div class="fields"> | ||||
<div class="field"> | ||||
<div class="label"> | ||||
<label>${_('2FA status')}:</label> | ||||
</div> | ||||
<div class="checkboxes"> | ||||
% if c.locked_2fa: | ||||
<span class="help-block">${_('2FA settings cannot be changed here, because 2FA was forced enabled by RhodeCode Administrator.')}</span> | ||||
r5367 | ||||
% else: | ||||
<div class="form-check"> | ||||
<input type="radio" id="2faEnabled" name="2fa_status" value="1" ${'checked=1' if c.state_of_2fa else ''}/> | ||||
<label for="2faEnabled">${_('Enable 2FA')}</label> | ||||
<input type="radio" id="2faDisabled" name="2fa_status" value="0" ${'checked=1' if not c.state_of_2fa else ''} /> | ||||
<label for="2faDisabled">${_('Disable 2FA')}</label> | ||||
</div> | ||||
r5360 | % endif | |||
r5367 | ||||
r5360 | </div> | |||
</div> | ||||
</div> | ||||
<button id="saveBtn" class="btn btn-primary" ${'disabled' if c.locked_2fa else ''}>${_('Save')}</button> | ||||
</div> | ||||
</div> | ||||
r5367 | ${h.end_form()} | |||
r5360 | </div> | |||
r5361 | ||||
r5360 | % if c.state_of_2fa: | |||
r5367 | ||||
% if not c.user_seen_2fa_recovery_codes: | ||||
<div class="panel panel-warning"> | ||||
<div class="panel-heading" id="advanced-archive"> | ||||
<h3 class="panel-title">${_('2FA Recovery codes')} <a class="permalink" href="#advanced-archive"> ¶</a></h3> | ||||
</div> | ||||
<div class="panel-body"> | ||||
<p> | ||||
${_('You have not seen your 2FA recovery codes yet.')} | ||||
${_('Please save them in a safe place, or you will lose access to your account in case of lost access to authenticator app.')} | ||||
</p> | ||||
<br/> | ||||
r5368 | <a href="${request.route_path('my_account_configure_2fa', _query={'show-recovery-codes': 1})}" class="btn btn-primary">${_('Show recovery codes')}</a> | |||
r5367 | </div> | |||
</div> | ||||
% endif | ||||
${h.secure_form(h.route_path('my_account_regenerate_2fa_recovery_codes'), request=request)} | ||||
r5360 | <div class="panel panel-default"> | |||
<div class="panel-heading"> | ||||
<h3 class="panel-title">${_('Regenerate 2FA recovery codes for your account')}</h3> | ||||
</div> | ||||
<div class="panel-body"> | ||||
<form id="2faForm"> | ||||
r5367 | <input type="text" name="totp" placeholder="${_('Verify the code from the app')}" pattern="\d{6}" style="width: 20%"> | |||
<button type="submit" class="btn btn-primary">${_('Verify and generate new codes')}</button> | ||||
r5360 | </form> | |||
</div> | ||||
</div> | ||||
r5367 | ${h.end_form()} | |||
% endif | ||||
r5361 | ||||
r5360 | <script> | |||
r5361 | ||||
r5367 | function showRecoveryCodesPopup() { | |||
r5361 | ||||
SwalNoAnimation.fire({ | ||||
r5367 | title: _gettext('2FA recovery codes'), | |||
html: '<span>Should you ever lose your phone or access to your one time password secret, each of these recovery codes can be used one time each to regain access to your account. Please save them in a safe place, or you will lose access to your account.</span>', | ||||
showCancelButton: false, | ||||
showConfirmButton: true, | ||||
showLoaderOnConfirm: true, | ||||
confirmButtonText: _gettext('Show now'), | ||||
allowOutsideClick: function () { | ||||
!Swal.isLoading() | ||||
}, | ||||
preConfirm: function () { | ||||
var postData = { | ||||
'csrf_token': CSRF_TOKEN | ||||
}; | ||||
return new Promise(function (resolve, reject) { | ||||
$.ajax({ | ||||
type: 'POST', | ||||
data: postData, | ||||
url: pyroutes.url('my_account_show_2fa_recovery_codes'), | ||||
headers: {'X-PARTIAL-XHR': true} | ||||
}) | ||||
.done(function (data) { | ||||
resolve(data); | ||||
}) | ||||
.fail(function (jqXHR, textStatus, errorThrown) { | ||||
var message = formatErrorMessage(jqXHR, textStatus, errorThrown); | ||||
ajaxErrorSwal(message); | ||||
}); | ||||
}) | ||||
} | ||||
r5361 | }) | |||
r5367 | .then(function (result) { | |||
if (result.value) { | ||||
let funcData = {'recoveryCodes': result.value.recovery_codes} | ||||
let recoveryCodesHtml = renderTemplate('recoveryCodes', funcData); | ||||
SwalNoAnimation.fire({ | ||||
allowOutsideClick: false, | ||||
confirmButtonText: _gettext('I Copied the codes'), | ||||
title: _gettext('2FA Recovery Codes'), | ||||
html: recoveryCodesHtml | ||||
}).then(function (result) { | ||||
if (result.isConfirmed) { | ||||
window.location.reload() | ||||
} | ||||
}) | ||||
} | ||||
}) | ||||
r5360 | } | |||
r5367 | % if request.GET.get('show-recovery-codes') == '1' and not c.user_seen_2fa_recovery_codes: | |||
showRecoveryCodesPopup(); | ||||
% endif | ||||
r5360 | </script> | |||