Add resend verification link on login + rate limit (3/15min)
This commit is contained in:
parent
d073f398d8
commit
230a73be3a
3 changed files with 43 additions and 0 deletions
|
|
@ -51,6 +51,10 @@
|
||||||
<input type="text" id="login-totp" placeholder="6-digit code" maxlength="6">
|
<input type="text" id="login-totp" placeholder="6-digit code" maxlength="6">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn-auth">Sign In</button>
|
<button type="submit" class="btn-auth">Sign In</button>
|
||||||
|
<div id="resend-verify-box" class="hidden" style="margin:12px 0;padding:12px;background:#fef3c7;border-radius:8px;text-align:center;">
|
||||||
|
<p style="margin:0 0 8px;font-size:13px;color:#92400e;">Your email is not verified yet.</p>
|
||||||
|
<a href="#" id="resend-verify-link" style="font-size:13px;font-weight:600;color:#2563eb;">Resend verification link</a>
|
||||||
|
</div>
|
||||||
<div class="auth-links">
|
<div class="auth-links">
|
||||||
<a href="#" id="show-register" style="display:none">Create account</a>
|
<a href="#" id="show-register" style="display:none">Create account</a>
|
||||||
<a href="#" id="show-forgot">Forgot password?</a>
|
<a href="#" id="show-forgot">Forgot password?</a>
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.needsVerification) {
|
if (data.needsVerification) {
|
||||||
|
var resendBox = document.getElementById('resend-verify-box');
|
||||||
|
if (resendBox) resendBox.className = resendBox.className.replace('hidden', '').trim();
|
||||||
showToast('Verify your email first. Check inbox.', 'error');
|
showToast('Verify your email first. Check inbox.', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -308,6 +310,38 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- RESEND VERIFICATION LINK ----
|
||||||
|
var resendLink = document.getElementById('resend-verify-link');
|
||||||
|
if (resendLink) {
|
||||||
|
resendLink.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var email = document.getElementById('login-email').value.trim();
|
||||||
|
if (!email) { showToast('Enter your email first', 'error'); return; }
|
||||||
|
resendLink.style.pointerEvents = 'none';
|
||||||
|
resendLink.textContent = 'Sending...';
|
||||||
|
fetch('/api/auth/resend-verification', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ email: email })
|
||||||
|
})
|
||||||
|
.then(function(r) { return r.json(); })
|
||||||
|
.then(function(data) {
|
||||||
|
resendLink.style.pointerEvents = '';
|
||||||
|
resendLink.textContent = 'Resend verification link';
|
||||||
|
if (data.error) {
|
||||||
|
showToast(data.error, 'error');
|
||||||
|
} else {
|
||||||
|
showToast('Verification email sent! Check your inbox.', 'success');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
resendLink.style.pointerEvents = '';
|
||||||
|
resendLink.textContent = 'Resend verification link';
|
||||||
|
showToast('Connection error', 'error');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---- REGISTER FORM SUBMIT ----
|
// ---- REGISTER FORM SUBMIT ----
|
||||||
if (registerForm) {
|
if (registerForm) {
|
||||||
registerForm.addEventListener('submit', function(e) {
|
registerForm.addEventListener('submit', function(e) {
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,11 @@ app.use('/api/auth/forgot-password', rateLimit({
|
||||||
message: { error: 'Too many password reset attempts.' },
|
message: { error: 'Too many password reset attempts.' },
|
||||||
standardHeaders: true, legacyHeaders: false
|
standardHeaders: true, legacyHeaders: false
|
||||||
}));
|
}));
|
||||||
|
app.use('/api/auth/resend-verification', rateLimit({
|
||||||
|
windowMs: 15 * 60 * 1000, max: 3,
|
||||||
|
message: { error: 'Too many verification requests. Try again in 15 minutes.' },
|
||||||
|
standardHeaders: true, legacyHeaders: false
|
||||||
|
}));
|
||||||
|
|
||||||
app.use(loggingMiddleware);
|
app.use(loggingMiddleware);
|
||||||
app.use(express.static(path.join(__dirname, 'public'), {
|
app.use(express.static(path.join(__dirname, 'public'), {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue