mira-app-server
Version:
Mira Server - standalone server application using mira-app-core
346 lines • 13.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthRouter = void 0;
const express_1 = require("express");
const UserStorage_1 = require("../UserStorage");
class AuthService {
constructor(dataDir = './data') {
this.userStorage = new UserStorage_1.UserStorage(dataDir);
}
async initialize() {
return this.userStorage.initialize();
}
// 验证用户凭据
async authenticateUser(username, password) {
return await this.userStorage.authenticateUser(username, password);
}
// 生成令牌
async generateToken(userId) {
return await this.userStorage.createSession(userId);
}
// 验证令牌
async validateToken(token) {
return await this.userStorage.validateSession(token);
}
// 撤销令牌
async revokeToken(token) {
return await this.userStorage.revokeSession(token);
}
// 获取用户信息(不包含密码)
getUserInfo(user) {
return this.userStorage.getUserInfo(user);
}
// 清理过期令牌
async cleanupExpiredTokens() {
return await this.userStorage.cleanupExpiredSessions();
}
async close() {
await this.userStorage.close();
}
getUserStorage() {
return this.userStorage;
}
}
class AuthRouter {
constructor(dataDir = './data') {
this.router = (0, express_1.Router)();
this.authService = new AuthService(dataDir);
this.setupRoutes();
// 每小时清理一次过期令牌
setInterval(async () => {
try {
const cleaned = await this.authService.cleanupExpiredTokens();
if (cleaned > 0) {
console.log(`🧹 清理了 ${cleaned} 个过期会话`);
}
}
catch (error) {
console.error('清理过期会话时出错:', error);
}
}, 60 * 60 * 1000);
}
async initialize() {
return this.authService.initialize();
}
setupRoutes() {
// 获取权限码路由 - 符合vben框架标准
this.router.get('/codes', async (req, res) => {
try {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
code: 401,
message: '未提供认证令牌',
data: []
});
}
const authService = this.getAuthService();
const user = await authService.validateToken(token);
if (user) {
// 根据用户角色返回权限码
let accessCodes = [];
if (user.role === 'super') {
// 超级管理员拥有所有权限
accessCodes = [
'AC_100100', // 超级管理员权限
'AC_100010', // 资源库管理权限
'AC_100020', // 用户管理权限
'AC_100030', // 系统设置权限
'AC_200000', // 数据库访问权限
'AC_300000', // 设备管理权限
'AC_400000', // 文件管理权限
];
}
else if (user.role === 'admin') {
// 管理员权限
accessCodes = [
'AC_100100', // 系统管理权限
'AC_100010', // 资源库管理权限
'AC_100020', // 用户管理权限
'AC_200000', // 数据库访问权限
'AC_300000', // 设备管理权限
];
}
else if (user.role === 'user') {
// 普通用户权限
accessCodes = [
'AC_000100', // 基础用户权限
];
}
res.json({
code: 0,
message: '获取权限码成功',
data: accessCodes
});
}
else {
res.status(401).json({
code: 401,
message: '无效或过期的认证令牌',
data: []
});
}
}
catch (error) {
console.error('Get access codes error:', error);
res.status(500).json({
code: 500,
message: '服务器内部错误',
data: []
});
}
});
// 注册路由
this.router.post('/register', async (req, res) => {
try {
const { username, password, email } = req.body;
console.log('📝 Register attempt:', { username, email, passwordLength: password?.length });
// 验证输入
if (!username || !password) {
return res.status(400).json({
code: 400,
message: '用户名和密码不能为空',
data: null
});
}
// 检查用户名是否已存在
const userStorage = this.authService.getUserStorage();
const existingUser = await userStorage.findUserByUsername(username);
if (existingUser) {
return res.status(409).json({
code: 409,
message: '用户名已存在',
data: null
});
}
// 创建新用户
const hashedPassword = userStorage.hashPassword(password);
const now = Date.now();
const newUser = {
username,
password: hashedPassword,
email: email || null,
role: 'user',
permissions: ['basic'],
created_at: now,
updated_at: now,
is_active: true
};
const userId = await userStorage.createUser(newUser);
// 生成令牌
const token = await this.authService.generateToken(userId);
// 符合vben框架标准的返回格式
res.status(201).json({
code: 0,
message: '注册成功',
data: {
accessToken: token,
user: {
id: userId,
username,
email,
role: 'user'
}
}
});
console.log(`✅ User ${username} registered successfully with ID: ${userId}`);
}
catch (error) {
console.error('Register error:', error);
res.status(500).json({
code: 500,
message: '服务器内部错误',
data: null
});
}
});
// 登录路由
this.router.post('/login', async (req, res) => {
try {
const { username, password } = req.body;
console.log('📝 Login attempt:', { username, passwordLength: password?.length });
if (!username || !password) {
return res.status(400).json({
code: 400,
message: '用户名和密码不能为空',
data: null
});
}
const user = await this.authService.authenticateUser(username, password);
if (user) {
const token = await this.authService.generateToken(user.id);
const userInfo = this.authService.getUserInfo(user);
res.json({
code: 0,
message: '登录成功',
data: {
accessToken: token,
user: userInfo
}
});
console.log(`✅ User ${username} logged in successfully`);
}
else {
res.status(401).json({
code: 401,
message: '用户名或密码错误',
data: null
});
console.log(`❌ Failed login attempt for username: ${username}`);
}
}
catch (error) {
console.error('Login error:', error);
res.status(500).json({
code: 500,
message: '服务器内部错误',
data: null
});
}
});
// 登出路由
this.router.post('/logout', async (req, res) => {
try {
const token = req.headers.authorization?.replace('Bearer ', '');
if (token) {
const revoked = await this.authService.revokeToken(token);
console.log(`🔓 Token ${revoked ? 'successfully' : 'failed to'} revoked`);
}
res.json({
success: true,
message: '退出成功'
});
}
catch (error) {
console.error('Logout error:', error);
res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
});
// 验证令牌路由(用于中间件)
this.router.get('/verify', async (req, res) => {
try {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
message: '未提供认证令牌',
code: 'NO_TOKEN'
});
}
const user = await this.authService.validateToken(token);
if (user) {
res.json({
success: true,
message: '令牌有效',
data: {
user: this.authService.getUserInfo(user)
}
});
}
else {
res.status(401).json({
success: false,
message: '无效或过期的认证令牌',
code: 'INVALID_TOKEN'
});
}
}
catch (error) {
console.error('Token verification error:', error);
res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
});
}
// 认证中间件
authMiddleware() {
return async (req, res, next) => {
try {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
message: '未提供认证令牌',
code: 'NO_TOKEN'
});
}
const user = await this.authService.validateToken(token);
if (user) {
// 将用户信息添加到请求对象中
req.user = this.authService.getUserInfo(user);
next();
}
else {
res.status(401).json({
success: false,
message: '无效或过期的认证令牌',
code: 'INVALID_TOKEN'
});
}
}
catch (error) {
console.error('Auth middleware error:', error);
res.status(500).json({
success: false,
message: '认证服务错误'
});
}
};
}
getRouter() {
return this.router;
}
getAuthService() {
return this.authService;
}
getUserStorage() {
return this.authService.getUserStorage();
}
}
exports.AuthRouter = AuthRouter;
//# sourceMappingURL=AuthRouter.js.map