##// END OF EJS Templates
fix(caching): fixed problems with Cache query for users....
fix(caching): fixed problems with Cache query for users. The old way of querying caused the user get query to be always cached, and returning old results even in 2fa forms. The new limited query doesn't cache the user object resolving issues

File last commit:

r5360:4cbf1ad2 default
r5365:ae8a165b default
Show More
configure_2fa.mako
153 lines | 5.8 KiB | application/x-mako | MakoHtmlLexer
<%inherit file="base/root.mako"/>
<%def name="title()">
${_('Setup authenticator app')}
%if c.rhodecode_name:
&middot; ${h.branding(c.rhodecode_name)}
%endif
</%def>
<style>body{background-color:#eeeeee;}</style>
<div class="loginbox">
<div class="header-account">
<div id="header-inner" class="title">
<div id="logo">
% if c.rhodecode_name:
<div class="branding">
<a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
</div>
% endif
</div>
</div>
</div>
<div class="loginwrapper">
<h1>Setup the authenticator app</h1>
<p>Authenticator apps like <a href='https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2' target="_blank" rel="noopener noreferrer">Google Authenticator</a>, etc. generate one-time passwords that are used as a second factor to verify you identity.</p>
<rhodecode-toast id="notifications"></rhodecode-toast>
<div id="setup_2fa">
<div class="sign-in-title">
<h1>${_('Scan the QR code')}</h1>
</div>
<p>Use an authenticator app to scan.</p>
<img src="data:image/png;base64, ${qr}"/>
<p>${_('Unable to scan?')} <a id="toggleLink">${_('Click here')}</a></p>
<div id="secretDiv" class="hidden">
<p>${_('Copy and use this code to manually setup an authenticator app')}</p>
<input type="text" id="secretField" value=${key}>
<i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="" title="${_('Copy the secret key')}"></i>
</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>
<br><br>
<div id="verify_2fa">
${h.secure_form(h.route_path('setup_2fa'), request=request, id='totp_form')}
<div class="form mt-4">
<div class="field">
<p>
<div class="label">
<label for="totp" class="form-label text-dark font-weight-bold" style="text-align: left;">${_('Verify the code from the app')}:</label>
</div>
</p>
<p>
<div>
<div class="input-group">
${h.text('totp', class_='form-control', style='width: 40%;')}
<div id="formErrors">
%if 'totp' in errors:
<span class="error-message">${errors.get('totp')}</span>
<br />
%endif
</div>
<div class="input-group-append">
${h.submit('save',_('Verify'),class_="btn btn-primary", style='width: 40%;', disabled=not codes_viewed)}
</div>
</div>
</div>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
let clipboardIcons = document.querySelectorAll('.clipboard-action');
clipboardIcons.forEach(function(icon) {
icon.addEventListener('click', function() {
var inputField = document.getElementById('secretField');
inputField.select();
document.execCommand('copy');
});
});
});
</script>
<script>
document.getElementById('toggleLink').addEventListener('click', function() {
let hiddenField = document.getElementById('secretDiv');
if (hiddenField.classList.contains('hidden')) {
hiddenField.classList.remove('hidden');
}
});
</script>
<script>
const recovery_codes_string = '${recovery_codes}';
const cleaned_recovery_codes_string = recovery_codes_string
.replace(/&#34;/g, '"')
.replace(/&#39;/g, "'");
const recovery_codes = JSON.parse(cleaned_recovery_codes_string);
const cleaned_recovery_codes = recovery_codes.map(code => code.replace(/['"]/g, ''));
function showRecoveryCodesPopup() {
const popup = document.getElementById("codesPopup");
const codesList = document.getElementById("recoveryCodesList");
const verify_btn = document.getElementById('save')
if (verify_btn.disabled) {
codesList.innerHTML = "";
cleaned_recovery_codes.forEach(code => {
const listItem = document.createElement("li");
listItem.textContent = code;
codesList.appendChild(listItem);
});
popup.style.display = "block";
verify_btn.disabled = false;
}
}
document.getElementById("save").addEventListener("mouseover", showRecoveryCodesPopup);
const popup = document.getElementById("codesPopup");
const closeButton = document.querySelector(".close");
window.onclick = function(event) {
if (event.target === popup || event.target === closeButton) {
popup.style.display = "none";
}
}
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);
});
</script>