Replace password reset with email OTP verification flow. Add auth_otp module, OTP templates, and email delivery. Expand styleguide CSS with full component library. Rework login, register, and admin views for cookie sessions. Remove legacy 2FA templates and password reset flow. Update SSH wrappers, forms, validators, and middleware.
65 lines
2.3 KiB
Mako
65 lines
2.3 KiB
Mako
<%inherit file="base/root.mako"/>
|
|
|
|
<%def name="title()">
|
|
${_('Confirm Your Identity')}
|
|
%if c.rhodecode_name:
|
|
· ${h.branding(c.rhodecode_name)}
|
|
%endif
|
|
</%def>
|
|
|
|
<div class="loginbox">
|
|
<div class="header-account">
|
|
<div id="header-inner" class="title">
|
|
<div id="logo">
|
|
<div class="logo-wrapper">
|
|
<a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
|
|
</div>
|
|
% if c.rhodecode_name:
|
|
<div class="branding">
|
|
<a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
|
|
</div>
|
|
% endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<rhodecode-toast id="notifications"></rhodecode-toast>
|
|
|
|
<div class="loginwrapper">
|
|
<div class="auth-image-wrapper">
|
|
<img class="sign-in-image" src="${h.asset('images/sign-in.png')}" alt="RhodeCode"/>
|
|
</div>
|
|
|
|
<div id="login">
|
|
<div class="sign-in-title">
|
|
<h1>${_('Confirm your identity')}</h1>
|
|
<h4>${_('This action requires elevated verification. We sent an 8-digit code to your email.')}</h4>
|
|
</div>
|
|
<div class="inner form">
|
|
${h.form(request.route_path('sudo_otp_verify'), needs_csrf_token=True)}
|
|
|
|
<label for="otp">${_('Verification code')}:</label>
|
|
${h.text('otp', class_='focus', inputmode='numeric', autocomplete='one-time-code', maxlength='8', value=defaults.get('otp', ''))}
|
|
%if 'otp' in errors:
|
|
<span class="error-message">${errors.get('otp')}</span>
|
|
<br />
|
|
%endif
|
|
|
|
<p class="help-block">
|
|
${_('Enter the 8-digit code sent to your email. It expires in 5 minutes.')}
|
|
</p>
|
|
|
|
${h.submit('verify', _('Verify'), class_="btn sign-in")}
|
|
|
|
${h.end_form()}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var otpInput = document.querySelector('input[name="otp"]');
|
|
if (otpInput) otpInput.focus();
|
|
});
|
|
</script>
|
|
|