##// END OF EJS Templates
feat(2fa): Added 2fa option. Fixes: RCCE-65
feat(2fa): Added 2fa option. Fixes: RCCE-65

File last commit:

r5360:4cbf1ad2 default
r5360:4cbf1ad2 default
Show More
my_account_2fa.mako
140 lines | 5.3 KiB | application/x-mako | MakoHtmlLexer
<%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>
<div class="panel-body">
<div class="form">
<div class="fields">
<div class="field">
<div class="label">
<label>${_('2FA status')}:</label>
</div>
<div class="checkboxes">
<div class="form-check">
<label class="form-check-label">
<input type="radio" id="2faEnabled" value="1" ${'checked' if c.state_of_2fa else ''}>
${_('Enabled')}
</label>
<label class="form-check-label">
<input type="radio" id="2faDisabled" value="0" ${'checked' if not c.state_of_2fa else ''}>
${_('Disabled')}
</label>
</div>
% if c.locked_2fa:
<span class="help-block">${_('2FA settings cannot be changed here, because 2FA was forced enabled by RhodeCode Administrator.')}</span>
% endif
</div>
</div>
</div>
<button id="saveBtn" class="btn btn-primary" ${'disabled' if c.locked_2fa else ''}>${_('Save')}</button>
</div>
<div id="codesPopup" class="modal">
<div class="modal-content">
<ul id="recoveryCodesList"></ul>
<button id="copyAllBtn" class="btn btn-primary">Copy All</button>
</div>
</div>
</div>
</div>
% if c.state_of_2fa:
<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">
<input type="text" name="totp" placeholder="${_('Verify the code from the app')}" pattern="\d{6}"
style="width: 20%">
<button type="button" class="btn btn-primary" onclick="submitForm()">Verify</button>
</form>
<div id="result"></div>
</div>
</div>
% endif
<script>
function submitForm() {
let formData = new FormData(document.getElementById("2faForm"));
let xhr = new XMLHttpRequest();
let success = function (response) {
let recovery_codes = response.recovery_codes;
const codesList = document.getElementById("recoveryCodesList");
codesList.innerHTML = "";
recovery_codes.forEach(code => {
const listItem = document.createElement("li");
listItem.textContent = code;
codesList.appendChild(listItem);
});
}
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
let responseDoc = new DOMParser().parseFromString(xhr.responseText, "text/html");
let contentToDisplay = responseDoc.querySelector('#formErrors');
if (contentToDisplay) {
document.getElementById("result").innerHTML = contentToDisplay.innerHTML;
} else {
let regenerate_url = pyroutes.url('my_account_regenerate_2fa_recovery_codes');
ajaxPOST(regenerate_url, {'csrf_token': CSRF_TOKEN}, success);
showRecoveryCodesPopup();
}
}
};
let url = pyroutes.url('check_2fa');
xhr.open("POST", url, true);
xhr.send(formData);
}
</script>
<script>
document.getElementById('2faEnabled').addEventListener('click', function () {
document.getElementById('2faDisabled').checked = false;
});
document.getElementById('2faDisabled').addEventListener('click', function () {
document.getElementById('2faEnabled').checked = false;
});
function getStateValue() {
if (document.getElementById('2faEnabled').checked) {
return '1';
} else {
return '0';
}
};
function saveChanges(state) {
let post_data = {'state': state, 'csrf_token': CSRF_TOKEN};
let url = pyroutes.url('my_account_configure_2fa');
ajaxPOST(url, post_data, null)
};
document.getElementById('saveBtn').addEventListener('click', function () {
var state = getStateValue();
saveChanges(state);
});
</script>
<script>
function showRecoveryCodesPopup() {
const popup = document.getElementById("codesPopup");
popup.style.display = "block";
}
document.getElementById("copyAllBtn").addEventListener("click", function () {
const codesListItems = document.querySelectorAll("#recoveryCodesList li");
const allCodes = Array.from(codesListItems).map(item => item.textContent).join(", ");
const textarea = document.createElement('textarea');
textarea.value = allCodes;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
const popup = document.getElementById("codesPopup");
popup.style.display = ""
});
</script>