diff --git a/backend/routes/auth.js b/backend/routes/auth.js index acb40dd..6def71f 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -47,18 +47,17 @@ router.post('/register', validateLengths({ } const hashed = await bcrypt.hash(password, 10); - const verifyToken = uuid(); - const verifyExpires = new Date(Date.now() + 24 * 3600 * 1000).toISOString().replace('T', ' ').slice(0, 19); + const verifyCode = String(Math.floor(100000 + Math.random() * 900000)); + const verifyExpires = new Date(Date.now() + 30 * 60000).toISOString().replace('T', ' ').slice(0, 19); await query( 'INSERT INTO users(username, password, email, game_name, game_uid, active, email_verified, verify_token, verify_expires, source) VALUES (?,?,?,?,?,?,?,?,?,?)', - [username, hashed, email, game_name, game_uid, 0, 0, verifyToken, verifyExpires, source || 'netease'] + [username, hashed, email, game_name, game_uid, 0, 0, verifyCode, verifyExpires, source || 'netease'] ); - const siteUrl = await getSiteUrl(); const sent = await sendEmail(email, 'verify_email', { username, game_name, game_uid, - verify_link: `${siteUrl}#/verify?token=${verifyToken}`, + verify_link: verifyCode, }); if (!sent) { @@ -73,19 +72,16 @@ router.post('/register', validateLengths({ } }); -router.get('/verify-email', async (req, res) => { +router.post('/verify-email', async (req, res) => { try { - const { token } = req.query; - if (!token) return res.status(400).json({ error: '无效的验证链接' }); + const { code } = req.body; + if (!code) return res.status(400).json({ error: '请输入验证码' }); - const user = await getRow('SELECT * FROM users WHERE verify_token = ? AND verify_expires > NOW()', [token]); - if (!user) return res.status(400).json({ error: '验证链接无效或已过期' }); + const user = await getRow('SELECT * FROM users WHERE verify_token = ? AND verify_expires > NOW()', [code]); + if (!user) return res.status(400).json({ error: '验证码无效或已过期' }); await query('UPDATE users SET email_verified = 1, active = 1, verify_token = NULL, verify_expires = NULL WHERE id = ?', [user.id]); - await query( - 'INSERT INTO audit_logs(user_id, username, action, entity_type, entity_id, details) VALUES (?,?,?,?,?,?)', - [user.id, user.username, 'verify_email', 'user', user.id, '邮箱验证通过'] - ); + await query('INSERT INTO audit_logs(user_id, username, action, entity_type, entity_id, details) VALUES (?,?,?,?,?,?)', [user.id, user.username, 'verify_email', 'user', user.id, '邮箱验证通过']); res.json({ message: '邮箱验证成功,现在可以登录了' }); } catch (err) { @@ -93,6 +89,7 @@ router.get('/verify-email', async (req, res) => { res.status(500).json({ error: '服务器内部错误' }); } }); +}); router.post('/login', async (req, res) => { try { diff --git a/public/index.html b/public/index.html index c92f265..74d7ecf 100644 --- a/public/index.html +++ b/public/index.html @@ -57,6 +57,8 @@ + + diff --git a/public/js/app.js b/public/js/app.js index 76489e5..dc8fffe 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -62,17 +62,13 @@ const App = { const param = parts.slice(1).join('/'); if (page === 'verify') { - const params = new URLSearchParams((location.hash.split('?')[1] || '')); - const token = params.get('token'); - if (token) { - API.get(`/auth/verify-email?token=${token}`).then(r => { alert(r.message || '验证成功'); location.hash = '#/login'; }).catch(e => { alert(e.message); location.hash = '#/home'; }); - } + this.showPublic('verify'); return; } 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 === 'login' || page === 'register' || page === 'forgot' || page === 'reset') { this.showPublic(page); return; } if (!Auth.logged()) { location.hash = '#/login'; return; } this.showLayout(); @@ -184,6 +180,9 @@ window.LoginPage = LoginPage; window.RegisterPage = RegisterPage; window.HomePage = HomePage; window.InstallPage = InstallPage; +window.ForgotPage = ForgotPage; +window.ResetPage = ResetPage; +window.VerifyPage = VerifyPage; window.U = U; window.Auth = Auth; window.API = API; diff --git a/public/js/pages/verify.js b/public/js/pages/verify.js new file mode 100644 index 0000000..704a779 --- /dev/null +++ b/public/js/pages/verify.js @@ -0,0 +1,26 @@ +const VerifyPage = { + async render() { + return `
+
+ +
+
返回登录
+
`; + }, + mount() { + document.getElementById('verify-form').addEventListener('submit', async e => { + e.preventDefault(); + const code = document.getElementById('vf-code').value.trim(); + const msg = document.getElementById('vf-msg'); + try { + const r = await API.post('/auth/verify-email', { code }); + msg.className = 'alert alert-s'; msg.textContent = r.message || '验证成功'; + msg.classList.remove('hidden'); + setTimeout(() => location.hash = '#/login', 2000); + } catch(ex) { + msg.className = 'alert alert-e'; msg.textContent = ex.message; + msg.classList.remove('hidden'); + } + }); + } +};