diff --git a/backend/routes/auth.js b/backend/routes/auth.js index 4259e71..7fa3949 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -205,4 +205,40 @@ router.put('/password', authenticate, async (req, res) => { } }); +router.post('/forgot-password', async (req, res) => { + try { + const { email } = req.body; + if (!email) return res.status(400).json({ error: '请输入邮箱' }); + const user = await getRow('SELECT * FROM users WHERE email = ?', [email]); + if (!user) return res.json({ message: '如果邮箱已注册,重置链接已发送' }); + const resetToken = uuid(); + await query("UPDATE users SET reset_token = ?, reset_expires = DATE_ADD(NOW(), INTERVAL 1 HOUR) WHERE id = ?", [resetToken, user.id]); + const site = await getRow("SELECT v FROM settings WHERE k='site_url'"); + await sendEmail(email, 'verify_email', { + username: user.username, game_name: user.game_name, game_uid: user.game_uid, + verify_link: `${site?.v||'http://localhost:3100'}#/reset?token=${resetToken}`, + }); + res.json({ message: '如果邮箱已注册,重置链接已发送' }); + } catch (err) { + console.error('[auth]', err); + res.status(500).json({ error: '服务器内部错误' }); + } +}); + +router.post('/reset-password', async (req, res) => { + try { + const { token, password } = req.body; + if (!token || !password) return res.status(400).json({ error: '参数不完整' }); + if (password.length < 6) return res.status(400).json({ error: '密码至少6位' }); + const user = await getRow("SELECT * FROM users WHERE reset_token = ? AND reset_expires > NOW()", [token]); + if (!user) return res.status(400).json({ error: '重置链接无效或已过期' }); + const hashed = await bcrypt.hash(password, 10); + await query("UPDATE users SET password = ?, reset_token = NULL, reset_expires = NULL WHERE id = ?", [hashed, user.id]); + res.json({ message: '密码重置成功,请登录' }); + } catch (err) { + console.error('[auth]', err); + res.status(500).json({ error: '服务器内部错误' }); + } +}); + module.exports = router; diff --git a/public/index.html b/public/index.html index 517cfa3..7f20a76 100644 --- a/public/index.html +++ b/public/index.html @@ -57,6 +57,7 @@ + diff --git a/public/js/app.js b/public/js/app.js index becf556..caedc7b 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -63,6 +63,7 @@ const App = { if (page === 'install') { this.showPublic('install'); return; } if (page === 'home') { this.showPublic('home', param); return; } if (page === 'login' || page === 'register') { this.showPublic(page); return; } + if (page === 'forgot' || page === 'reset') { this.showPublic(page); return; } if (!Auth.logged()) { location.hash = '#/login'; return; } this.showLayout(); @@ -98,7 +99,7 @@ const App = { const pub = document.getElementById('public-page'); pub.classList.remove('hidden'); this.updateTopAuth(); - const comp = page === 'login' ? LoginPage : page === 'register' ? RegisterPage : page === 'install' ? InstallPage : HomePage; + const comp = page === 'login' ? LoginPage : page === 'register' ? RegisterPage : page === 'install' ? InstallPage : page === 'forgot' ? ForgotPage : page === 'reset' ? ResetPage : HomePage; comp.render(param).then(html => { pub.innerHTML = html; if (comp.mount) comp.mount(param); }).catch(() => { pub.innerHTML = '
请刷新页面重试
输入注册邮箱获取重置链接
重置链接无效
请输入新密码
登录您的账号