const jwtUtils = require("../utils/jwt-utils"); const logger = require("../utils/logger"); /** * 认证模块 * 处理用户登录、token 刷新等功能 */ /** * 用户登录 * @param {Object} params - 登录参数 { username, password, corpId } * @param {Object} db - 数据库实例 * @returns {Object} 登录结果 */ async function login(params, db) { const { username, password, corpId } = params; if (!username || !password) { return { success: false, message: "用户名和密码不能为空", }; } // 查询用户信息 const user = await db.collection("corp-member").findOne( { corpId, mobile: username } // 查询条件 ); if (!user) { logger.warn(`登录失败: 用户不存在 - ${username}`); return { success: false, message: "用户名或密码错误", }; } // 验证密码(这里假设密码已加密,实际应该使用 bcrypt 等加密算法) if (user.password !== password) { logger.warn(`登录失败: 密码错误 - ${username}`); return { success: false, message: "用户名或密码错误", }; } // 检查用户状态 if (user.status === "disabled") { return { success: false, message: "账号已被禁用", }; } // 生成 token const tokens = jwtUtils.generateTokens({ userId: user._id.toString(), username: user.username, corpId: user.corpId, role: user.role || "user", }); // 更新最后登录时间 await usersCollection.updateOne( { _id: user._id }, { $set: { lastLoginTime: new Date(), lastLoginIp: params.ip || "", }, } ); logger.info(`用户登录成功: ${username}`); return { success: true, message: "登录成功", data: { accessToken: tokens.accessToken, refreshToken: tokens.refreshToken, expiresIn: tokens.expiresIn, tokenType: "Bearer", userInfo: { userId: user._id.toString(), username: user.username, corpId: user.corpId, role: user.role || "user", nickname: user.nickname || user.username, }, }, }; } /** * 刷新 token * @param {Object} params - 刷新参数 { refreshToken } * @returns {Object} 刷新结果 */ async function refreshToken(params) { const { refreshToken } = params; if (!refreshToken) { return { success: false, message: "刷新令牌不能为空", }; } // 验证并生成新的访问令牌 const result = jwtUtils.refreshAccessToken(refreshToken); logger.info("Token 刷新成功"); return { success: true, message: "Token 刷新成功", data: { accessToken: result.accessToken, expiresIn: result.expiresIn, tokenType: "Bearer", }, }; } /** * 退出登录 * @param {Object} params - 参数 * @param {Object} user - 当前用户信息(来自 JWT) * @returns {Object} 退出结果 */ async function logout(params, user) { // 可以在这里实现 token 黑名单机制 // 将当前 token 加入黑名单,使其失效 logger.info(`用户退出登录: ${user.username}`); return { success: true, message: "退出成功", }; } /** * 小程序授权登录(支付宝/微信) * @param {Object} params - 登录参数 { authCode, platform, corpId } * @param {Object} db - 数据库实例 * @returns {Object} 登录结果 */ async function miniProgramLogin(params, db) { const { authCode, platform = "alipay", corpId } = params; if (!authCode) { return { success: false, message: "授权码不能为空", }; } try { // 这里需要调用支付宝/微信的接口获取用户信息 // 由于没有具体的获取用户信息的逻辑,我们假设通过 authCode 可以获取到 userId // 实际项目中,应该调用对应平台的 API 来验证 authCode 并获取用户信息 // 临时方案:使用 authCode 作为用户标识 // 在实际应用中,需要调用支付宝 API: alipay.system.oauth.token const userId = authCode; // 这里应该是从支付宝返回的真实 userId // 查询或创建小程序用户 const usersCollection = db.collection("miniapp_users"); let user = await usersCollection.findOne({ userId, platform, ...(corpId && { corpId }), }); if (!user) { // 首次登录,创建用户记录 const newUser = { userId, platform, corpId: corpId || "", role: "customer", status: "active", createTime: new Date(), lastLoginTime: new Date(), lastLoginIp: params.ip || "", }; const result = await usersCollection.insertOne(newUser); user = { _id: result.insertedId, ...newUser }; logger.info(`小程序新用户注册: ${userId}`); } else { // 更新最后登录时间 await usersCollection.updateOne( { _id: user._id }, { $set: { lastLoginTime: new Date(), lastLoginIp: params.ip || "", }, } ); logger.info(`小程序用户登录: ${userId}`); } // 检查用户状态 if (user.status === "disabled") { return { success: false, message: "账号已被禁用", }; } // 生成 JWT token const tokens = jwtUtils.generateTokens({ userId: user._id.toString(), miniappUserId: user.userId, platform: user.platform, corpId: user.corpId, role: user.role || "customer", }); return { success: true, message: "登录成功", data: { accessToken: tokens.accessToken, refreshToken: tokens.refreshToken, expiresIn: tokens.expiresIn, tokenType: "Bearer", userInfo: { userId: user._id.toString(), miniappUserId: user.userId, platform: user.platform, corpId: user.corpId, role: user.role || "customer", }, }, }; } catch (error) { logger.error("小程序登录失败:", error); return { success: false, message: "登录失败: " + error.message, }; } } /** * 获取当前用户信息 * @param {Object} user - 当前用户信息(来自 JWT) * @param {Object} db - 数据库实例 * @returns {Object} 用户信息 */ async function getCurrentUser(user, db) { // 判断是小程序用户还是普通用户 if (user.miniappUserId) { // 小程序用户 const usersCollection = db.collection("miniapp_users"); const userInfo = await usersCollection.findOne({ _id: require("mongodb").ObjectId.createFromHexString(user.userId), }); if (!userInfo) { return { success: false, message: "用户不存在", }; } return { success: true, data: { userId: userInfo._id.toString(), miniappUserId: userInfo.userId, platform: userInfo.platform, corpId: userInfo.corpId, role: userInfo.role || "customer", status: userInfo.status, createTime: userInfo.createTime, lastLoginTime: userInfo.lastLoginTime, }, }; } else { // 普通用户 const usersCollection = db.collection("users"); const userInfo = await usersCollection.findOne( { _id: require("mongodb").ObjectId.createFromHexString(user.userId) }, { projection: { password: 0 } } // 不返回密码 ); if (!userInfo) { return { success: false, message: "用户不存在", }; } return { success: true, data: { userId: userInfo._id.toString(), username: userInfo.username, corpId: userInfo.corpId, role: userInfo.role || "user", nickname: userInfo.nickname || userInfo.username, email: userInfo.email, phone: userInfo.phone, avatar: userInfo.avatar, status: userInfo.status, createTime: userInfo.createTime, lastLoginTime: userInfo.lastLoginTime, }, }; } } /** * 主路由处理函数 * @param {Object} params - 请求参数 * @param {Object} db - 数据库实例 * @param {Object} user - 当前用户信息(可选) * @returns {Object} 处理结果 */ async function main(params, db, user) { const { type } = params; switch (type) { case "login": return await login(params, db); case "miniProgramLogin": return await miniProgramLogin(params, db); case "refreshToken": return await refreshToken(params); case "logout": if (!user) { return { success: false, message: "未登录" }; } return await logout(params, user); case "getCurrentUser": if (!user) { return { success: false, message: "未登录" }; } return await getCurrentUser(user, db); default: return { success: false, message: "未知的操作类型", }; } } module.exports = { main, login, miniProgramLogin, refreshToken, logout, getCurrentUser, };