@nest-omni/core 4.1.3-20 → 4.1.3-23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/audit/audit.module.d.ts +1 -0
  2. package/audit/audit.module.js +5 -3
  3. package/audit/controllers/audit.controller.d.ts +3 -11
  4. package/audit/controllers/audit.controller.js +12 -19
  5. package/audit/decorators/audit-operation.decorator.d.ts +0 -7
  6. package/audit/decorators/audit-operation.decorator.js +0 -7
  7. package/audit/dto/audit-action-query.dto.d.ts +13 -0
  8. package/audit/dto/audit-action-query.dto.js +77 -0
  9. package/audit/dto/index.d.ts +1 -0
  10. package/audit/dto/index.js +1 -0
  11. package/audit/entities/entity-audit-log.entity.d.ts +1 -4
  12. package/audit/entities/entity-audit-log.entity.js +1 -17
  13. package/audit/entities/manual-operation-log.entity.d.ts +0 -2
  14. package/audit/entities/manual-operation-log.entity.js +0 -8
  15. package/audit/enums/audit.enums.d.ts +0 -8
  16. package/audit/enums/audit.enums.js +1 -10
  17. package/audit/examples/decorator-value-mapping.example.d.ts +70 -0
  18. package/audit/examples/decorator-value-mapping.example.js +414 -0
  19. package/audit/index.d.ts +1 -0
  20. package/audit/index.js +5 -1
  21. package/audit/interceptors/audit.interceptor.d.ts +1 -0
  22. package/audit/interceptors/audit.interceptor.js +19 -11
  23. package/audit/interfaces/audit.interfaces.d.ts +2 -17
  24. package/audit/services/audit-context.service.d.ts +9 -0
  25. package/audit/services/entity-audit.service.d.ts +65 -24
  26. package/audit/services/entity-audit.service.js +280 -93
  27. package/audit/services/manual-audit-log.service.d.ts +0 -1
  28. package/audit/services/manual-audit-log.service.js +1 -3
  29. package/audit/subscribers/entity-audit.subscriber.d.ts +1 -0
  30. package/audit/subscribers/entity-audit.subscriber.js +22 -5
  31. package/cache/cache.module.d.ts +7 -2
  32. package/cache/cache.module.js +9 -7
  33. package/cache/cache.service.d.ts +4 -4
  34. package/cache/cache.service.js +5 -5
  35. package/cache/entities/index.d.ts +1 -0
  36. package/cache/entities/index.js +17 -0
  37. package/cache/entities/typeorm-cache.entity.d.ts +71 -0
  38. package/cache/entities/typeorm-cache.entity.js +110 -0
  39. package/cache/index.d.ts +2 -1
  40. package/cache/index.js +19 -2
  41. package/cache/providers/index.d.ts +2 -1
  42. package/cache/providers/index.js +2 -1
  43. package/cache/providers/lrucache.provider.d.ts +76 -0
  44. package/cache/providers/lrucache.provider.js +226 -0
  45. package/cache/providers/typeorm-cache.provider.d.ts +211 -0
  46. package/cache/providers/typeorm-cache.provider.js +483 -0
  47. package/common/boilerplate.polyfill.d.ts +1 -0
  48. package/common/boilerplate.polyfill.js +17 -0
  49. package/common/helpers/validation-metadata-helper.d.ts +55 -0
  50. package/common/helpers/validation-metadata-helper.js +60 -0
  51. package/common/index.d.ts +1 -0
  52. package/common/index.js +4 -0
  53. package/decorators/field.decorators.d.ts +71 -2
  54. package/decorators/field.decorators.js +147 -18
  55. package/decorators/transform.decorators.d.ts +0 -2
  56. package/decorators/transform.decorators.js +0 -23
  57. package/filters/bad-request.filter.js +19 -4
  58. package/http-client/examples/axios-config-extended.example.d.ts +17 -0
  59. package/http-client/examples/axios-config-extended.example.js +313 -0
  60. package/http-client/examples/index.d.ts +2 -0
  61. package/http-client/examples/index.js +2 -0
  62. package/http-client/examples/ssl-certificate.example.d.ts +47 -0
  63. package/http-client/examples/ssl-certificate.example.js +431 -0
  64. package/http-client/index.d.ts +1 -1
  65. package/http-client/interfaces/http-client-config.interface.d.ts +73 -0
  66. package/http-client/services/http-client.service.js +46 -5
  67. package/http-client/utils/context-extractor.util.js +2 -0
  68. package/ip-filter/constants.d.ts +21 -0
  69. package/ip-filter/constants.js +24 -0
  70. package/ip-filter/decorators/index.d.ts +1 -0
  71. package/ip-filter/decorators/index.js +17 -0
  72. package/ip-filter/decorators/ip-filter.decorator.d.ts +58 -0
  73. package/ip-filter/decorators/ip-filter.decorator.js +79 -0
  74. package/ip-filter/guards/index.d.ts +1 -0
  75. package/ip-filter/guards/index.js +17 -0
  76. package/ip-filter/guards/ip-filter.guard.d.ts +62 -0
  77. package/ip-filter/guards/ip-filter.guard.js +174 -0
  78. package/ip-filter/index.d.ts +7 -0
  79. package/ip-filter/index.js +23 -0
  80. package/ip-filter/interfaces/index.d.ts +4 -0
  81. package/ip-filter/interfaces/index.js +20 -0
  82. package/ip-filter/interfaces/ip-filter-async-options.interface.d.ts +15 -0
  83. package/ip-filter/interfaces/ip-filter-async-options.interface.js +2 -0
  84. package/ip-filter/interfaces/ip-filter-metadata.interface.d.ts +26 -0
  85. package/ip-filter/interfaces/ip-filter-metadata.interface.js +2 -0
  86. package/ip-filter/interfaces/ip-filter-options.interface.d.ts +34 -0
  87. package/ip-filter/interfaces/ip-filter-options.interface.js +2 -0
  88. package/ip-filter/interfaces/ip-rule.interface.d.ts +36 -0
  89. package/ip-filter/interfaces/ip-rule.interface.js +2 -0
  90. package/ip-filter/ip-filter.module.d.ts +55 -0
  91. package/ip-filter/ip-filter.module.js +105 -0
  92. package/ip-filter/services/index.d.ts +1 -0
  93. package/ip-filter/services/index.js +17 -0
  94. package/ip-filter/services/ip-filter.service.d.ts +92 -0
  95. package/ip-filter/services/ip-filter.service.js +238 -0
  96. package/ip-filter/utils/index.d.ts +1 -0
  97. package/ip-filter/utils/index.js +17 -0
  98. package/ip-filter/utils/ip-utils.d.ts +61 -0
  99. package/ip-filter/utils/ip-utils.js +162 -0
  100. package/package.json +23 -24
  101. package/providers/context.provider.d.ts +9 -0
  102. package/providers/context.provider.js +13 -0
  103. package/setup/bootstrap.setup.d.ts +1 -1
  104. package/setup/bootstrap.setup.js +1 -1
  105. package/shared/service-registry.module.js +0 -1
  106. package/cache/providers/memory-cache.provider.d.ts +0 -69
  107. package/cache/providers/memory-cache.provider.js +0 -237
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ var IpFilterModule_1;
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.IpFilterModule = void 0;
20
+ const common_1 = require("@nestjs/common");
21
+ const ip_filter_guard_1 = require("./guards/ip-filter.guard");
22
+ const ip_filter_service_1 = require("./services/ip-filter.service");
23
+ /**
24
+ * IP过滤模块
25
+ * 提供IP访问控制功能
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * // 同步配置
30
+ * @Module({
31
+ * imports: [
32
+ * IpFilterModule.register({
33
+ * mode: 'whitelist',
34
+ * defaultPolicy: 'deny',
35
+ * rules: [
36
+ * {
37
+ * id: 'office-network',
38
+ * type: 'whitelist',
39
+ * ipRanges: ['192.168.1.0/24', '10.0.0.0/8'],
40
+ * enabled: true,
41
+ * priority: 100,
42
+ * },
43
+ * ],
44
+ * }),
45
+ * ],
46
+ * })
47
+ * export class AppModule {}
48
+ *
49
+ * // 异步配置
50
+ * @Module({
51
+ * imports: [
52
+ * IpFilterModule.registerAsync({
53
+ * imports: [ConfigModule],
54
+ * inject: [ConfigService],
55
+ * useFactory: (config: ConfigService) => ({
56
+ * mode: 'whitelist',
57
+ * defaultPolicy: 'deny',
58
+ * rules: config.get('ipFilterRules'),
59
+ * }),
60
+ * }),
61
+ * ],
62
+ * })
63
+ * export class AppModule {}
64
+ * ```
65
+ */
66
+ let IpFilterModule = IpFilterModule_1 = class IpFilterModule {
67
+ /**
68
+ * 同步注册模块
69
+ */
70
+ static register(options) {
71
+ const serviceProvider = {
72
+ provide: ip_filter_service_1.IpFilterService,
73
+ useValue: new ip_filter_service_1.IpFilterService(options),
74
+ };
75
+ return {
76
+ module: IpFilterModule_1,
77
+ providers: [serviceProvider, ip_filter_guard_1.IpFilterGuard],
78
+ exports: [ip_filter_service_1.IpFilterService, ip_filter_guard_1.IpFilterGuard],
79
+ };
80
+ }
81
+ /**
82
+ * 异步注册模块
83
+ */
84
+ static registerAsync(options) {
85
+ const serviceProvider = {
86
+ provide: ip_filter_service_1.IpFilterService,
87
+ useFactory: (...args) => __awaiter(this, void 0, void 0, function* () {
88
+ const moduleOptions = yield options.useFactory(...args);
89
+ return new ip_filter_service_1.IpFilterService(moduleOptions);
90
+ }),
91
+ inject: options.inject || [],
92
+ };
93
+ return {
94
+ module: IpFilterModule_1,
95
+ imports: options.imports || [],
96
+ providers: [serviceProvider, ip_filter_guard_1.IpFilterGuard],
97
+ exports: [ip_filter_service_1.IpFilterService, ip_filter_guard_1.IpFilterGuard],
98
+ };
99
+ }
100
+ };
101
+ exports.IpFilterModule = IpFilterModule;
102
+ exports.IpFilterModule = IpFilterModule = IpFilterModule_1 = __decorate([
103
+ (0, common_1.Global)(),
104
+ (0, common_1.Module)({})
105
+ ], IpFilterModule);
@@ -0,0 +1 @@
1
+ export * from './ip-filter.service';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ip-filter.service"), exports);
@@ -0,0 +1,92 @@
1
+ import { IpFilterModuleOptions, IpRule } from '../interfaces';
2
+ /**
3
+ * IP检查结果
4
+ */
5
+ export interface IpCheckResult {
6
+ allowed: boolean;
7
+ matchedRule?: string;
8
+ ruleType?: 'whitelist' | 'blacklist';
9
+ reason?: string;
10
+ }
11
+ /**
12
+ * IP过滤服务(优化版)
13
+ *
14
+ * 功能:
15
+ * - IP 规则匹配
16
+ * - 优先级处理
17
+ * - 黑名单优先检查
18
+ * - 白名单验证
19
+ * - 默认策略应用
20
+ * - 规则热更新
21
+ */
22
+ export declare class IpFilterService {
23
+ private readonly options?;
24
+ private readonly logger;
25
+ private rules;
26
+ private defaultPolicy;
27
+ constructor(options?: IpFilterModuleOptions);
28
+ /**
29
+ * 检查IP是否被允许访问
30
+ */
31
+ checkIp(ip: string, routeMetadata?: any): IpCheckResult;
32
+ /**
33
+ * 检查路由级别规则
34
+ */
35
+ private checkRouteRules;
36
+ /**
37
+ * 检查全局规则
38
+ */
39
+ private checkGlobalRules;
40
+ /**
41
+ * 更新规则(热更新)
42
+ *
43
+ * @param rules - 新的规则列表
44
+ * @param clearCache - 是否清除缓存(默认: true)
45
+ */
46
+ updateRules(rules: IpRule[], clearCache?: boolean): void;
47
+ /**
48
+ * 重新加载规则
49
+ *
50
+ * @param newOptions - 新的模块选项
51
+ */
52
+ reloadRules(newOptions: IpFilterModuleOptions): void;
53
+ /**
54
+ * 添加单个规则
55
+ *
56
+ * @param rule - 要添加的规则
57
+ */
58
+ addRule(rule: IpRule): void;
59
+ /**
60
+ * 删除规则
61
+ *
62
+ * @param ruleId - 要删除的规则ID
63
+ */
64
+ removeRule(ruleId: string): void;
65
+ /**
66
+ * 启用/禁用规则
67
+ *
68
+ * @param ruleId - 规则ID
69
+ * @param enabled - 是否启用
70
+ */
71
+ toggleRule(ruleId: string, enabled: boolean): void;
72
+ /**
73
+ * 获取所有规则
74
+ */
75
+ getRules(): IpRule[];
76
+ /**
77
+ * 获取规则统计
78
+ */
79
+ getRulesStats(): {
80
+ total: number;
81
+ enabled: number;
82
+ disabled: number;
83
+ whitelist: number;
84
+ blacklist: number;
85
+ };
86
+ private logBlocked;
87
+ private logAllowed;
88
+ getErrorResponse(): {
89
+ message: string;
90
+ statusCode: number;
91
+ };
92
+ }
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var IpFilterService_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.IpFilterService = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const utils_1 = require("../utils");
16
+ /**
17
+ * 默认常量
18
+ */
19
+ const DEFAULT_CONSTANTS = {
20
+ DEFAULT_PRIORITY: 50,
21
+ DEFAULT_ERROR_MESSAGE: 'Access denied',
22
+ DEFAULT_ERROR_STATUS_CODE: 403,
23
+ };
24
+ /**
25
+ * IP过滤服务(优化版)
26
+ *
27
+ * 功能:
28
+ * - IP 规则匹配
29
+ * - 优先级处理
30
+ * - 黑名单优先检查
31
+ * - 白名单验证
32
+ * - 默认策略应用
33
+ * - 规则热更新
34
+ */
35
+ let IpFilterService = IpFilterService_1 = class IpFilterService {
36
+ constructor(options) {
37
+ this.options = options;
38
+ this.logger = new common_1.Logger(IpFilterService_1.name);
39
+ this.rules = [];
40
+ this.defaultPolicy = 'allow';
41
+ if (options === null || options === void 0 ? void 0 : options.rules) {
42
+ this.rules = [...options.rules];
43
+ }
44
+ if (options === null || options === void 0 ? void 0 : options.defaultPolicy) {
45
+ this.defaultPolicy = options.defaultPolicy;
46
+ }
47
+ }
48
+ /**
49
+ * 检查IP是否被允许访问
50
+ */
51
+ checkIp(ip, routeMetadata) {
52
+ var _a;
53
+ const normalizedIp = utils_1.IpUtils.normalizeIp(ip);
54
+ if (!utils_1.IpUtils.isValidIp(normalizedIp)) {
55
+ return { allowed: false, reason: 'Invalid IP address format' };
56
+ }
57
+ // 路由级别规则优先
58
+ if ((routeMetadata === null || routeMetadata === void 0 ? void 0 : routeMetadata.enabled) !== false && ((_a = routeMetadata === null || routeMetadata === void 0 ? void 0 : routeMetadata.ipRanges) === null || _a === void 0 ? void 0 : _a.length)) {
59
+ return this.checkRouteRules(normalizedIp, routeMetadata);
60
+ }
61
+ // 全局规则
62
+ return this.checkGlobalRules(normalizedIp);
63
+ }
64
+ /**
65
+ * 检查路由级别规则
66
+ */
67
+ checkRouteRules(ip, metadata) {
68
+ const { mode, ipRanges } = metadata;
69
+ const matched = utils_1.IpUtils.matchAnyCidr(ip, ipRanges);
70
+ if (mode === 'whitelist') {
71
+ return {
72
+ allowed: matched,
73
+ ruleType: 'whitelist',
74
+ reason: matched ? 'IP in route whitelist' : 'IP not in route whitelist',
75
+ };
76
+ }
77
+ // blacklist
78
+ return {
79
+ allowed: !matched,
80
+ ruleType: matched ? 'blacklist' : undefined,
81
+ reason: matched ? 'IP in route blacklist' : 'IP not in route blacklist',
82
+ };
83
+ }
84
+ /**
85
+ * 检查全局规则
86
+ */
87
+ checkGlobalRules(ip) {
88
+ var _a;
89
+ if (!((_a = this.rules) === null || _a === void 0 ? void 0 : _a.length)) {
90
+ return {
91
+ allowed: this.defaultPolicy === 'allow',
92
+ reason: 'No rules configured',
93
+ };
94
+ }
95
+ // 按优先级排序:黑名单优先
96
+ const sortedRules = [...this.rules]
97
+ .filter(r => r.enabled !== false)
98
+ .sort((a, b) => (b.priority || DEFAULT_CONSTANTS.DEFAULT_PRIORITY) - (a.priority || DEFAULT_CONSTANTS.DEFAULT_PRIORITY));
99
+ // 黑名单优先检查
100
+ for (const rule of sortedRules.filter(r => r.type === 'blacklist')) {
101
+ if (utils_1.IpUtils.matchAnyCidr(ip, rule.ipRanges)) {
102
+ this.logBlocked(ip, rule);
103
+ return { allowed: false, matchedRule: rule.id, ruleType: 'blacklist' };
104
+ }
105
+ }
106
+ // 白名单
107
+ const whitelistRules = sortedRules.filter(r => r.type === 'whitelist');
108
+ if (whitelistRules.length) {
109
+ for (const rule of whitelistRules) {
110
+ if (utils_1.IpUtils.matchAnyCidr(ip, rule.ipRanges)) {
111
+ this.logAllowed(ip, rule);
112
+ return { allowed: true, matchedRule: rule.id, ruleType: 'whitelist' };
113
+ }
114
+ }
115
+ // 有白名单但未匹配
116
+ return { allowed: false, reason: 'IP not in any whitelist' };
117
+ }
118
+ // 默认策略
119
+ return {
120
+ allowed: this.defaultPolicy === 'allow',
121
+ reason: `Using default policy: ${this.defaultPolicy}`,
122
+ };
123
+ }
124
+ /**
125
+ * 更新规则(热更新)
126
+ *
127
+ * @param rules - 新的规则列表
128
+ * @param clearCache - 是否清除缓存(默认: true)
129
+ */
130
+ updateRules(rules, clearCache = true) {
131
+ this.rules = [...rules];
132
+ if (clearCache) {
133
+ utils_1.IpUtils.clearCache();
134
+ this.logger.log(`Rules updated and cache cleared. Total rules: ${rules.length}`);
135
+ }
136
+ else {
137
+ this.logger.log(`Rules updated. Total rules: ${rules.length}`);
138
+ }
139
+ }
140
+ /**
141
+ * 重新加载规则
142
+ *
143
+ * @param newOptions - 新的模块选项
144
+ */
145
+ reloadRules(newOptions) {
146
+ if (newOptions.rules) {
147
+ this.updateRules(newOptions.rules);
148
+ }
149
+ if (newOptions.defaultPolicy) {
150
+ this.defaultPolicy = newOptions.defaultPolicy;
151
+ }
152
+ this.logger.log('Rules reloaded successfully');
153
+ }
154
+ /**
155
+ * 添加单个规则
156
+ *
157
+ * @param rule - 要添加的规则
158
+ */
159
+ addRule(rule) {
160
+ this.rules.push(rule);
161
+ utils_1.IpUtils.clearCache();
162
+ this.logger.log(`Rule added: ${rule.id}`);
163
+ }
164
+ /**
165
+ * 删除规则
166
+ *
167
+ * @param ruleId - 要删除的规则ID
168
+ */
169
+ removeRule(ruleId) {
170
+ const index = this.rules.findIndex(r => r.id === ruleId);
171
+ if (index !== -1) {
172
+ this.rules.splice(index, 1);
173
+ utils_1.IpUtils.clearCache();
174
+ this.logger.log(`Rule removed: ${ruleId}`);
175
+ }
176
+ }
177
+ /**
178
+ * 启用/禁用规则
179
+ *
180
+ * @param ruleId - 规则ID
181
+ * @param enabled - 是否启用
182
+ */
183
+ toggleRule(ruleId, enabled) {
184
+ const rule = this.rules.find(r => r.id === ruleId);
185
+ if (rule) {
186
+ rule.enabled = enabled;
187
+ utils_1.IpUtils.clearCache();
188
+ this.logger.log(`Rule ${ruleId} ${enabled ? 'enabled' : 'disabled'}`);
189
+ }
190
+ }
191
+ /**
192
+ * 获取所有规则
193
+ */
194
+ getRules() {
195
+ return [...this.rules];
196
+ }
197
+ /**
198
+ * 获取规则统计
199
+ */
200
+ getRulesStats() {
201
+ const total = this.rules.length;
202
+ const enabled = this.rules.filter(r => r.enabled !== false).length;
203
+ const disabled = total - enabled;
204
+ const whitelist = this.rules.filter(r => r.type === 'whitelist').length;
205
+ const blacklist = this.rules.filter(r => r.type === 'blacklist').length;
206
+ return {
207
+ total,
208
+ enabled,
209
+ disabled,
210
+ whitelist,
211
+ blacklist,
212
+ };
213
+ }
214
+ logBlocked(ip, rule) {
215
+ var _a;
216
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.enableLogging) {
217
+ this.logger.warn(`IP blocked: ${ip} - Rule: ${rule.id}`);
218
+ }
219
+ }
220
+ logAllowed(ip, rule) {
221
+ var _a;
222
+ if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.enableLogging) {
223
+ this.logger.log(`IP allowed: ${ip} - Rule: ${rule.id}`);
224
+ }
225
+ }
226
+ getErrorResponse() {
227
+ var _a, _b, _c, _d;
228
+ return {
229
+ message: ((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.errorResponse) === null || _b === void 0 ? void 0 : _b.message) || DEFAULT_CONSTANTS.DEFAULT_ERROR_MESSAGE,
230
+ statusCode: ((_d = (_c = this.options) === null || _c === void 0 ? void 0 : _c.errorResponse) === null || _d === void 0 ? void 0 : _d.statusCode) || DEFAULT_CONSTANTS.DEFAULT_ERROR_STATUS_CODE,
231
+ };
232
+ }
233
+ };
234
+ exports.IpFilterService = IpFilterService;
235
+ exports.IpFilterService = IpFilterService = IpFilterService_1 = __decorate([
236
+ (0, common_1.Injectable)(),
237
+ __metadata("design:paramtypes", [Object])
238
+ ], IpFilterService);
@@ -0,0 +1 @@
1
+ export * from './ip-utils';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ip-utils"), exports);
@@ -0,0 +1,61 @@
1
+ /**
2
+ * IP匹配结果
3
+ */
4
+ export interface IpMatchResult {
5
+ matched: boolean;
6
+ ruleId?: string;
7
+ ruleType?: 'whitelist' | 'blacklist';
8
+ }
9
+ /**
10
+ * IP工具类(优化版)
11
+ * 提供IP地址匹配和验证功能,带LRU缓存优化
12
+ */
13
+ export declare class IpUtils {
14
+ private static cidrCache;
15
+ private static validationCache;
16
+ /**
17
+ * 检查IP地址是否匹配CIDR范围(带缓存)
18
+ */
19
+ static matchCidr(ip: string, cidr: string): boolean;
20
+ /**
21
+ * 实际执行CIDR匹配
22
+ */
23
+ private static doMatchCidr;
24
+ /**
25
+ * 检查IP地址是否在任意一个CIDR范围内(短路优化)
26
+ */
27
+ static matchAnyCidr(ip: string, cidrList: string[]): boolean;
28
+ /**
29
+ * 验证IP地址格式是否有效(带缓存)
30
+ */
31
+ static isValidIp(ip: string): boolean;
32
+ /**
33
+ * 验证IP地址格式是否有效(同步版本)
34
+ */
35
+ static isValidIpSync(ip: string): boolean;
36
+ /**
37
+ * 标准化IP地址(优化版)
38
+ */
39
+ static normalizeIp(ip: string): string;
40
+ /**
41
+ * 获取IP版本
42
+ */
43
+ static getIpVersion(ip: string): 'IPv4' | 'IPv6' | 'unknown';
44
+ /**
45
+ * 清空缓存(用于测试或规则变更)
46
+ */
47
+ static clearCache(): void;
48
+ /**
49
+ * 获取缓存统计
50
+ */
51
+ static getCacheStats(): {
52
+ cidr: {
53
+ size: number;
54
+ maxSize: number;
55
+ };
56
+ validation: {
57
+ size: number;
58
+ maxSize: number;
59
+ };
60
+ };
61
+ }
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IpUtils = void 0;
4
+ const Address = require("ip-address");
5
+ const lru_cache_1 = require("lru-cache");
6
+ /**
7
+ * 缓存常量
8
+ */
9
+ const CACHE_CONSTANTS = {
10
+ CIDR_CACHE_SIZE: 1000,
11
+ VALIDATION_CACHE_SIZE: 500,
12
+ };
13
+ /**
14
+ * IP工具类(优化版)
15
+ * 提供IP地址匹配和验证功能,带LRU缓存优化
16
+ */
17
+ class IpUtils {
18
+ /**
19
+ * 检查IP地址是否匹配CIDR范围(带缓存)
20
+ */
21
+ static matchCidr(ip, cidr) {
22
+ const cacheKey = `${ip}:${cidr}`;
23
+ const cached = this.cidrCache.get(cacheKey);
24
+ if (cached !== undefined) {
25
+ return cached;
26
+ }
27
+ const result = this.doMatchCidr(ip, cidr);
28
+ this.cidrCache.set(cacheKey, result);
29
+ return result;
30
+ }
31
+ /**
32
+ * 实际执行CIDR匹配
33
+ */
34
+ static doMatchCidr(ip, cidr) {
35
+ try {
36
+ // 快速路径:单个IP精确匹配
37
+ if (!cidr.includes('/')) {
38
+ return ip === cidr;
39
+ }
40
+ // IPv4快速路径
41
+ if (!ip.includes(':') && !cidr.includes(':')) {
42
+ const ipv4Addr = new Address.Address4(ip);
43
+ const ipv4Cidr = new Address.Address4(cidr);
44
+ // 注意:参数顺序是 address.isInSubnet(cidr)
45
+ return ipv4Addr.isInSubnet(ipv4Cidr);
46
+ }
47
+ // IPv6路径
48
+ const addr = new Address.Address6(ip);
49
+ const cidrBlock = new Address.Address6(cidr);
50
+ return addr.isInSubnet(cidrBlock);
51
+ }
52
+ catch (error) {
53
+ // 记录错误日志但不抛出异常
54
+ console.warn(`CIDR match failed for ${ip} in ${cidr}:`, error);
55
+ return false;
56
+ }
57
+ }
58
+ /**
59
+ * 检查IP地址是否在任意一个CIDR范围内(短路优化)
60
+ */
61
+ static matchAnyCidr(ip, cidrList) {
62
+ if (!(cidrList === null || cidrList === void 0 ? void 0 : cidrList.length))
63
+ return false;
64
+ return cidrList.some(cidr => this.matchCidr(ip, cidr));
65
+ }
66
+ /**
67
+ * 验证IP地址格式是否有效(带缓存)
68
+ */
69
+ static isValidIp(ip) {
70
+ if (!ip || typeof ip !== 'string')
71
+ return false;
72
+ const cached = this.validationCache.get(ip);
73
+ if (cached !== undefined) {
74
+ return cached;
75
+ }
76
+ const result = this.isValidIpSync(ip);
77
+ this.validationCache.set(ip, result);
78
+ return result;
79
+ }
80
+ /**
81
+ * 验证IP地址格式是否有效(同步版本)
82
+ */
83
+ static isValidIpSync(ip) {
84
+ if (!ip || typeof ip !== 'string')
85
+ return false;
86
+ return ip.includes(':')
87
+ ? Address.Address6.isValid(ip)
88
+ : Address.Address4.isValid(ip);
89
+ }
90
+ /**
91
+ * 标准化IP地址(优化版)
92
+ */
93
+ static normalizeIp(ip) {
94
+ if (!ip)
95
+ return '';
96
+ // 处理 IPv6 映射的 IPv4
97
+ if (ip.startsWith('::ffff:')) {
98
+ return ip.substring(7);
99
+ }
100
+ // 检查是否是 IPv6 地址(包含多个冒号或包含 ::)
101
+ const ipv6Pattern = /:.*:/;
102
+ if (ipv6Pattern.test(ip)) {
103
+ // 纯 IPv6 地址,保持不变
104
+ return ip;
105
+ }
106
+ // IPv4 地址(可能带端口号)
107
+ // 移除端口号
108
+ const lastColonIndex = ip.lastIndexOf(':');
109
+ if (lastColonIndex > 0) {
110
+ // 可能是 IPv4:port 格式
111
+ const potentialPort = ip.substring(lastColonIndex + 1);
112
+ if (/^\d+$/.test(potentialPort)) {
113
+ // 确认是端口号,返回 IPv4 部分
114
+ return ip.substring(0, lastColonIndex);
115
+ }
116
+ }
117
+ return ip;
118
+ }
119
+ /**
120
+ * 获取IP版本
121
+ */
122
+ static getIpVersion(ip) {
123
+ if (!ip)
124
+ return 'unknown';
125
+ if (ip.includes(':'))
126
+ return 'IPv6';
127
+ if (this.isValidIpSync(ip))
128
+ return 'IPv4';
129
+ return 'unknown';
130
+ }
131
+ /**
132
+ * 清空缓存(用于测试或规则变更)
133
+ */
134
+ static clearCache() {
135
+ this.cidrCache.clear();
136
+ this.validationCache.clear();
137
+ }
138
+ /**
139
+ * 获取缓存统计
140
+ */
141
+ static getCacheStats() {
142
+ return {
143
+ cidr: {
144
+ size: this.cidrCache.size,
145
+ maxSize: this.cidrCache.max,
146
+ },
147
+ validation: {
148
+ size: this.validationCache.size,
149
+ maxSize: this.validationCache.max,
150
+ },
151
+ };
152
+ }
153
+ }
154
+ exports.IpUtils = IpUtils;
155
+ // CIDR匹配缓存(使用 lru-cache 库)
156
+ IpUtils.cidrCache = new lru_cache_1.LRUCache({
157
+ max: CACHE_CONSTANTS.CIDR_CACHE_SIZE,
158
+ });
159
+ // IP验证缓存
160
+ IpUtils.validationCache = new lru_cache_1.LRUCache({
161
+ max: CACHE_CONSTANTS.VALIDATION_CACHE_SIZE,
162
+ });