迁移邮箱找回密码脚本
This commit is contained in:
@@ -0,0 +1,103 @@
|
|||||||
|
// 邮箱找回密码页交互入口,负责 AJAX 发送重置链接和页面提示。
|
||||||
|
|
||||||
|
let passwordForgotControlsBound = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取 CSRF 令牌,供找回密码请求使用。
|
||||||
|
*
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getCsrfToken() {
|
||||||
|
return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 展示找回密码页面提示。
|
||||||
|
*
|
||||||
|
* @param {string} message
|
||||||
|
* @param {string} type
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function showAlert(message, type) {
|
||||||
|
const alertBox = document.getElementById("alert-box");
|
||||||
|
if (!alertBox) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alertBox.textContent = message;
|
||||||
|
alertBox.className = type === "success" ? "alert alert-success" : "alert alert-error";
|
||||||
|
alertBox.style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交邮箱找回密码请求。
|
||||||
|
*
|
||||||
|
* @param {SubmitEvent} event
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async function submitPasswordRecovery(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const form = event.target;
|
||||||
|
const submitButton = document.getElementById("submit-btn");
|
||||||
|
const alertBox = document.getElementById("alert-box");
|
||||||
|
if (!(form instanceof HTMLFormElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submitButton instanceof HTMLButtonElement) {
|
||||||
|
submitButton.disabled = true;
|
||||||
|
submitButton.innerText = "发送中...";
|
||||||
|
}
|
||||||
|
if (alertBox) {
|
||||||
|
alertBox.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(form.getAttribute("data-password-email-url") ?? form.action, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "same-origin",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-CSRF-TOKEN": getCsrfToken(),
|
||||||
|
Accept: "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(Object.fromEntries(new FormData(form).entries())),
|
||||||
|
});
|
||||||
|
const body = await response.json();
|
||||||
|
|
||||||
|
if (response.status === 200 && body.status === "success") {
|
||||||
|
showAlert(body.message, "success");
|
||||||
|
form.reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const errorMessage = body.message || (body.errors ? Object.values(body.errors)[0][0] : "邮件发送失败,请稍后重试。");
|
||||||
|
showAlert(errorMessage, "error");
|
||||||
|
} catch {
|
||||||
|
showAlert("网络或服务器异常,请稍后再试。", "error");
|
||||||
|
} finally {
|
||||||
|
if (submitButton instanceof HTMLButtonElement) {
|
||||||
|
submitButton.disabled = false;
|
||||||
|
submitButton.innerText = "发送重置邮件";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定邮箱找回密码页提交事件。
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function bindPasswordForgotControls() {
|
||||||
|
if (passwordForgotControlsBound || typeof document === "undefined") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordForgotControlsBound = true;
|
||||||
|
document.getElementById("password-recovery-form")?.addEventListener("submit", (event) => {
|
||||||
|
void submitPasswordRecovery(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bindPasswordForgotControls();
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700;900&family=Noto+Serif+SC:wght@700;900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700;900&family=Noto+Serif+SC:wght@700;900&display=swap" rel="stylesheet">
|
||||||
|
@vite('resources/js/password-forgot.js')
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--bg: #0c0d0c;
|
--bg: #0c0d0c;
|
||||||
@@ -202,7 +203,7 @@
|
|||||||
|
|
||||||
<div id="alert-box" class="alert" aria-live="polite"></div>
|
<div id="alert-box" class="alert" aria-live="polite"></div>
|
||||||
|
|
||||||
<form id="password-recovery-form">
|
<form id="password-recovery-form" data-password-email-url="{{ route('password.email') }}">
|
||||||
<label for="email">绑定邮箱</label>
|
<label for="email">绑定邮箱</label>
|
||||||
<input
|
<input
|
||||||
id="email"
|
id="email"
|
||||||
@@ -232,68 +233,6 @@
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
|
||||||
const form = document.getElementById('password-recovery-form');
|
|
||||||
const submitButton = document.getElementById('submit-btn');
|
|
||||||
const alertBox = document.getElementById('alert-box');
|
|
||||||
|
|
||||||
function showAlert(message, type) {
|
|
||||||
alertBox.textContent = message;
|
|
||||||
alertBox.className = type === 'success' ? 'alert alert-success' : 'alert alert-error';
|
|
||||||
alertBox.style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (form) {
|
|
||||||
form.addEventListener('submit', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
submitButton.disabled = true;
|
|
||||||
submitButton.innerText = '发送中...';
|
|
||||||
alertBox.style.display = 'none';
|
|
||||||
|
|
||||||
const data = Object.fromEntries(new FormData(form).entries());
|
|
||||||
|
|
||||||
fetch('{{ route('password.email') }}', {
|
|
||||||
method: 'POST',
|
|
||||||
credentials: 'same-origin',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
|
||||||
'Accept': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
})
|
|
||||||
.then(function(response) {
|
|
||||||
return response.json().then(function(body) {
|
|
||||||
return {
|
|
||||||
status: response.status,
|
|
||||||
body: body,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function(result) {
|
|
||||||
if (result.status === 200 && result.body.status === 'success') {
|
|
||||||
showAlert(result.body.message, 'success');
|
|
||||||
form.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const errorMessage =
|
|
||||||
result.body.message ||
|
|
||||||
(result.body.errors ? Object.values(result.body.errors)[0][0] : '邮件发送失败,请稍后重试。');
|
|
||||||
|
|
||||||
showAlert(errorMessage, 'error');
|
|
||||||
})
|
|
||||||
.catch(function() {
|
|
||||||
showAlert('网络或服务器异常,请稍后再试。', 'error');
|
|
||||||
})
|
|
||||||
.finally(function() {
|
|
||||||
submitButton.disabled = false;
|
|
||||||
submitButton.innerText = '发送重置邮件';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export default defineConfig({
|
|||||||
"resources/js/effects.js",
|
"resources/js/effects.js",
|
||||||
"resources/js/front.js",
|
"resources/js/front.js",
|
||||||
"resources/js/home-login.js",
|
"resources/js/home-login.js",
|
||||||
|
"resources/js/password-forgot.js",
|
||||||
],
|
],
|
||||||
refresh: true,
|
refresh: true,
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user