diff --git a/public/index.html b/public/index.html
index 29870dd..9c0257a 100644
--- a/public/index.html
+++ b/public/index.html
@@ -51,6 +51,10 @@
+
Create account
Forgot password?
diff --git a/public/js/auth.js b/public/js/auth.js
index ad240cd..e5003a6 100644
--- a/public/js/auth.js
+++ b/public/js/auth.js
@@ -287,6 +287,8 @@ document.addEventListener('DOMContentLoaded', function() {
}
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');
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 ----
if (registerForm) {
registerForm.addEventListener('submit', function(e) {
diff --git a/server.js b/server.js
index 8c2fe29..4d488a7 100644
--- a/server.js
+++ b/server.js
@@ -82,6 +82,11 @@ app.use('/api/auth/forgot-password', rateLimit({
message: { error: 'Too many password reset attempts.' },
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(express.static(path.join(__dirname, 'public'), {