فهرست منبع

🗑️ chore(auth): remove auth-core package

- 删除auth-core包及其所有相关文件
- 移除认证核心服务、JWT服务及单元测试
- 删除package.json和tsconfig.json配置文件
yourname 4 هفته پیش
والد
کامیت
e853d9b462

+ 0 - 32
packages/auth-core/package.json

@@ -1,32 +0,0 @@
-{
-  "name": "@d8d/auth-core",
-  "version": "1.0.0",
-  "type": "module",
-  "description": "D8D Authentication Core Services",
-  "main": "src/index.ts",
-  "types": "src/index.ts",
-  "exports": {
-    ".": {
-      "import": "./src/index.ts",
-      "require": "./src/index.ts",
-      "types": "./src/index.ts"
-    }
-  },
-  "scripts": {
-    "typecheck": "tsc --noEmit",
-    "test": "vitest",
-    "test:unit": "vitest run tests/unit"
-  },
-  "dependencies": {
-    "@d8d/shared-types": "workspace:*",
-    "jsonwebtoken": "^9.0.2",
-    "bcrypt": "^6.0.0"
-  },
-  "devDependencies": {
-    "typescript": "^5.8.3",
-    "vitest": "^3.2.4"
-  },
-  "files": [
-    "src"
-  ]
-}

+ 0 - 115
packages/auth-core/src/auth.service.ts

@@ -1,115 +0,0 @@
-import debug from 'debug';
-import { JWTService, JWTPayload } from './jwt.service.js';
-import { EnableStatus } from '@d8d/shared-types';
-
-const logger = {
-  info: debug('auth-core:auth:info'),
-  error: debug('auth-core:auth:error')
-}
-
-export interface User {
-  id: number;
-  username: string;
-  nickname?: string;
-  isDisabled: EnableStatus;
-  roles?: Array<{ name: string }>;
-  openid?: string;
-}
-
-export interface UserService {
-  getUserByUsername(username: string): Promise<User | null>;
-  verifyPassword(user: User, password: string): Promise<boolean>;
-  createUser(userData: Partial<User> & { username: string; password: string }): Promise<User>;
-}
-
-export class AuthService {
-  private userService: UserService;
-
-  constructor(userService: UserService) {
-    this.userService = userService;
-  }
-
-  async login(username: string, password: string): Promise<{ token: string; user: User }> {
-    try {
-      const user = await this.userService.getUserByUsername(username);
-      if (!user) {
-        throw new Error('用户不存在');
-      }
-
-      // 检查用户是否被禁用
-      if (user.isDisabled === EnableStatus.DISABLED) {
-        throw new Error('用户账户已被禁用');
-      }
-
-      const isPasswordValid = await this.userService.verifyPassword(user, password);
-      if (!isPasswordValid) {
-        throw new Error('密码错误');
-      }
-
-      const payload: JWTPayload = {
-        id: user.id,
-        username: user.username,
-        roles: user.roles?.map(role => role.name) || [],
-        openid: user.openid || undefined
-      };
-
-      const token = JWTService.generateToken(payload);
-      return { token, user };
-    } catch (error) {
-      logger.error('登录错误:', error);
-      throw error;
-    }
-  }
-
-  generateToken(user: User, expiresIn?: string): string {
-    const payload: JWTPayload = {
-      id: user.id,
-      username: user.username,
-      roles: user.roles?.map(role => role.name) || [],
-      openid: user.openid || undefined
-    };
-    return JWTService.generateToken(payload, expiresIn);
-  }
-
-  verifyToken(token: string): JWTPayload {
-    return JWTService.verifyToken(token);
-  }
-
-  async logout(token: string): Promise<void> {
-    try {
-      // 验证token有效性
-      const decoded = this.verifyToken(token);
-      if (!decoded) {
-        throw new Error('无效的token');
-      }
-
-      // 实际项目中这里可以添加token黑名单逻辑
-      // 或者调用Redis等缓存服务使token失效
-
-      return Promise.resolve();
-    } catch (error) {
-      logger.error('登出失败:', error);
-      throw error;
-    }
-  }
-
-  /**
-   * 验证用户权限
-   * @param user 用户信息
-   * @param requiredRole 需要的角色
-   * @returns 是否有权限
-   */
-  hasPermission(user: User, requiredRole: string): boolean {
-    return user.roles?.some(role => role.name === requiredRole) || false;
-  }
-
-  /**
-   * 验证用户是否有任意一个权限
-   * @param user 用户信息
-   * @param requiredRoles 需要的角色列表
-   * @returns 是否有权限
-   */
-  hasAnyPermission(user: User, requiredRoles: string[]): boolean {
-    return requiredRoles.some(role => this.hasPermission(user, role));
-  }
-}

