nestjs-security-cli 1.1.1 โ 1.2.1
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.
- package/README.md +81 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces/security-config.interface.d.ts +0 -1
- package/dist/schemas/blacklisted-ip.schema.d.ts +0 -1
- package/dist/schemas/blacklisted-ip.schema.js +1 -5
- package/dist/schemas/blacklisted-ip.schema.js.map +1 -1
- package/dist/security.module.d.ts +1 -1
- package/dist/security.module.js +5 -8
- package/dist/security.module.js.map +1 -1
- package/dist/services/security.service.d.ts +6 -4
- package/dist/services/security.service.js +55 -35
- package/dist/services/security.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,23 +10,80 @@ npm install nestjs-security-cli
|
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
|
+
```typescript
|
|
14
|
+
import { Module } from '@nestjs/common';
|
|
15
|
+
import { MongooseModule } from '@nestjs/mongoose';
|
|
16
|
+
import { SecurityModule, BlacklistedIp, BlacklistedIpSchema } from 'nestjs-security-cli';
|
|
17
|
+
@Module({ imports: [
|
|
18
|
+
// 1. Set up MongoDB connection first MongooseModule.forRoot('mongodb://localhost:27017/myapp'),
|
|
19
|
+
// 2. Register the schema in your app
|
|
20
|
+
MongooseModule.forFeature([
|
|
21
|
+
{ name: BlacklistedIp.name, schema: BlacklistedIpSchema }
|
|
22
|
+
]),
|
|
23
|
+
// 3. Then add SecurityModule
|
|
24
|
+
SecurityModule.forRoot({
|
|
25
|
+
enableDatabase: true,
|
|
26
|
+
defaultBlockDurationHours: 24,
|
|
27
|
+
enableAutoBlocking: true,
|
|
28
|
+
enableAdminPanel: false,
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
})
|
|
32
|
+
export class AppModule {}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## with ConfigService
|
|
36
|
+
```
|
|
37
|
+
import { Module } from '@nestjs/common';
|
|
38
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
39
|
+
import { MongooseModule } from '@nestjs/mongoose';
|
|
40
|
+
import { SecurityModule, BlacklistedIp, BlacklistedIpSchema } from 'nestjs-security-cli';
|
|
41
|
+
@Module({ imports: [ ConfigModule.forRoot(),
|
|
42
|
+
// MongoDB connection
|
|
43
|
+
MongooseModule.forRootAsync({
|
|
44
|
+
imports: [ConfigModule],
|
|
45
|
+
useFactory: async (configService: ConfigService) => ({
|
|
46
|
+
uri: configService.get<string>('MONGODB_URI'),
|
|
47
|
+
}),
|
|
48
|
+
inject: [ConfigService],
|
|
49
|
+
}),
|
|
50
|
+
|
|
51
|
+
// Register schema
|
|
52
|
+
MongooseModule.forFeature([
|
|
53
|
+
{ name: BlacklistedIp.name, schema: BlacklistedIpSchema }
|
|
54
|
+
]),
|
|
55
|
+
|
|
56
|
+
// Security module
|
|
57
|
+
SecurityModule.forRoot({
|
|
58
|
+
enableDatabase: true,
|
|
59
|
+
defaultBlockDurationHours: 24,
|
|
60
|
+
enableAutoBlocking: true,
|
|
61
|
+
}),
|
|
62
|
+
],
|
|
63
|
+
})
|
|
64
|
+
export class AppModule {}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Cache-Only Mode (No Database)
|
|
68
|
+
|
|
69
|
+
If you don't want to use MongoDB, you can skip the schema registration:
|
|
70
|
+
|
|
13
71
|
```typescript
|
|
14
72
|
import { Module } from '@nestjs/common';
|
|
15
73
|
import { SecurityModule } from 'nestjs-security-cli';
|
|
16
74
|
|
|
17
|
-
@Module(
|
|
75
|
+
@Module({
|
|
18
76
|
imports: [
|
|
19
|
-
SecurityModule.forRoot(
|
|
20
|
-
enableDatabase:
|
|
21
|
-
dbConnectionName: '<some-connection-name>', // put the db connection name here
|
|
77
|
+
SecurityModule.forRoot({
|
|
78
|
+
enableDatabase: false, // This will use only cache
|
|
22
79
|
defaultBlockDurationHours: 24,
|
|
23
80
|
enableAutoBlocking: true,
|
|
24
|
-
}
|
|
81
|
+
}),
|
|
25
82
|
],
|
|
26
|
-
}
|
|
27
|
-
export class AppModule {
|
|
28
|
-
|
|
29
|
-
|
|
83
|
+
})
|
|
84
|
+
export class AppModule {}
|
|
85
|
+
````
|
|
86
|
+
|
|
30
87
|
|
|
31
88
|
## Clean up cron
|
|
32
89
|
|
|
@@ -59,6 +116,21 @@ the
|
|
|
59
116
|
|
|
60
117
|
[need to add api docs]
|
|
61
118
|
|
|
119
|
+
## Configuration Options
|
|
120
|
+
```aiignore
|
|
121
|
+
interface SecurityConfigInterface {
|
|
122
|
+
enableDatabase?: boolean; // Default: true
|
|
123
|
+
enableAutoBlocking?: boolean; // Default: true
|
|
124
|
+
enableAdminPanel?: boolean; // Default: false
|
|
125
|
+
defaultBlockDurationHours?: number; // Default: 24
|
|
126
|
+
enableLogging?: boolean; // Default: true
|
|
127
|
+
cache?: {
|
|
128
|
+
ttl?: number;
|
|
129
|
+
max?: number;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
62
134
|
## Requirements
|
|
63
135
|
|
|
64
136
|
- Node.js >= 16.0.0
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export { IpBlacklistGuard } from './guards/ip-blacklist.guard';
|
|
|
4
4
|
export { RolesGuard } from './guards/roles.guard';
|
|
5
5
|
export { AdminGuard } from './guards/admin.guard';
|
|
6
6
|
export { Roles } from './decorators/roles.decorator';
|
|
7
|
-
export { BlacklistedIp, BlacklistedIpSchema
|
|
7
|
+
export { BlacklistedIp, BlacklistedIpSchema } from './schemas/blacklisted-ip.schema';
|
|
8
8
|
export { SecurityConfigInterface } from './interfaces/security-config.interface';
|
|
9
9
|
export { SecurityController } from './controllers/security.controller';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SecurityController = exports.
|
|
3
|
+
exports.SecurityController = exports.BlacklistedIpSchema = exports.BlacklistedIp = exports.Roles = exports.AdminGuard = exports.RolesGuard = exports.IpBlacklistGuard = exports.SecurityService = exports.SecurityModule = void 0;
|
|
4
4
|
var security_module_1 = require("./security.module");
|
|
5
5
|
Object.defineProperty(exports, "SecurityModule", { enumerable: true, get: function () { return security_module_1.SecurityModule; } });
|
|
6
6
|
var security_service_1 = require("./services/security.service");
|
|
@@ -16,7 +16,6 @@ Object.defineProperty(exports, "Roles", { enumerable: true, get: function () { r
|
|
|
16
16
|
var blacklisted_ip_schema_1 = require("./schemas/blacklisted-ip.schema");
|
|
17
17
|
Object.defineProperty(exports, "BlacklistedIp", { enumerable: true, get: function () { return blacklisted_ip_schema_1.BlacklistedIp; } });
|
|
18
18
|
Object.defineProperty(exports, "BlacklistedIpSchema", { enumerable: true, get: function () { return blacklisted_ip_schema_1.BlacklistedIpSchema; } });
|
|
19
|
-
Object.defineProperty(exports, "blackListFeature", { enumerable: true, get: function () { return blacklisted_ip_schema_1.blackListFeature; } });
|
|
20
19
|
var security_controller_1 = require("./controllers/security.controller");
|
|
21
20
|
Object.defineProperty(exports, "SecurityController", { enumerable: true, get: function () { return security_controller_1.SecurityController; } });
|
|
22
21
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,qDAAkD;AAAzC,iHAAA,cAAc,OAAA;AAGvB,gEAA6D;AAApD,mHAAA,eAAe,OAAA;AAGxB,kEAA8D;AAArD,sHAAA,gBAAgB,OAAA;AACzB,oDAAiD;AAAxC,yGAAA,UAAU,OAAA;AACnB,oDAAiD;AAAxC,yGAAA,UAAU,OAAA;AAGnB,gEAAoD;AAA3C,wGAAA,KAAK,OAAA;AAGd,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,qDAAkD;AAAzC,iHAAA,cAAc,OAAA;AAGvB,gEAA6D;AAApD,mHAAA,eAAe,OAAA;AAGxB,kEAA8D;AAArD,sHAAA,gBAAgB,OAAA;AACzB,oDAAiD;AAAxC,yGAAA,UAAU,OAAA;AACnB,oDAAiD;AAAxC,yGAAA,UAAU,OAAA;AAGnB,gEAAoD;AAA3C,wGAAA,KAAK,OAAA;AAGd,yEAAoF;AAA3E,sHAAA,aAAa,OAAA;AAAE,4HAAA,mBAAmB,OAAA;AAM3C,yEAAsE;AAA7D,yHAAA,kBAAkB,OAAA"}
|
|
@@ -9,7 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
12
|
+
exports.BlacklistedIpSchema = exports.BlacklistedIp = void 0;
|
|
13
13
|
const mongoose_1 = require("@nestjs/mongoose");
|
|
14
14
|
const mongoose_2 = require("mongoose");
|
|
15
15
|
let BlacklistedIp = class BlacklistedIp extends mongoose_2.Document {
|
|
@@ -66,8 +66,4 @@ exports.BlacklistedIpSchema = mongoose_1.SchemaFactory.createForClass(Blackliste
|
|
|
66
66
|
exports.BlacklistedIpSchema.index({ expiresAt: 1 });
|
|
67
67
|
exports.BlacklistedIpSchema.index({ active: 1, expiresAt: 1 });
|
|
68
68
|
exports.BlacklistedIpSchema.index({ createdAt: -1 });
|
|
69
|
-
const blackListFeature = (dbConnectionName = '') => mongoose_1.MongooseModule.forFeature([
|
|
70
|
-
{ name: BlacklistedIp.name, schema: exports.BlacklistedIpSchema }
|
|
71
|
-
], dbConnectionName);
|
|
72
|
-
exports.blackListFeature = blackListFeature;
|
|
73
69
|
//# sourceMappingURL=blacklisted-ip.schema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blacklisted-ip.schema.js","sourceRoot":"","sources":["../../src/schemas/blacklisted-ip.schema.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+
|
|
1
|
+
{"version":3,"file":"blacklisted-ip.schema.js","sourceRoot":"","sources":["../../src/schemas/blacklisted-ip.schema.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+CAA8D;AAC9D,uCAAmC;AAG5B,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,mBAAQ;CAiC1C,CAAA;AAjCY,sCAAa;AAEzB;IADC,IAAA,eAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAE;;yCAC/B;AAGV;IADC,IAAA,eAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAE;;6CACb;AAGd;IADC,IAAA,eAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAE;8BAChB,IAAI;gDAAA;AAGf;IADC,IAAA,eAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAE;8BAChB,IAAI;gDAAA;AAGf;IADC,IAAA,eAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAE;;oDACN;AAGrB;IADC,IAAA,eAAI,GAAE;;gDACU;AAGjB;IADC,IAAA,eAAI,GAAE;;gDACW;AAGlB;IADC,IAAA,eAAI,GAAE;;iDACY;AAGnB;IADC,IAAA,eAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAE;;6CACX;AAGf;IADC,IAAA,eAAI,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAE;;gDACF;AAG5B;IADC,IAAA,eAAI,GAAE;;oDACe;wBAhCV,aAAa;IADzB,IAAA,iBAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAE;GAClB,aAAa,CAiCzB;AAEY,QAAA,mBAAmB,GAAG,wBAAa,CAAC,cAAc,CAAE,aAAa,CAAE,CAAA;AAIhF,2BAAmB,CAAC,KAAK,CAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAE,CAAA;AAC7C,2BAAmB,CAAC,KAAK,CAAE,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAE,CAAA;AACxD,2BAAmB,CAAC,KAAK,CAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAE,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { SecurityConfigInterface } from './interfaces/security-config.interface';
|
|
3
3
|
export declare class SecurityModule {
|
|
4
|
-
static forRoot(config
|
|
4
|
+
static forRoot(config?: SecurityConfigInterface): DynamicModule;
|
|
5
5
|
static forRootAsync(options: {
|
|
6
6
|
useFactory: (...args: any[]) => Promise<SecurityConfigInterface> | SecurityConfigInterface;
|
|
7
7
|
inject?: any[];
|
package/dist/security.module.js
CHANGED
|
@@ -19,7 +19,7 @@ const admin_guard_1 = require("./guards/admin.guard");
|
|
|
19
19
|
const roles_guard_1 = require("./guards/roles.guard");
|
|
20
20
|
const blacklisted_ip_schema_1 = require("./schemas/blacklisted-ip.schema");
|
|
21
21
|
let SecurityModule = SecurityModule_1 = class SecurityModule {
|
|
22
|
-
static forRoot(config) {
|
|
22
|
+
static forRoot(config = {}) {
|
|
23
23
|
const imports = [
|
|
24
24
|
schedule_1.ScheduleModule.forRoot()
|
|
25
25
|
];
|
|
@@ -29,9 +29,6 @@ let SecurityModule = SecurityModule_1 = class SecurityModule {
|
|
|
29
29
|
else {
|
|
30
30
|
imports.push(cache_manager_1.CacheModule.register());
|
|
31
31
|
}
|
|
32
|
-
if (config.enableDatabase !== false) {
|
|
33
|
-
imports.push((0, blacklisted_ip_schema_1.blackListFeature)(config.dbConnectionName));
|
|
34
|
-
}
|
|
35
32
|
return {
|
|
36
33
|
module: SecurityModule_1,
|
|
37
34
|
imports,
|
|
@@ -43,15 +40,15 @@ let SecurityModule = SecurityModule_1 = class SecurityModule {
|
|
|
43
40
|
roles_guard_1.RolesGuard,
|
|
44
41
|
{
|
|
45
42
|
provide: 'SECURITY_CONFIG',
|
|
46
|
-
useValue: config
|
|
47
|
-
}
|
|
43
|
+
useValue: config,
|
|
44
|
+
},
|
|
48
45
|
],
|
|
49
46
|
exports: [
|
|
50
47
|
security_service_1.SecurityService,
|
|
51
48
|
ip_blacklist_guard_1.IpBlacklistGuard,
|
|
52
49
|
admin_guard_1.AdminGuard,
|
|
53
|
-
roles_guard_1.RolesGuard
|
|
54
|
-
]
|
|
50
|
+
roles_guard_1.RolesGuard,
|
|
51
|
+
],
|
|
55
52
|
};
|
|
56
53
|
}
|
|
57
54
|
static forRootAsync(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.module.js","sourceRoot":"","sources":["../src/security.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAsD;AACtD,yDAAmD;AACnD,+CAAiD;AACjD,+CAAiD;AACjD,kEAA6D;AAC7D,2EAAsE;AACtE,oEAA8D;AAC9D,sDAAiD;AACjD,sDAAiD;AACjD,
|
|
1
|
+
{"version":3,"file":"security.module.js","sourceRoot":"","sources":["../src/security.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAsD;AACtD,yDAAmD;AACnD,+CAAiD;AACjD,+CAAiD;AACjD,kEAA6D;AAC7D,2EAAsE;AACtE,oEAA8D;AAC9D,sDAAiD;AACjD,sDAAiD;AACjD,2EAAoF;AAI7E,IAAM,cAAc,sBAApB,MAAM,cAAc;IAC1B,MAAM,CAAC,OAAO,CAAC,SAAkC,EAAE;QAClD,MAAM,OAAO,GAAG;YACf,yBAAc,CAAC,OAAO,EAAE;SACxB,CAAC;QAGF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,2BAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,2BAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtC,CAAC;QAKD,OAAO;YACN,MAAM,EAAE,gBAAc;YACtB,OAAO;YACP,WAAW,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,wCAAkB,CAAC,CAAC,CAAC,CAAC,EAAE;YAChE,SAAS,EAAE;gBACV,kCAAe;gBACf,qCAAgB;gBAChB,wBAAU;gBACV,wBAAU;gBACV;oBACC,OAAO,EAAE,iBAAiB;oBAC1B,QAAQ,EAAE,MAAM;iBAChB;aACD;YACD,OAAO,EAAE;gBACR,kCAAe;gBACf,qCAAgB;gBAChB,wBAAU;gBACV,wBAAU;aACV;SACD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAGnB;QACA,OAAO;YACN,MAAM,EAAE,gBAAc;YACtB,OAAO,EAAE;gBACR,yBAAc,CAAC,OAAO,EAAE;gBACxB,2BAAW,CAAC,QAAQ,EAAE;gBACtB,yBAAc,CAAC,UAAU,CAAE;oBAC1B,EAAE,IAAI,EAAE,qCAAa,CAAC,IAAI,EAAE,MAAM,EAAE,2CAAmB,EAAE;iBACzD,CAAE;aACH;YACD,WAAW,EAAE,CAAE,wCAAkB,CAAE;YACnC,SAAS,EAAE;gBACV;oBACC,OAAO,EAAE,iBAAiB;oBAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;iBAC5B;gBACD,kCAAe;gBACf,qCAAgB;gBAChB,wBAAU;gBACV,wBAAU;aACV;YACD,OAAO,EAAE;gBACR,kCAAe;gBACf,qCAAgB;gBAChB,wBAAU;gBACV,wBAAU;aACV;SACD,CAAA;IACF,CAAC;CACD,CAAA;AAxEY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,eAAM,EAAE,EAAE,CAAE;GACA,cAAc,CAwE1B"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { Model } from 'mongoose';
|
|
2
2
|
import type { Cache } from 'cache-manager';
|
|
3
3
|
import { BlacklistedIp } from '../schemas/blacklisted-ip.schema';
|
|
4
|
+
import { SecurityConfigInterface } from '../interfaces/security-config.interface';
|
|
4
5
|
export declare class SecurityService {
|
|
5
6
|
private readonly cache;
|
|
6
|
-
private readonly blacklistedIpModel
|
|
7
|
-
|
|
7
|
+
private readonly blacklistedIpModel?;
|
|
8
|
+
private readonly config?;
|
|
9
|
+
constructor(cache: Cache, blacklistedIpModel?: Model<BlacklistedIp>, config?: SecurityConfigInterface);
|
|
8
10
|
blacklistIp(ip: string, durationHours?: number, reason?: string, blockedBy?: string, attackDetails?: {
|
|
9
11
|
userAgent?: string;
|
|
10
12
|
requestUrl?: string;
|
|
11
13
|
attackPattern?: string;
|
|
12
14
|
}): Promise<void>;
|
|
13
|
-
removeFromBlacklist(ip: string): Promise<void>;
|
|
14
15
|
isBlacklisted(ip: string): Promise<boolean>;
|
|
16
|
+
cleanupExpiredBlocks(): Promise<void>;
|
|
17
|
+
removeFromBlacklist(ip: string): Promise<void>;
|
|
15
18
|
getBlacklistedIps(options?: {
|
|
16
19
|
active?: boolean;
|
|
17
20
|
limit?: number;
|
|
@@ -20,5 +23,4 @@ export declare class SecurityService {
|
|
|
20
23
|
sortOrder?: 'asc' | 'desc';
|
|
21
24
|
}): Promise<any[]>;
|
|
22
25
|
getSecurityAnalytics(days?: number): Promise<any>;
|
|
23
|
-
cleanupExpiredBlocks(): Promise<void>;
|
|
24
26
|
}
|
|
@@ -20,51 +20,70 @@ const cache_manager_1 = require("@nestjs/cache-manager");
|
|
|
20
20
|
const blacklisted_ip_schema_1 = require("../schemas/blacklisted-ip.schema");
|
|
21
21
|
const schedule_1 = require("@nestjs/schedule");
|
|
22
22
|
let SecurityService = class SecurityService {
|
|
23
|
-
constructor(cache, blacklistedIpModel) {
|
|
23
|
+
constructor(cache, blacklistedIpModel, config) {
|
|
24
24
|
this.cache = cache;
|
|
25
25
|
this.blacklistedIpModel = blacklistedIpModel;
|
|
26
|
+
this.config = config;
|
|
26
27
|
}
|
|
27
|
-
async blacklistIp(ip, durationHours = 24, reason, blockedBy, attackDetails) {
|
|
28
|
+
async blacklistIp(ip, durationHours = this.config?.defaultBlockDurationHours || 24, reason, blockedBy, attackDetails) {
|
|
28
29
|
const now = new Date();
|
|
29
30
|
const expiresAt = new Date(now.getTime() + durationHours * 60 * 60 * 1000);
|
|
30
|
-
|
|
31
|
-
ip,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
if (this.blacklistedIpModel && this.config?.enableDatabase !== false) {
|
|
32
|
+
await this.blacklistedIpModel.findOneAndUpdate({ ip }, {
|
|
33
|
+
ip,
|
|
34
|
+
reason: reason || 'Manual block',
|
|
35
|
+
blockedAt: now,
|
|
36
|
+
expiresAt,
|
|
37
|
+
durationHours,
|
|
38
|
+
blockedBy,
|
|
39
|
+
userAgent: attackDetails?.userAgent,
|
|
40
|
+
requestUrl: attackDetails?.requestUrl,
|
|
41
|
+
attackPattern: attackDetails?.attackPattern,
|
|
42
|
+
active: true,
|
|
43
|
+
blockType: blockedBy ? 'manual' : 'auto'
|
|
44
|
+
}, { upsert: true, new: true });
|
|
45
|
+
}
|
|
43
46
|
await this.cache.set(`blacklist:${ip}`, true, durationHours * 60 * 60 * 1000);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
await this.blacklistedIpModel.updateOne({ ip }, { active: false });
|
|
48
|
-
await this.cache.del(`blacklist:${ip}`);
|
|
49
|
-
console.log(`โ
IP ${ip} removed from blacklist`);
|
|
47
|
+
if (this.config?.enableLogging !== false) {
|
|
48
|
+
console.log(`๐ซ IP ${ip} blacklisted. Reason: ${reason}`);
|
|
49
|
+
}
|
|
50
50
|
}
|
|
51
51
|
async isBlacklisted(ip) {
|
|
52
52
|
const cached = await this.cache.get(`blacklist:${ip}`);
|
|
53
53
|
if (cached)
|
|
54
54
|
return true;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
if (this.blacklistedIpModel && this.config?.enableDatabase !== false) {
|
|
56
|
+
const dbRecord = await this.blacklistedIpModel.findOne({
|
|
57
|
+
ip,
|
|
58
|
+
active: true,
|
|
59
|
+
expiresAt: { $gt: new Date() }
|
|
60
|
+
});
|
|
61
|
+
if (dbRecord) {
|
|
62
|
+
const ttl = Math.max(0, dbRecord.expiresAt.getTime() - Date.now());
|
|
63
|
+
await this.cache.set(`blacklist:${ip}`, true, ttl);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
64
66
|
}
|
|
65
67
|
return false;
|
|
66
68
|
}
|
|
69
|
+
async cleanupExpiredBlocks() {
|
|
70
|
+
if (this.blacklistedIpModel && this.config?.enableDatabase !== false) {
|
|
71
|
+
const result = await this.blacklistedIpModel.updateMany({ active: true, expiresAt: { $lt: new Date() } }, { active: false });
|
|
72
|
+
if (this.config?.enableLogging !== false) {
|
|
73
|
+
console.log(`๐งน Cleaned up ${result.modifiedCount} expired IP blocks`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async removeFromBlacklist(ip) {
|
|
78
|
+
if (this.blacklistedIpModel && this.config?.enableDatabase === false)
|
|
79
|
+
return;
|
|
80
|
+
await this.blacklistedIpModel.updateOne({ ip }, { active: false });
|
|
81
|
+
await this.cache.del(`blacklist:${ip}`);
|
|
82
|
+
console.log(`โ
IP ${ip} removed from blacklist`);
|
|
83
|
+
}
|
|
67
84
|
async getBlacklistedIps(options = {}) {
|
|
85
|
+
if (this.blacklistedIpModel && this.config?.enableDatabase === false)
|
|
86
|
+
return;
|
|
68
87
|
const { active = true, limit = 50, skip = 0, sortBy = 'createdAt', sortOrder = 'desc' } = options;
|
|
69
88
|
const query = {};
|
|
70
89
|
if (active) {
|
|
@@ -76,6 +95,8 @@ let SecurityService = class SecurityService {
|
|
|
76
95
|
return await this.blacklistedIpModel.find(query).sort(sort).limit(limit).skip(skip).lean().exec();
|
|
77
96
|
}
|
|
78
97
|
async getSecurityAnalytics(days = 7) {
|
|
98
|
+
if (this.blacklistedIpModel && this.config?.enableDatabase === false)
|
|
99
|
+
return;
|
|
79
100
|
const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
|
80
101
|
const [totalBlocks, autoBlocks, topReasons, topAttackPatterns] = await Promise.all([
|
|
81
102
|
this.blacklistedIpModel.countDocuments({ createdAt: { $gte: since } }),
|
|
@@ -105,10 +126,6 @@ let SecurityService = class SecurityService {
|
|
|
105
126
|
topAttackPatterns
|
|
106
127
|
};
|
|
107
128
|
}
|
|
108
|
-
async cleanupExpiredBlocks() {
|
|
109
|
-
const result = await this.blacklistedIpModel.updateMany({ active: true, expiresAt: { $lt: new Date() } }, { active: false });
|
|
110
|
-
console.log(`๐งน Cleaned up ${result.modifiedCount} expired IP blocks`);
|
|
111
|
-
}
|
|
112
129
|
};
|
|
113
130
|
exports.SecurityService = SecurityService;
|
|
114
131
|
__decorate([
|
|
@@ -120,7 +137,10 @@ __decorate([
|
|
|
120
137
|
exports.SecurityService = SecurityService = __decorate([
|
|
121
138
|
(0, common_1.Injectable)(),
|
|
122
139
|
__param(0, (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER)),
|
|
140
|
+
__param(1, (0, common_1.Optional)()),
|
|
123
141
|
__param(1, (0, mongoose_1.InjectModel)(blacklisted_ip_schema_1.BlacklistedIp.name)),
|
|
124
|
-
|
|
142
|
+
__param(2, (0, common_1.Optional)()),
|
|
143
|
+
__param(2, (0, common_1.Inject)('SECURITY_CONFIG')),
|
|
144
|
+
__metadata("design:paramtypes", [Object, mongoose_2.Model, Object])
|
|
125
145
|
], SecurityService);
|
|
126
146
|
//# sourceMappingURL=security.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.service.js","sourceRoot":"","sources":["../../src/services/security.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"security.service.js","sourceRoot":"","sources":["../../src/services/security.service.ts"],"names":[],"mappings":"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"}
|