const jwt = require('jsonwebtoken') const { sendVerificationCode, verifyCode } = require('../services/auth') const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production' const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '7d' const WHITELIST_CODE = process.env.WHITELIST_CODE || '888888' const WHITELIST_EMAILS = (process.env.WHITELIST_EMAILS || '') .split(',').map(e => e.trim().toLowerCase()).filter(Boolean) function createAuthRoutes(db) { const usersCollection = db.collection('users') return { async sendCode(req, res) { try { const { email } = req.body if (!email) { return res.status(400).json({ success: false, error: '邮箱不能为空' }) } if (WHITELIST_EMAILS.includes(email.toLowerCase())) { return res.json({ success: true, message: '验证码已发送' }) } const result = await sendVerificationCode(db, email.toLowerCase()) if (!result.success) { return res.status(400).json(result) } res.json({ success: true, message: '验证码已发送' }) } catch (err) { console.error('[Auth] Send code error:', err) res.status(500).json({ success: false, error: err.message }) } }, async login(req, res) { try { const { email, code, nickname } = req.body if (!email || !code) { return res.status(400).json({ success: false, error: '邮箱和验证码不能为空' }) } const emailLower = email.toLowerCase() if (WHITELIST_EMAILS.includes(emailLower)) { if (code !== WHITELIST_CODE) { return res.status(400).json({ success: false, error: '验证码错误' }) } } else { const verifyResult = await verifyCode(db, emailLower, code) if (!verifyResult.success) { return res.status(400).json(verifyResult) } } let user = await usersCollection.findOne({ email: emailLower }) if (!user) { const newUser = { email: emailLower, nickname: nickname || emailLower.split('@')[0], avatar: null, created_at: new Date(), updated_at: new Date(), last_login: new Date(), status: 'active' } const result = await usersCollection.insertOne(newUser) user = { ...newUser, _id: result.insertedId } } else { await usersCollection.updateOne( { _id: user._id }, { $set: { last_login: new Date(), updated_at: new Date() } } ) } const token = jwt.sign( { userId: user._id.toString(), email: user.email }, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN } ) res.json({ success: true, token, user: { id: user._id, email: user.email, nickname: user.nickname, avatar: user.avatar, created_at: user.created_at } }) } catch (err) { console.error('[Auth] Login error:', err) res.status(500).json({ success: false, error: err.message }) } }, async verifyToken(req, res, next) { try { const authHeader = req.headers.authorization if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ success: false, error: '未登录' }) } const token = authHeader.split(' ')[1] try { const decoded = jwt.verify(token, JWT_SECRET) const user = await usersCollection.findOne({ _id: new (require('mongodb').ObjectId)(decoded.userId) }) if (!user) { return res.status(401).json({ success: false, error: '用户不存在' }) } req.user = { id: user._id.toString(), email: user.email, nickname: user.nickname, avatar: user.avatar } next() } catch (jwtErr) { return res.status(401).json({ success: false, error: 'Token无效或已过期' }) } } catch (err) { console.error('[Auth] Verify token error:', err) res.status(500).json({ success: false, error: err.message }) } }, async getProfile(req, res) { try { res.json({ success: true, user: req.user }) } catch (err) { console.error('[Auth] Get profile error:', err) res.status(500).json({ success: false, error: err.message }) } }, async updateProfile(req, res) { try { const { nickname, avatar } = req.body const updateData = { updated_at: new Date() } if (nickname) updateData.nickname = nickname if (avatar) updateData.avatar = avatar await usersCollection.updateOne( { _id: new (require('mongodb').ObjectId)(req.user.id) }, { $set: updateData } ) res.json({ success: true, user: { ...req.user, ...updateData } }) } catch (err) { console.error('[Auth] Update profile error:', err) res.status(500).json({ success: false, error: err.message }) } } } } module.exports = { createAuthRoutes }