+ 0 - 2
packages/auth-core/src/index.ts

@@ -1,2 +0,0 @@
-export * from './jwt.service.js';
-export * from './auth.service.js';

+ 0 - 84
packages/auth-core/src/jwt.service.ts

@@ -1,84 +0,0 @@
-import jwt, { SignOptions } from 'jsonwebtoken';
-import debug from 'debug';
-
-const logger = {
-  info: debug('auth-core:jwt:info'),
-  error: debug('auth-core:jwt:error')
-};
-
-const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
-const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '7d';
-
-export interface JWTPayload {
-  id: number;
-  username: string;
-  roles?: string[];
-  openid?: string;
-}
-
-export class JWTService {
-  /**
-   * 生成 JWT token
-   * @param payload JWT payload 数据
-   * @param expiresIn 过期时间
-   * @returns JWT token
-   */
-  static generateToken(payload: JWTPayload, expiresIn?: string): string {
-    if (!payload.id || !payload.username) {
-      throw new Error('用户ID和用户名不能为空');
-    }
-
-    try {
-      const options: SignOptions = {
-        expiresIn: expiresIn || JWT_EXPIRES_IN as SignOptions['expiresIn']
-      };
-      return jwt.sign(payload, JWT_SECRET, options);
-    } catch (error) {
-      logger.error('生成JWT token失败:', error);
-      throw new Error('生成token失败');
-    }
-  }
-
-  /**
-   * 验证 JWT token
-   * @param token JWT token
-   * @returns 验证后的 payload
-   */
-  static verifyToken(token: string): JWTPayload {
-    try {
-      return jwt.verify(token, JWT_SECRET) as JWTPayload;
-    } catch (error) {
-      logger.error('验证JWT token失败:', error);
-      throw new Error('无效的token');
-    }
-  }
-
-  /**
-   * 解码 JWT token(不验证签名)
-   * @param token JWT token
-   * @returns 解码后的 payload
-   */
-  static decodeToken(token: string): JWTPayload | null {
-    try {
-      return jwt.decode(token) as JWTPayload;
-    } catch (error) {
-      logger.error('解码JWT token失败:', error);
-      return null;
-    }
-  }
-
-  /**
-   * 获取 token 的剩余有效期(秒)
-   * @param token JWT token
-   * @returns 剩余有效期(秒),如果 token 无效则返回 0
-   */
-  static getTokenRemainingTime(token: string): number {
-    try {
-      const decoded = jwt.verify(token, JWT_SECRET) as JWTPayload & { exp: number };
-      const currentTime = Math.floor(Date.now() / 1000);
-      return Math.max(0, decoded.exp - currentTime);
-    } catch (error) {
-      return 0;
-    }
-  }
-}

+ 0 - 142
packages/auth-core/tests/unit/auth.service.test.ts

