nestjs-ip-filter 0.1.0
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/.eslintrc.js +29 -0
- package/.prettierrc +4 -0
- package/.vscode/settings.json +3 -0
- package/LICENSE +21 -0
- package/README.md +190 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/ipfilter-core.module.d.ts +24 -0
- package/dist/ipfilter-core.module.js +87 -0
- package/dist/ipfilter-core.module.js.map +1 -0
- package/dist/ipfilter-deny.exception.d.ts +4 -0
- package/dist/ipfilter-deny.exception.js +11 -0
- package/dist/ipfilter-deny.exception.js.map +1 -0
- package/dist/ipfilter.constants.d.ts +2 -0
- package/dist/ipfilter.constants.js +6 -0
- package/dist/ipfilter.constants.js.map +1 -0
- package/dist/ipfilter.guard.d.ts +8 -0
- package/dist/ipfilter.guard.js +57 -0
- package/dist/ipfilter.guard.js.map +1 -0
- package/dist/ipfilter.interface.d.ts +18 -0
- package/dist/ipfilter.interface.js +3 -0
- package/dist/ipfilter.interface.js.map +1 -0
- package/dist/ipfilter.module.d.ts +6 -0
- package/dist/ipfilter.module.js +22 -0
- package/dist/ipfilter.module.js.map +1 -0
- package/dist/ipfilter.providers.d.ts +3 -0
- package/dist/ipfilter.providers.js +13 -0
- package/dist/ipfilter.providers.js.map +1 -0
- package/dist/ipfilter.service.d.ts +12 -0
- package/dist/ipfilter.service.js +45 -0
- package/dist/ipfilter.service.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/index.js +6 -0
- package/index.ts +1 -0
- package/lib/index.ts +8 -0
- package/lib/ipfilter-core.module.ts +94 -0
- package/lib/ipfilter-deny.exception.ts +7 -0
- package/lib/ipfilter.constants.ts +2 -0
- package/lib/ipfilter.guard.ts +56 -0
- package/lib/ipfilter.interface.ts +28 -0
- package/lib/ipfilter.module.ts +23 -0
- package/lib/ipfilter.providers.ts +13 -0
- package/lib/ipfilter.service.ts +37 -0
- package/nest-cli.json +5 -0
- package/package.json +86 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.json +24 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// eslint-disable-next-line no-undef
|
|
2
|
+
module.exports = {
|
|
3
|
+
root: true,
|
|
4
|
+
env: {
|
|
5
|
+
node: true,
|
|
6
|
+
es2017: true,
|
|
7
|
+
},
|
|
8
|
+
extends: [
|
|
9
|
+
'google',
|
|
10
|
+
'eslint:recommended',
|
|
11
|
+
'plugin:@typescript-eslint/recommended',
|
|
12
|
+
'plugin:prettier/recommended',
|
|
13
|
+
],
|
|
14
|
+
parser: '@typescript-eslint/parser',
|
|
15
|
+
parserOptions: {
|
|
16
|
+
ecmaVersion: 8,
|
|
17
|
+
sourceType: 'module',
|
|
18
|
+
tsconfigRootDir: __dirname,
|
|
19
|
+
},
|
|
20
|
+
plugins: ['@typescript-eslint'],
|
|
21
|
+
rules: {
|
|
22
|
+
'@typescript-eslint/interface-name-prefix': 0,
|
|
23
|
+
'@typescript-eslint/explicit-function-return-type': 0,
|
|
24
|
+
'@typescript-eslint/explicit-module-boundary-types': 0,
|
|
25
|
+
'@typescript-eslint/no-explicit-any': 0,
|
|
26
|
+
'new-cap': 0,
|
|
27
|
+
'require-jsdoc': 0,
|
|
28
|
+
},
|
|
29
|
+
};
|
package/.prettierrc
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Deokgyu Yang <secugyu@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# NestJS IP Filter
|
|
2
|
+
|
|
3
|
+
Now we can filter the incoming requests by setting the whitelist and the blacklist IP addresses.
|
|
4
|
+
|
|
5
|
+
It will work using the built-in feature in NestJS, **Guard**, so it works like a charm as it should be and as much as it should do.
|
|
6
|
+
|
|
7
|
+
## How to install
|
|
8
|
+
|
|
9
|
+
Simply, install using NPM by the following command.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install nestjs-ip-filter
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Use Regex for the IP list
|
|
18
|
+
|
|
19
|
+
You can use Regex format string for the IP ranges.
|
|
20
|
+
|
|
21
|
+
For a simple example, if you want to allow the private network hosts in `192.168.0.1/16`, you can write the Regex string like the below.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# 192.168.0.0 ~ 192.168.255.255
|
|
25
|
+
(^192.168.)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Check the other use cases.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# 192.168.0.100 ~ 192.168.0.110
|
|
32
|
+
(^192.168.0.1[0-1]0)
|
|
33
|
+
|
|
34
|
+
# 172.16.16.10, 172.16.17.10, 172.16.18.10
|
|
35
|
+
(^172.16.1[6-8].10)
|
|
36
|
+
|
|
37
|
+
# 110~119.*
|
|
38
|
+
(^11[0-9].*)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
And, writing in this way also works on this pacakge.
|
|
42
|
+
|
|
43
|
+
But be aware of that you should write the Regex string very carefully to avoid allowing unwanted incoming IP addresses.
|
|
44
|
+
|
|
45
|
+
### Baisc usage for Whitelist
|
|
46
|
+
|
|
47
|
+
You can initialize the dedicated Guard using non-async or async mode, as like the other NestJS packages support.
|
|
48
|
+
|
|
49
|
+
Use `forRoot` for the static IP address list.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
IpFilter.forRoot({
|
|
53
|
+
whitelist: [
|
|
54
|
+
'(^::1)',
|
|
55
|
+
'(^192.168.)',
|
|
56
|
+
'127.0.0.1',
|
|
57
|
+
],
|
|
58
|
+
}),
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or, use `forRootAsync` for the provided IP addresses from the other Provider, such as ConfigModule or RepositoryModule for your database.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// If it would like to get the whitelist IPs from a config file,
|
|
65
|
+
// and if MyConfigModule provides that
|
|
66
|
+
|
|
67
|
+
IpFilter.forRootAsync({
|
|
68
|
+
imports: [ MyConfigModule ],
|
|
69
|
+
inject: [ MyConfigService ],
|
|
70
|
+
useFactory: async (myConfigService: MyConfigService) => ({
|
|
71
|
+
whitelist: myConfigService.getWhitelist(),
|
|
72
|
+
}),
|
|
73
|
+
}),
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Yeah, you can use your method to provide some async data.
|
|
77
|
+
|
|
78
|
+
After setting up the `IpFilter` module with the `forRoot*` method, this will accept only the incoming requests for the given whitelist IP addresses.
|
|
79
|
+
|
|
80
|
+
### Blacklist
|
|
81
|
+
|
|
82
|
+
You can deny the requests that are from the blacklist IPs.
|
|
83
|
+
|
|
84
|
+
Use `blacklist` option to let the Guart know the list.
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// If it would like to get the whitelist IPs from a config file,
|
|
88
|
+
// and if MyConfigModule provides that
|
|
89
|
+
|
|
90
|
+
IpFilter.forRootAsync({
|
|
91
|
+
imports: [ MyConfigModule ],
|
|
92
|
+
inject: [ MyConfigService ],
|
|
93
|
+
useFactory: async (myConfigService: MyConfigService) => ({
|
|
94
|
+
whitelist: myConfigService.getWhitelist(),
|
|
95
|
+
blacklist: myConfigService.getBlacklist(),
|
|
96
|
+
}),
|
|
97
|
+
}),
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Then its NestJS Guard will deny all the IPs which are from the blacklist.
|
|
101
|
+
|
|
102
|
+
### Use IpFilterDenyException when denying a request
|
|
103
|
+
|
|
104
|
+
You can handle the denial condition by catching the HTTP exception.
|
|
105
|
+
|
|
106
|
+
If you want to throw that `IpFilterDenyException` when denial, set the option `useDenyException` to `true`.
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// If it would like to get the whitelist IPs from a config file,
|
|
110
|
+
// and if MyConfigModule provides that
|
|
111
|
+
|
|
112
|
+
IpFilter.forRootAsync({
|
|
113
|
+
imports: [ MyConfigModule ],
|
|
114
|
+
inject: [ MyConfigService ],
|
|
115
|
+
useFactory: async (myConfigService: MyConfigService) => ({
|
|
116
|
+
whitelist: myConfigService.getWhitelist(),
|
|
117
|
+
blacklist: myConfigService.getBlacklist(),
|
|
118
|
+
useDenyException: true,
|
|
119
|
+
}),
|
|
120
|
+
}),
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Then it will throw `IpFilterDenyException` when the request is denied for the given whitelist or the blacklist.
|
|
124
|
+
|
|
125
|
+
So that, you can handle the denied request and can send a custom response on that handler, using NestJS **Exception Filter**.
|
|
126
|
+
|
|
127
|
+
When the Guard throws an exception, it will also carry some informative data like the incoming IP address, current whitelist and blacklist.
|
|
128
|
+
|
|
129
|
+
### Inject IpFilterService
|
|
130
|
+
|
|
131
|
+
If you want, you can inject `IpFilterService` into your code and can see current options you put when you initilize it. And, you can set the whitelist and the blacklist too.
|
|
132
|
+
|
|
133
|
+
Inject the service using the `IPFILTER_TOKEN` module.
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
@Injectable()
|
|
137
|
+
export class SomeService {
|
|
138
|
+
constructor(
|
|
139
|
+
@inject(IPFILTER_TOKEN)
|
|
140
|
+
private readonly ipFilterService: IpFilterService
|
|
141
|
+
) {}
|
|
142
|
+
// ...
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Then you can edit the whitelist, blacklist IP addresses dynamically.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
this.ipFilterService.whitelist = [ {NEW_WHITELIST} ];
|
|
150
|
+
this.ipFilterService.blacklist = [ {NEW_BLACKLIST} ];
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Example project
|
|
154
|
+
|
|
155
|
+
This repository contains an example project of this `nestjs-ip-filter` package.
|
|
156
|
+
|
|
157
|
+
Move to `example` directory and run the following commands.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm ci
|
|
161
|
+
npm start:debug
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Then, the example project will run in **3001** port.
|
|
165
|
+
|
|
166
|
+
With the `curl` command, you can do a simple test for the project.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
curl -X GET -H "Content-Type: application/json" http://localhost:3001/ipfilter
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
It will result like the below, if your localhost IP is accepted for the whitelist.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
{"whitelist":["(^::1)","(^192.168.)","127.0.0.1"],"blacklist":[]}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
If it denies, it will result like the below. Check the `ipFilterData` field.
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
{"statusCode":403,"timestamp":"2022-06-13T09:29:40.452Z","ipFilterData":{"clientIp":"::ffff:127.0.0.1","whitelist":["(^::1)","(^192.168.)"],"blacklist":[]},"path":"/ipfilter"}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
[Our exception filter](example/src/exception/ipfilter-exception-filter.exception.ts) put that additional field on the typical HttpException results.
|
|
185
|
+
|
|
186
|
+
You can test the projects with your local host IP address, [by editing the whitelist and the blacklist](example/src/ip-repository/ip-repository.service.ts).
|
|
187
|
+
|
|
188
|
+
## License
|
|
189
|
+
|
|
190
|
+
It follows the [MIT license](LICENSE).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './ipfilter-core.module';
|
|
2
|
+
export * from './ipfilter-deny.exception';
|
|
3
|
+
export * from './ipfilter.constants';
|
|
4
|
+
export * from './ipfilter.guard';
|
|
5
|
+
export * from './ipfilter.interface';
|
|
6
|
+
export * from './ipfilter.module';
|
|
7
|
+
export * from './ipfilter.providers';
|
|
8
|
+
export * from './ipfilter.service';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./ipfilter-core.module"), exports);
|
|
14
|
+
__exportStar(require("./ipfilter-deny.exception"), exports);
|
|
15
|
+
__exportStar(require("./ipfilter.constants"), exports);
|
|
16
|
+
__exportStar(require("./ipfilter.guard"), exports);
|
|
17
|
+
__exportStar(require("./ipfilter.interface"), exports);
|
|
18
|
+
__exportStar(require("./ipfilter.module"), exports);
|
|
19
|
+
__exportStar(require("./ipfilter.providers"), exports);
|
|
20
|
+
__exportStar(require("./ipfilter.service"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yDAAuC;AACvC,4DAA0C;AAC1C,uDAAqC;AACrC,mDAAiC;AACjC,uDAAqC;AACrC,oDAAkC;AAClC,uDAAqC;AACrC,qDAAmC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Provider, Type } from '@nestjs/common';
|
|
2
|
+
import { IpFilterModuleAsyncOptions, IpFilterModuleOptions } from './ipfilter.interface';
|
|
3
|
+
import { IpFilterGuard } from './ipfilter.guard';
|
|
4
|
+
export declare class IpFilterCoreModule {
|
|
5
|
+
static forRoot(options: IpFilterModuleOptions): {
|
|
6
|
+
module: typeof IpFilterCoreModule;
|
|
7
|
+
providers: (Provider<any> | {
|
|
8
|
+
provide: string;
|
|
9
|
+
useClass: typeof IpFilterGuard;
|
|
10
|
+
})[];
|
|
11
|
+
exports: Provider<any>[];
|
|
12
|
+
};
|
|
13
|
+
static forRootAsync(options: IpFilterModuleAsyncOptions): {
|
|
14
|
+
module: typeof IpFilterCoreModule;
|
|
15
|
+
imports: (Type<any> | import("@nestjs/common").DynamicModule | Promise<import("@nestjs/common").DynamicModule> | import("@nestjs/common").ForwardReference<any>)[];
|
|
16
|
+
providers: (Provider<any> | {
|
|
17
|
+
provide: string;
|
|
18
|
+
useClass: typeof IpFilterGuard;
|
|
19
|
+
})[];
|
|
20
|
+
exports: import("@nestjs/common").FactoryProvider<any>[];
|
|
21
|
+
};
|
|
22
|
+
private static createAsyncProviders;
|
|
23
|
+
private static createAsyncOptionsProvider;
|
|
24
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
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 IpFilterCoreModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.IpFilterCoreModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const ipfilter_constants_1 = require("./ipfilter.constants");
|
|
13
|
+
const ipfilter_providers_1 = require("./ipfilter.providers");
|
|
14
|
+
const ipfilter_service_1 = require("./ipfilter.service");
|
|
15
|
+
const core_1 = require("@nestjs/core");
|
|
16
|
+
const ipfilter_guard_1 = require("./ipfilter.guard");
|
|
17
|
+
let IpFilterCoreModule = IpFilterCoreModule_1 = class IpFilterCoreModule {
|
|
18
|
+
static forRoot(options) {
|
|
19
|
+
const ipFilterServiceProvider = (0, ipfilter_providers_1.createIpFilterProviders)(options);
|
|
20
|
+
const ipFilterGuardProvider = {
|
|
21
|
+
provide: core_1.APP_GUARD,
|
|
22
|
+
useClass: ipfilter_guard_1.IpFilterGuard,
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
module: IpFilterCoreModule_1,
|
|
26
|
+
providers: [ipFilterGuardProvider, ipFilterServiceProvider],
|
|
27
|
+
exports: [ipFilterServiceProvider],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
static forRootAsync(options) {
|
|
31
|
+
const provider = {
|
|
32
|
+
inject: [ipfilter_constants_1.IPFILTER_MODULE_OPTIONS],
|
|
33
|
+
provide: ipfilter_constants_1.IPFILTER_TOKEN,
|
|
34
|
+
useFactory: (options) => new ipfilter_service_1.IpFilterService(options),
|
|
35
|
+
};
|
|
36
|
+
const ipFilterGuardProvider = {
|
|
37
|
+
provide: core_1.APP_GUARD,
|
|
38
|
+
useClass: ipfilter_guard_1.IpFilterGuard,
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
module: IpFilterCoreModule_1,
|
|
42
|
+
imports: options.imports,
|
|
43
|
+
providers: [
|
|
44
|
+
...this.createAsyncProviders(options),
|
|
45
|
+
ipFilterGuardProvider,
|
|
46
|
+
provider,
|
|
47
|
+
],
|
|
48
|
+
exports: [provider],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
static createAsyncProviders(options) {
|
|
52
|
+
if (options.useExisting || options.useFactory) {
|
|
53
|
+
return [this.createAsyncOptionsProvider(options)];
|
|
54
|
+
}
|
|
55
|
+
const useClass = options.useClass;
|
|
56
|
+
return [
|
|
57
|
+
this.createAsyncOptionsProvider(options),
|
|
58
|
+
{
|
|
59
|
+
provide: useClass,
|
|
60
|
+
useClass,
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
static createAsyncOptionsProvider(options) {
|
|
65
|
+
if (options.useFactory) {
|
|
66
|
+
return {
|
|
67
|
+
inject: options.inject || [],
|
|
68
|
+
provide: ipfilter_constants_1.IPFILTER_MODULE_OPTIONS,
|
|
69
|
+
useFactory: options.useFactory,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const inject = [
|
|
73
|
+
(options.useClass || options.useExisting),
|
|
74
|
+
];
|
|
75
|
+
return {
|
|
76
|
+
provide: ipfilter_constants_1.IPFILTER_MODULE_OPTIONS,
|
|
77
|
+
useFactory: async (optionsFactory) => await optionsFactory.createIpFilterModuleOptions(),
|
|
78
|
+
inject,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
IpFilterCoreModule = IpFilterCoreModule_1 = __decorate([
|
|
83
|
+
(0, common_1.Global)(),
|
|
84
|
+
(0, common_1.Module)({})
|
|
85
|
+
], IpFilterCoreModule);
|
|
86
|
+
exports.IpFilterCoreModule = IpFilterCoreModule;
|
|
87
|
+
//# sourceMappingURL=ipfilter-core.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipfilter-core.module.js","sourceRoot":"","sources":["../lib/ipfilter-core.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAgE;AAMhE,6DAA+E;AAC/E,6DAA+D;AAC/D,yDAAqD;AACrD,uCAAyC;AACzC,qDAAiD;AAIjD,IAAa,kBAAkB,0BAA/B,MAAa,kBAAkB;IAC7B,MAAM,CAAC,OAAO,CAAC,OAA8B;QAC3C,MAAM,uBAAuB,GAAG,IAAA,4CAAuB,EAAC,OAAO,CAAC,CAAC;QACjE,MAAM,qBAAqB,GAAG;YAC5B,OAAO,EAAE,gBAAS;YAClB,QAAQ,EAAE,8BAAa;SACxB,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,oBAAkB;YAC1B,SAAS,EAAE,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;YAC3D,OAAO,EAAE,CAAC,uBAAuB,CAAC;SACnC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAmC;QACrD,MAAM,QAAQ,GAAa;YACzB,MAAM,EAAE,CAAC,4CAAuB,CAAC;YACjC,OAAO,EAAE,mCAAc;YACvB,UAAU,EAAE,CAAC,OAA8B,EAAE,EAAE,CAC7C,IAAI,kCAAe,CAAC,OAAO,CAAC;SAC/B,CAAC;QACF,MAAM,qBAAqB,GAAG;YAC5B,OAAO,EAAE,gBAAS;YAClB,QAAQ,EAAE,8BAAa;SACxB,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,oBAAkB;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE;gBACT,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;gBACrC,qBAAqB;gBACrB,QAAQ;aACT;YACD,OAAO,EAAE,CAAC,QAAQ,CAAC;SACpB,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,oBAAoB,CACjC,OAAmC;QAEnC,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE;YAC7C,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAAC;SACnD;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAwC,CAAC;QAElE,OAAO;YACL,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC;YACxC;gBACE,OAAO,EAAE,QAAQ;gBACjB,QAAQ;aACT;SACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,0BAA0B,CACvC,OAAmC;QAEnC,IAAI,OAAO,CAAC,UAAU,EAAE;YACtB,OAAO;gBACL,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;gBAC5B,OAAO,EAAE,4CAAuB;gBAChC,UAAU,EAAE,OAAO,CAAC,UAAU;aAC/B,CAAC;SACH;QAED,MAAM,MAAM,GAAG;YACb,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAiC;SAC1E,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,4CAAuB;YAChC,UAAU,EAAE,KAAK,EAAE,cAAsC,EAAE,EAAE,CAC3D,MAAM,cAAc,CAAC,2BAA2B,EAAE;YACpD,MAAM;SACP,CAAC;IACJ,CAAC;CACF,CAAA;AA/EY,kBAAkB;IAF9B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,kBAAkB,CA+E9B;AA/EY,gDAAkB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IpFilterDenyException = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
class IpFilterDenyException extends common_1.HttpException {
|
|
6
|
+
constructor(response, status) {
|
|
7
|
+
super(response, status);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.IpFilterDenyException = IpFilterDenyException;
|
|
11
|
+
//# sourceMappingURL=ipfilter-deny.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipfilter-deny.exception.js","sourceRoot":"","sources":["../lib/ipfilter-deny.exception.ts"],"names":[],"mappings":";;;AAAA,2CAA+C;AAE/C,MAAa,qBAAsB,SAAQ,sBAAa;IACtD,YAAY,QAAsC,EAAE,MAAc;QAChE,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,sDAIC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IPFILTER_TOKEN = exports.IPFILTER_MODULE_OPTIONS = void 0;
|
|
4
|
+
exports.IPFILTER_MODULE_OPTIONS = Symbol('IpFilterModuleOptions');
|
|
5
|
+
exports.IPFILTER_TOKEN = Symbol('IpFilterToken');
|
|
6
|
+
//# sourceMappingURL=ipfilter.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipfilter.constants.js","sourceRoot":"","sources":["../lib/ipfilter.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,uBAAuB,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAC1D,QAAA,cAAc,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { IpFilterService } from './ipfilter.service';
|
|
4
|
+
export declare class IpFilterGuard implements CanActivate {
|
|
5
|
+
private readonly ipFilterService;
|
|
6
|
+
constructor(ipFilterService: IpFilterService);
|
|
7
|
+
canActivate(context: ExecutionContext): Promise<boolean> | Observable<boolean> | boolean;
|
|
8
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
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 __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.IpFilterGuard = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const requestIp = require("@supercharge/request-ip");
|
|
18
|
+
const ipfilter_service_1 = require("./ipfilter.service");
|
|
19
|
+
const ipfilter_constants_1 = require("./ipfilter.constants");
|
|
20
|
+
const ipfilter_deny_exception_1 = require("./ipfilter-deny.exception");
|
|
21
|
+
let IpFilterGuard = class IpFilterGuard {
|
|
22
|
+
constructor(ipFilterService) {
|
|
23
|
+
this.ipFilterService = ipFilterService;
|
|
24
|
+
}
|
|
25
|
+
canActivate(context) {
|
|
26
|
+
const request = context.switchToHttp().getRequest();
|
|
27
|
+
const ipAddress = requestIp.getClientIp(request);
|
|
28
|
+
const whitelist = this.ipFilterService.whitelist;
|
|
29
|
+
const blacklist = this.ipFilterService.blacklist;
|
|
30
|
+
let approved = false;
|
|
31
|
+
if (whitelist.length > 0) {
|
|
32
|
+
approved = whitelist.some((item) => {
|
|
33
|
+
return new RegExp(item).test(ipAddress);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (blacklist.length > 0) {
|
|
37
|
+
approved = !blacklist.some((item) => {
|
|
38
|
+
return new RegExp(item).test(ipAddress);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (!approved && this.ipFilterService.useDenyException) {
|
|
42
|
+
throw new ipfilter_deny_exception_1.IpFilterDenyException({
|
|
43
|
+
clientIp: ipAddress,
|
|
44
|
+
whitelist: whitelist,
|
|
45
|
+
blacklist: blacklist,
|
|
46
|
+
}, 403);
|
|
47
|
+
}
|
|
48
|
+
return approved;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
IpFilterGuard = __decorate([
|
|
52
|
+
(0, common_1.Injectable)(),
|
|
53
|
+
__param(0, (0, common_1.Inject)(ipfilter_constants_1.IPFILTER_TOKEN)),
|
|
54
|
+
__metadata("design:paramtypes", [ipfilter_service_1.IpFilterService])
|
|
55
|
+
], IpFilterGuard);
|
|
56
|
+
exports.IpFilterGuard = IpFilterGuard;
|
|
57
|
+
//# sourceMappingURL=ipfilter.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipfilter.guard.js","sourceRoot":"","sources":["../lib/ipfilter.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAKwB;AAExB,qDAAqD;AACrD,yDAAqD;AACrD,6DAAsD;AACtD,uEAAkE;AAGlE,IAAa,aAAa,GAA1B,MAAa,aAAa;IACxB,YAEmB,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IAChD,CAAC;IAEJ,WAAW,CACT,OAAyB;QAEzB,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,SAAS,GAAW,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAEzD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC;QAEjD,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACxB,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBACjC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;SACJ;QAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACxB,QAAQ,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBAClC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;SACJ;QAED,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE;YACtD,MAAM,IAAI,+CAAqB,CAC7B;gBACE,QAAQ,EAAE,SAAS;gBACnB,SAAS,EAAE,SAAS;gBACpB,SAAS,EAAE,SAAS;aACrB,EACD,GAAG,CACJ,CAAC;SACH;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF,CAAA;AA1CY,aAAa;IADzB,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,mCAAc,CAAC,CAAA;qCACW,kCAAe;GAHxC,aAAa,CA0CzB;AA1CY,sCAAa"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ModuleMetadata, Type } from '@nestjs/common';
|
|
2
|
+
export declare type IpFilterModuleOptions = {
|
|
3
|
+
whitelist?: string[];
|
|
4
|
+
blacklist?: string[];
|
|
5
|
+
useDenyException?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export interface IpFilterDenyHandler {
|
|
8
|
+
handle(): boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface IpFilterOptionsFactory {
|
|
11
|
+
createIpFilterModuleOptions(): Promise<IpFilterModuleOptions> | IpFilterModuleOptions;
|
|
12
|
+
}
|
|
13
|
+
export interface IpFilterModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
14
|
+
inject?: any[];
|
|
15
|
+
useClass?: Type<IpFilterOptionsFactory>;
|
|
16
|
+
useExisting?: Type<IpFilterOptionsFactory>;
|
|
17
|
+
useFactory?: (...args: any[]) => Promise<IpFilterModuleOptions> | IpFilterModuleOptions;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipfilter.interface.js","sourceRoot":"","sources":["../lib/ipfilter.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { IpFilterModuleAsyncOptions, IpFilterModuleOptions } from './ipfilter.interface';
|
|
3
|
+
export declare class IpFilter {
|
|
4
|
+
static forRoot(options: IpFilterModuleOptions): DynamicModule;
|
|
5
|
+
static forRootAsync(options: IpFilterModuleAsyncOptions): DynamicModule;
|
|
6
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IpFilter = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const ipfilter_core_module_1 = require("./ipfilter-core.module");
|
|
6
|
+
(0, common_1.Module)({});
|
|
7
|
+
class IpFilter {
|
|
8
|
+
static forRoot(options) {
|
|
9
|
+
return {
|
|
10
|
+
module: IpFilter,
|
|
11
|
+
imports: [ipfilter_core_module_1.IpFilterCoreModule.forRoot(options)],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
static forRootAsync(options) {
|
|
15
|
+
return {
|
|
16
|
+
module: IpFilter,
|
|
17
|
+
imports: [ipfilter_core_module_1.IpFilterCoreModule.forRootAsync(options)],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.IpFilter = IpFilter;
|
|
22
|
+
//# sourceMappingURL=ipfilter.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipfilter.module.js","sourceRoot":"","sources":["../lib/ipfilter.module.ts"],"names":[],"mappings":";;;AAAA,2CAAuD;AACvD,iEAA4D;AAM5D,IAAA,eAAM,EAAC,EAAE,CAAC,CAAC;AACX,MAAa,QAAQ;IACnB,MAAM,CAAC,OAAO,CAAC,OAA8B;QAC3C,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,CAAC,yCAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAC/C,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAmC;QACrD,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,CAAC,yCAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;SACpD,CAAC;IACJ,CAAC;CACF;AAdD,4BAcC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createIpFilterProviders = void 0;
|
|
4
|
+
const ipfilter_constants_1 = require("./ipfilter.constants");
|
|
5
|
+
const ipfilter_service_1 = require("./ipfilter.service");
|
|
6
|
+
function createIpFilterProviders(options) {
|
|
7
|
+
return {
|
|
8
|
+
provide: ipfilter_constants_1.IPFILTER_TOKEN,
|
|
9
|
+
useValue: new ipfilter_service_1.IpFilterService(options),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
exports.createIpFilterProviders = createIpFilterProviders;
|
|
13
|
+
//# sourceMappingURL=ipfilter.providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipfilter.providers.js","sourceRoot":"","sources":["../lib/ipfilter.providers.ts"],"names":[],"mappings":";;;AAEA,6DAAsD;AACtD,yDAAqD;AAErD,SAAgB,uBAAuB,CACrC,OAA8B;IAE9B,OAAO;QACL,OAAO,EAAE,mCAAc;QACvB,QAAQ,EAAE,IAAI,kCAAe,CAAC,OAAO,CAAC;KACvC,CAAC;AACJ,CAAC;AAPD,0DAOC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IpFilterModuleOptions } from './ipfilter.interface';
|
|
2
|
+
export declare class IpFilterService {
|
|
3
|
+
readonly options: IpFilterModuleOptions;
|
|
4
|
+
useDenyException: boolean;
|
|
5
|
+
private _whitelist;
|
|
6
|
+
private _blacklist;
|
|
7
|
+
constructor(options: IpFilterModuleOptions);
|
|
8
|
+
get whitelist(): string[];
|
|
9
|
+
set whitelist(whitelist: string[]);
|
|
10
|
+
get blacklist(): string[];
|
|
11
|
+
set blacklist(blacklist: string[]);
|
|
12
|
+
}
|