forked from datawhale/whale-town-end
CRITICAL ISSUES: Database management service with major problems
WARNING: This commit contains code with significant issues that need immediate attention: 1. Type Safety Issues: - Unused import ZulipAccountsService causing compilation warnings - Implicit 'any' type in formatZulipAccount method parameter - Type inconsistencies in service injections 2. Service Integration Problems: - Inconsistent service interface usage - Missing proper type definitions for injected services - Potential runtime errors due to type mismatches 3. Code Quality Issues: - Violation of TypeScript strict mode requirements - Inconsistent error handling patterns - Missing proper interface implementations Files affected: - src/business/admin/database_management.service.ts (main issue) - Multiple test files and service implementations - Configuration and documentation updates Next steps required: 1. Fix TypeScript compilation errors 2. Implement proper type safety 3. Resolve service injection inconsistencies 4. Add comprehensive error handling 5. Update tests to match new implementations Impact: High - affects admin functionality and system stability Priority: Urgent - requires immediate review and fixes Author: moyin Date: 2026-01-10
This commit is contained in:
@@ -42,8 +42,8 @@ export interface ThrottleConfig {
|
||||
limit: number;
|
||||
/** 时间窗口长度(秒) */
|
||||
ttl: number;
|
||||
/** 限制类型:ip(基于IP)或 user(基于用户) */
|
||||
type?: 'ip' | 'user';
|
||||
/** 限制类型:ip(基于IP)、user(基于用户)或 email(基于邮箱) */
|
||||
type?: 'ip' | 'user' | 'email';
|
||||
/** 自定义错误消息 */
|
||||
message?: string;
|
||||
}
|
||||
@@ -85,15 +85,21 @@ export function Throttle(config: ThrottleConfig) {
|
||||
* 预定义的频率限制配置
|
||||
*/
|
||||
export const ThrottlePresets = {
|
||||
/** 登录接口:每分钟5次 */
|
||||
/** 登录接口:每分钟5次(基于IP,防止暴力破解) */
|
||||
LOGIN: { limit: 5, ttl: 60, message: '登录尝试过于频繁,请1分钟后再试' },
|
||||
|
||||
/** 登录接口(基于账号):每个账号每分钟3次,但不同账号不互相影响 */
|
||||
LOGIN_PER_ACCOUNT: { limit: 3, ttl: 60, type: 'email' as any, message: '该账号登录尝试过于频繁,请1分钟后再试' },
|
||||
|
||||
/** 注册接口:每5分钟10次(开发环境放宽限制) */
|
||||
REGISTER: { limit: 10, ttl: 300, message: '注册请求过于频繁,请5分钟后再试' },
|
||||
|
||||
/** 发送验证码:每分钟1次 */
|
||||
/** 发送验证码:每分钟1次(基于IP,用于防止滥用) */
|
||||
SEND_CODE: { limit: 1, ttl: 60, message: '验证码发送过于频繁,请1分钟后再试' },
|
||||
|
||||
/** 发送验证码(基于邮箱):每个邮箱每分钟1次,但不同邮箱不互相影响 */
|
||||
SEND_CODE_PER_EMAIL: { limit: 1, ttl: 60, type: 'email' as any, message: '该邮箱验证码发送过于频繁,请1分钟后再试' },
|
||||
|
||||
/** 密码重置:每小时3次 */
|
||||
RESET_PASSWORD: { limit: 3, ttl: 3600, message: '密码重置请求过于频繁,请1小时后再试' },
|
||||
|
||||
|
||||
@@ -230,6 +230,10 @@ export class ThrottleGuard implements CanActivate, OnModuleDestroy {
|
||||
// 基于用户的限制(需要从JWT中获取用户ID)
|
||||
const userId = this.extractUserId(request);
|
||||
return `user:${userId}:${method}:${path}`;
|
||||
} else if (config.type === 'email') {
|
||||
// 基于邮箱的限制(从请求体中获取邮箱)
|
||||
const email = this.extractEmail(request);
|
||||
return `email:${email}:${method}:${path}`;
|
||||
} else {
|
||||
// 基于IP的限制(默认)
|
||||
return `ip:${ip}:${method}:${path}`;
|
||||
@@ -305,6 +309,46 @@ export class ThrottleGuard implements CanActivate, OnModuleDestroy {
|
||||
return request.ip || 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* 从请求中提取邮箱地址
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @returns 邮箱地址
|
||||
*/
|
||||
private extractEmail(request: Request): string {
|
||||
try {
|
||||
// 从请求体中获取邮箱
|
||||
const body = request.body;
|
||||
|
||||
// 优先从email字段获取
|
||||
if (body && body.email) {
|
||||
return body.email.toLowerCase(); // 统一转换为小写
|
||||
}
|
||||
|
||||
// 从identifier字段获取(登录接口使用这个字段)
|
||||
if (body && body.identifier) {
|
||||
// 检查identifier是否是邮箱格式
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (emailRegex.test(body.identifier)) {
|
||||
return body.identifier.toLowerCase();
|
||||
}
|
||||
// 如果不是邮箱格式,可能是用户名,也用作标识符
|
||||
return body.identifier.toLowerCase();
|
||||
}
|
||||
|
||||
// 检查其他可能的字段
|
||||
if (body && body.username) {
|
||||
return body.username.toLowerCase();
|
||||
}
|
||||
|
||||
// 如果都没有找到,使用IP作为fallback
|
||||
return request.ip || 'unknown';
|
||||
} catch (error) {
|
||||
// 解析失败,使用IP作为fallback
|
||||
return request.ip || 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动清理任务
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user