@@ -1,142 +0,0 @@
-import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { AuthService, User, UserService } from '../../src/auth.service.js';
-import { EnableStatus } from '@d8d/shared-types';
-
-describe('认证服务', () => {
-  let authService: AuthService;
-  let mockUserService: UserService;
-
-  const mockUser: User = {
-    id: 1,
-    username: 'testuser',
-    nickname: '测试用户',
-    isDisabled: EnableStatus.ENABLED,
-    roles: [{ name: 'user' }]
-  };
-
-  beforeEach(() => {
-    mockUserService = {
-      getUserByUsername: vi.fn(),
-      verifyPassword: vi.fn(),
-      createUser: vi.fn()
-    };
-
-    authService = new AuthService(mockUserService);
-    vi.stubEnv('JWT_SECRET', 'test-secret');
-  });
-
-  describe('登录', () => {
-    it('应该成功登录', async () => {
-      vi.mocked(mockUserService.getUserByUsername).mockResolvedValue(mockUser);
-      vi.mocked(mockUserService.verifyPassword).mockResolvedValue(true);
-
-      const result = await authService.login('testuser', 'password');
-
-      expect(result.token).toBeDefined();
-      expect(result.user).toEqual(mockUser);
-      expect(mockUserService.getUserByUsername).toHaveBeenCalledWith('testuser');
-      expect(mockUserService.verifyPassword).toHaveBeenCalledWith(mockUser, 'password');
-    });
-
-    it('用户不存在时应该抛出错误', async () => {
-      vi.mocked(mockUserService.getUserByUsername).mockResolvedValue(null);
-
-      await expect(authService.login('nonexistent', 'password'))
-        .rejects
-        .toThrow('用户不存在');
-    });
-
-    it('用户被禁用时应该抛出错误', async () => {
-      const disabledUser = { ...mockUser, isDisabled: EnableStatus.DISABLED };
-      vi.mocked(mockUserService.getUserByUsername).mockResolvedValue(disabledUser);
-
-      await expect(authService.login('testuser', 'password'))
-        .rejects
-        .toThrow('用户账户已被禁用');
-    });
-
-    it('密码错误时应该抛出错误', async () => {
-      vi.mocked(mockUserService.getUserByUsername).mockResolvedValue(mockUser);
-      vi.mocked(mockUserService.verifyPassword).mockResolvedValue(false);
-
-      await expect(authService.login('testuser', 'wrongpassword'))
-        .rejects
-        .toThrow('密码错误');
-    });
-  });
-
-  describe('生成token', () => {
-    it('应该成功生成token', () => {
-      const token = authService.generateToken(mockUser);
-
-      expect(token).toBeDefined();
-      expect(typeof token).toBe('string');
-    });
-
-    it('应该使用自定义过期时间生成token', () => {
-      const token = authService.generateToken(mockUser, '2h');
-
-      expect(token).toBeDefined();
-    });
-  });
-
-  describe('验证token', () => {
-    it('应该成功验证token', () => {
-      const token = authService.generateToken(mockUser);
-      const payload = authService.verifyToken(token);
-
-      expect(payload.id).toBe(mockUser.id);
-      expect(payload.username).toBe(mockUser.username);
-    });
-
-    it('无效token应该抛出错误', () => {
-      const invalidToken = 'invalid.token.here';
-
-      expect(() => {
-        authService.verifyToken(invalidToken);
-      }).toThrow('无效的token');
-    });
-  });
-
-  describe('权限验证', () => {
-    it('应该验证用户有权限', () => {
-      const hasPermission = authService.hasPermission(mockUser, 'user');
-
-      expect(hasPermission).toBe(true);
-    });
-
-    it('应该验证用户没有权限', () => {
-      const hasPermission = authService.hasPermission(mockUser, 'admin');
-
-      expect(hasPermission).toBe(false);
-    });
-
-    it('应该验证用户有任意一个权限', () => {
-      const hasAnyPermission = authService.hasAnyPermission(mockUser, ['user', 'admin']);
-
-      expect(hasAnyPermission).toBe(true);
-    });
-
-    it('应该验证用户没有任意一个权限', () => {
-      const hasAnyPermission = authService.hasAnyPermission(mockUser, ['admin', 'superuser']);
-
-      expect(hasAnyPermission).toBe(false);
-    });
-  });
-
-  describe('登出', () => {
-    it('应该成功登出', async () => {
-      const token = authService.generateToken(mockUser);
-
-      await expect(authService.logout(token)).resolves.toBeUndefined();
-    });
-
-    it('无效token登出时应该抛出错误', async () => {
-      const invalidToken = 'invalid.token.here';
-
-      await expect(authService.logout(invalidToken))
-        .rejects
-        .toThrow('无效的token');
-    });
-  });
-});

+ 0 - 124
packages/auth-core/tests/unit/jwt.service.test.ts

