增强:聊天室内修改绑定邮箱时强制要求邮件验证码校验,并增加 60 秒发送频率限制防滥发机制
This commit is contained in:
@@ -117,9 +117,21 @@
|
||||
</div>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<label style="font-size:12px; width:50px; text-align:right;">邮箱:</label>
|
||||
<input id="set-email" type="email" value="{{ Auth::user()->email ?? '' }}" placeholder="选填"
|
||||
<input id="set-email" type="email" value="{{ Auth::user()->email ?? '' }}"
|
||||
placeholder="用来找回密码(必填)"
|
||||
style="flex:1; padding:5px; border:1px solid #ccc; border-radius:4px; font-size:12px;">
|
||||
</div>
|
||||
@if (\App\Models\SysParam::where('alias', 'smtp_enabled')->value('body') === '1')
|
||||
<div style="display:flex; align-items:center; gap:8px; margin-top:6px;">
|
||||
<label style="font-size:12px; width:50px; text-align:right;">验证码:</label>
|
||||
<input id="set-email-code" type="text" placeholder="修改邮箱时必填" maxlength="6"
|
||||
style="flex:1; padding:5px; border:1px solid #ccc; border-radius:4px; font-size:12px; max-width:100px;">
|
||||
<button id="btn-send-code" type="button" onclick="sendEmailCode()"
|
||||
style="padding:5px 10px; border:1px solid #336699; background:#eef5ff; color:#336699; border-radius:4px; font-size:12px; cursor:pointer;">
|
||||
获取验证码
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -203,6 +215,8 @@
|
||||
const profileData = {
|
||||
sex: document.getElementById('set-sex').value,
|
||||
email: document.getElementById('set-email').value,
|
||||
email_code: document.getElementById('set-email-code') ? document.getElementById('set-email-code')
|
||||
.value : '',
|
||||
question: document.getElementById('set-question').value,
|
||||
answer: document.getElementById('set-answer').value,
|
||||
headface: @json(Auth::user()->usersf ?: '1.gif'),
|
||||
@@ -229,4 +243,71 @@
|
||||
alert('网络异常');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮箱验证码 (带有 60s 倒计时机制防灌水)
|
||||
*/
|
||||
async function sendEmailCode() {
|
||||
const emailInput = document.getElementById('set-email').value.trim();
|
||||
if (!emailInput) {
|
||||
alert('请先填写邮箱地址后再获取验证码!');
|
||||
return;
|
||||
}
|
||||
|
||||
const btn = document.getElementById('btn-send-code');
|
||||
btn.disabled = true;
|
||||
btn.innerText = '正在发送...';
|
||||
btn.style.opacity = '0.6';
|
||||
btn.style.cursor = 'not-allowed';
|
||||
|
||||
try {
|
||||
const res = await fetch('{{ route('user.send_email_code') }}', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: emailInput
|
||||
})
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (res.ok && data.status === 'success') {
|
||||
alert(data.message || '验证码发送成功,请前往邮箱查收!(有效期5分钟)');
|
||||
|
||||
// 开始 60 秒防暴力点击倒计时
|
||||
let count = 60;
|
||||
btn.innerText = count + 's 后重试';
|
||||
const timer = setInterval(() => {
|
||||
count--;
|
||||
if (count <= 0) {
|
||||
clearInterval(timer);
|
||||
btn.innerText = '获取验证码';
|
||||
btn.disabled = false;
|
||||
btn.style.opacity = '1';
|
||||
btn.style.cursor = 'pointer';
|
||||
} else {
|
||||
btn.innerText = count + 's 后重试';
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
} else {
|
||||
alert('发送失败: ' + (data.message || '系统繁忙'));
|
||||
// 失败了立刻解除禁用以重新尝试
|
||||
btn.innerText = '获取验证码';
|
||||
btn.disabled = false;
|
||||
btn.style.opacity = '1';
|
||||
btn.style.cursor = 'pointer';
|
||||
}
|
||||
} catch (e) {
|
||||
alert('网络异常,验证码发送请求失败。');
|
||||
btn.innerText = '获取验证码';
|
||||
btn.disabled = false;
|
||||
btn.style.opacity = '1';
|
||||
btn.style.cursor = 'pointer';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user