diff --git a/backend/database.js b/backend/database.js index 295ff7b..e275f97 100644 --- a/backend/database.js +++ b/backend/database.js @@ -510,17 +510,24 @@ const SettingsDB = { // 邮箱验证管理 const VerificationDB = { - setVerification(userId, token, expiresAt) { + setVerification(userId, token, expiresAtMs) { db.prepare(` UPDATE users SET verification_token = ?, verification_expires_at = ?, is_verified = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ? - `).run(token, expiresAt, userId); + `).run(token, expiresAtMs, userId); }, consumeVerificationToken(token) { const row = db.prepare(` SELECT * FROM users - WHERE verification_token = ? AND verification_expires_at > CURRENT_TIMESTAMP AND is_verified = 0 + WHERE verification_token = ? + AND ( + verification_expires_at IS NULL + OR verification_expires_at = '' + OR verification_expires_at > strftime('%s','now')*1000 -- 数值时间戳(ms) + OR verification_expires_at > CURRENT_TIMESTAMP -- 兼容旧的字符串时间 + ) + AND is_verified = 0 `).get(token); if (!row) return null; @@ -535,16 +542,19 @@ const VerificationDB = { // 密码重置 Token 管理 const PasswordResetTokenDB = { - create(userId, token, expiresAt) { + create(userId, token, expiresAtMs) { db.prepare(` INSERT INTO password_reset_tokens (user_id, token, expires_at, used) VALUES (?, ?, ?, 0) - `).run(userId, token, expiresAt); + `).run(userId, token, expiresAtMs); }, use(token) { const row = db.prepare(` SELECT * FROM password_reset_tokens - WHERE token = ? AND used = 0 AND expires_at > CURRENT_TIMESTAMP + WHERE token = ? AND used = 0 AND ( + expires_at > strftime('%s','now')*1000 -- 数值时间戳 + OR expires_at > CURRENT_TIMESTAMP -- 兼容旧的字符串时间 + ) `).get(token); if (!row) return null; db.prepare(`UPDATE password_reset_tokens SET used = 1 WHERE id = ?`).run(row.id); diff --git a/backend/server.js b/backend/server.js index 7f6b98d..673d673 100644 --- a/backend/server.js +++ b/backend/server.js @@ -815,7 +815,7 @@ app.post('/api/register', } const verifyToken = generateRandomToken(24); - const expiresAt = new Date(Date.now() + 30 * 60 * 1000).toISOString(); // 30分钟 + const expiresAtMs = Date.now() + 30 * 60 * 1000; // 30分钟 // 创建用户(不需要FTP配置),标记未验证 const userId = UserDB.create({ @@ -824,7 +824,7 @@ app.post('/api/register', password, is_verified: 0, verification_token: verifyToken, - verification_expires_at: expiresAt + verification_expires_at: expiresAtMs }); const verifyLink = `${getProtocol(req)}://${req.get('host')}/?verifyToken=${verifyToken}`; @@ -891,8 +891,8 @@ app.post('/api/resend-verification', [ } const verifyToken = generateRandomToken(24); - const expiresAt = new Date(Date.now() + 30 * 60 * 1000).toISOString(); - VerificationDB.setVerification(user.id, verifyToken, expiresAt); + const expiresAtMs = Date.now() + 30 * 60 * 1000; + VerificationDB.setVerification(user.id, verifyToken, expiresAtMs); const verifyLink = `${getProtocol(req)}://${req.get('host')}/?verifyToken=${verifyToken}`; await sendMail( @@ -956,8 +956,8 @@ app.post('/api/password/forgot', [ } const token = generateRandomToken(24); - const expiresAt = new Date(Date.now() + 30 * 60 * 1000).toISOString(); - PasswordResetTokenDB.create(user.id, token, expiresAt); + const expiresAtMs = Date.now() + 30 * 60 * 1000; + PasswordResetTokenDB.create(user.id, token, expiresAtMs); const resetLink = `${getProtocol(req)}://${req.get('host')}/?resetToken=${token}`; await sendMail( diff --git a/frontend/app.html b/frontend/app.html index 7ab7d77..ea534cd 100644 --- a/frontend/app.html +++ b/frontend/app.html @@ -663,6 +663,7 @@