@@ -1,124 +0,0 @@
-import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { JWTService, JWTPayload } from '../../src/jwt.service.js';
-
-describe('JWT服务', () => {
-  beforeEach(() => {
-    vi.stubEnv('JWT_SECRET', 'test-secret');
-    vi.stubEnv('JWT_EXPIRES_IN', '1h');
-  });
-
-  describe('生成token', () => {
-    it('应该成功生成JWT token', () => {
-      const payload: JWTPayload = {
-        id: 1,
-        username: 'testuser',
-        roles: ['admin'],
-        openid: 'test-openid'
-      };
-
-      const token = JWTService.generateToken(payload);
-
-      expect(token).toBeDefined();
-      expect(typeof token).toBe('string');
-      expect(token.split('.')).toHaveLength(3); // JWT token 有3部分
-    });
-
-    it('应该使用自定义过期时间生成token', () => {
-      const payload: JWTPayload = {
-        id: 1,
-        username: 'testuser'
-      };
-
-      const token = JWTService.generateToken(payload, '2h');
-
-      expect(token).toBeDefined();
-    });
-
-    it('缺少用户ID时应该抛出错误', () => {
-      const payload = {
-        username: 'testuser'
-      } as JWTPayload;
-
-      expect(() => {
-        JWTService.generateToken(payload);
-      }).toThrow('用户ID和用户名不能为空');
-    });
-
-    it('缺少用户名时应该抛出错误', () => {
-      const payload = {
-        id: 1
-      } as JWTPayload;
-
-      expect(() => {
-        JWTService.generateToken(payload);
-      }).toThrow('用户ID和用户名不能为空');
-    });
-  });
-
-  describe('验证token', () => {
-    it('应该成功验证有效的token', () => {
-      const payload: JWTPayload = {
-        id: 1,
-        username: 'testuser'
-      };
-
-      const token = JWTService.generateToken(payload);
-      const decoded = JWTService.verifyToken(token);
-
-      expect(decoded.id).toBe(payload.id);
-      expect(decoded.username).toBe(payload.username);
-    });
-
-    it('验证无效token时应该抛出错误', () => {
-      const invalidToken = 'invalid.token.here';
-
-      expect(() => {
-        JWTService.verifyToken(invalidToken);
-      }).toThrow('无效的token');
-    });
-  });
-
-  describe('解码token', () => {
-    it('应该成功解码token', () => {
-      const payload: JWTPayload = {
-        id: 1,
-        username: 'testuser'
-      };
-
-      const token = JWTService.generateToken(payload);
-      const decoded = JWTService.decodeToken(token);
-
-      expect(decoded?.id).toBe(payload.id);
-      expect(decoded?.username).toBe(payload.username);
-    });
-
-    it('解码无效token时应该返回null', () => {
-      const invalidToken = 'invalid.token.here';
-      const decoded = JWTService.decodeToken(invalidToken);
-
-      expect(decoded).toBeNull();
-    });
-  });
-
-  describe('获取token剩余时间', () => {
-    it('应该返回有效的剩余时间', () => {
-      const payload: JWTPayload = {
-        id: 1,
-        username: 'testuser'
-      };
-
-      const token = JWTService.generateToken(payload, '1h');
-      const remainingTime = JWTService.getTokenRemainingTime(token);
-
-      expect(remainingTime).toBeGreaterThan(0);
-      expect(remainingTime).toBeLessThanOrEqual(3600); // 1小时 = 3600秒
-    });
-
-    it('无效token应该返回0', () => {
-      const invalidToken = 'invalid.token.here';
-      const remainingTime = JWTService.getTokenRemainingTime(invalidToken);
-
-      expect(remainingTime).toBe(0);
-    });
-  });
-});

+ 0 - 28
packages/auth-core/tsconfig.json

@@ -1,28 +0,0 @@
-{
-  "compilerOptions": {
-    "composite": true,
-    "target": "ES2022",
-    "module": "ESNext",
-    "moduleResolution": "bundler",
-    "allowSyntheticDefaultImports": true,
-    "esModuleInterop": true,
-    "resolveJsonModule": true,
-    "isolatedModules": true,
-    "noEmit": false,
-    "strict": true,
-    "noUncheckedIndexedAccess": true,
-    "noImplicitOverride": true,
-    "outDir": "./dist",
-    "rootDir": ".",
-    "declaration": true,
-    "skipLibCheck": true
-  },
-  "include": [
-    "src/**/*",
-    "tests/**/*"
-  ],
-  "exclude": [
-    "node_modules",
-    "dist"
-  ]
-}