const express = require('express'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const router = express.Router(); const authMiddleware = require('../middleware/authMiddleware'); const User = require('../models/User'); const Logs = require('../libs/logs'); // 注册 router.post('/register', async (req, res) => { const { username, password } = req.body; User.findOne({ username }) .then(existing => { if (existing) { return Promise.reject(new Error('USER_EXISTS')); } return bcrypt.hash(password, 10); }) .then(hashedPassword => { const user = new User({ username, password: hashedPassword }); return user.save(); }) .then(() => { res.sendSuccess('注册成功'); }) .catch(err => { Logs.errDev('注册失败:', err); if (err.message === 'USER_EXISTS') { return res.badRequest('用户已存在'); } res.badRequest(err.message); }); }); // 登录 - 支持原路径 /login 和 mock 服务路径 /login router.post('/login', async (req, res) => { const { username, password } = req.body; User.findOne({ username }) .then(user => { if (!user) { return Promise.reject(new Error('USER_NOT_FOUND')); } return Promise.all([ bcrypt.compare(password, user.password), Promise.resolve(user), ]); }) .then(([isMatch, user]) => { if (!isMatch) { return Promise.reject(new Error('PASSWORD_ERROR')); } return user; }) .then(user => { // 签发 Access Token 和 Refresh Token const accessToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '30m' }); const refreshToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '7d' }); // 设置 refresh token 到 cookie res.cookie('jwt', refreshToken, { httpOnly: true, secure: true, sameSite: 'none', maxAge: 7 * 24 * 60 * 60 * 1000 // 7天 }); // 返回格式与前端期望一致 res.sendSuccess({ accessToken: accessToken, uid: user._id.toString(), username: user.username, roles: user.roles ?? ['user'], }); }) .catch(err => { Logs.errDev('登录失败:', err); if (err.message === 'USER_NOT_FOUND') { return res.badRequest('用户不存在'); } if (err.message === 'PASSWORD_ERROR') { return res.badRequest('密码错误'); } res.badRequest(err.message); }); }); // 刷新 Token - 支持 Vben Admin 的 /refresh 路径 router.post('/refresh', async (req, res) => { const refreshToken = req.cookies.jwt; if (!refreshToken) { return res.unauthorized('无效的刷新token'); } const decoded = jwt.verify(refreshToken, process.env.JWT_SECRET); User.findById(decoded.userId) .then(user => { if (!user) { return Promise.reject(new Error('USER_NOT_FOUND')); } // 签发新的 Access Token const newAccessToken = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: '30m' }); // 按照Vben Admin期望的格式返回 res.send(newAccessToken); }) .catch(err => { Logs.errDev('刷新Token失败:', err); res.clearCookie('jwt'); if (err.message === 'USER_NOT_FOUND') { return res.unauthorized('用户不存在'); } res.unauthorized(err.message); }); }); // 用户信息 - 支持 mock 服务的 /info 路径 router.get('/info', authMiddleware, async (req, res) => { User.findById(req.userId).select('-password') .then(user => { if (!user) { return Promise.reject(new Error('USER_NOT_FOUND')); } const userInfo = { uid: user._id.toString(), username: user.username, roles: user.roles ?? ['user'], }; res.sendSuccess(userInfo); }) .catch(err => { Logs.errDev('获取用户信息错误:', err); if (err.message === 'USER_NOT_FOUND') { return res.notFound('用户不存在'); } res.serverError(err.message); }); }); // 权限码 - 支持 mock 服务的 /codes 路径 router.get('/codes', authMiddleware, async (req, res) => { try { // 返回所有功能的权限码 const codes = [ 'dashboard', 'dashboard:analysis', 'dashboard:workbench', 'system', 'system:account', 'system:account:settings', 'system:role', 'system:menu', 'system:dept', ]; res.sendSuccess(codes); } catch (err) { Logs.errDev('获取权限码错误:', err); res.serverError(err.message); } }); module.exports = router;