1 | ;
|
2 |
|
3 | const ipRegex = require('ip-regex');
|
4 | const micromatch = require('micromatch');
|
5 | const toPath = require('to-file-path');
|
6 |
|
7 | /**
|
8 | * Filter `ip` against glob `patterns`, using [micromatch][] under the hood,
|
9 | * so `options` are passed to it.
|
10 | *
|
11 | * @example
|
12 | * const ipFilter = require('ip-filter');
|
13 | *
|
14 | * console.log(ipFilter('123.77.34.89', '123.??.34.8*')); // => '123.77.34.89'
|
15 | * console.log(ipFilter('123.222.34.88', '123.??.34.8*')); // => null
|
16 | * console.log(ipFilter('123.222.33.1', ['123.*.34.*', '*.222.33.*'])); // => '123.222.33.1'
|
17 | *
|
18 | * // should notice the difference
|
19 | * console.log(ipFilter('123.222.34.88', ['123.*.34.*', '!123.222.**']));
|
20 | * // => null
|
21 | * console.log(ipFilter('123.222.34.88', ['123.*.34.*', '!123.222.*']));
|
22 | * // => '123.222.34.88'
|
23 | *
|
24 | * @example
|
25 | * const ipFilter = require('ip-filter');
|
26 | * //
|
27 | * // NON-STRICT mode
|
28 | * //
|
29 | *
|
30 | * const res = ipFilter('x-koaip', ['*-koaip', '!foo-koa*'], { strict: false });
|
31 | * console.log(res); // => 'x-koaip'
|
32 | *
|
33 | * const res = ipFilter('x-koa.foo', ['*-koa.*', '!foo-koa.*'], { strict: false });
|
34 | * console.log(res); // => 'x-koa.foo'
|
35 | *
|
36 | * @name ipFilter
|
37 | * @param {string} `ip` Accepts only valid IPs by default
|
38 | * @param {string|array} `patterns` Basically everything that [micromatch][]'s second argument can accept.
|
39 | * @param {object} `options` Pass `strict: false` if want to validate non-ip values,
|
40 | * options are also passed to [micromatch][].
|
41 | * @return {string} a `string` or `null` - If not match returns `null`, otherwise the passed `ip` as string.
|
42 | * @api public
|
43 | */
|
44 | module.exports = function ipFilter(ip, patterns, options) {
|
45 | if (typeof ip !== 'string') {
|
46 | throw new TypeError('ip-filter: expect `ip` to be a string');
|
47 | }
|
48 |
|
49 | const opts = { ...options };
|
50 | opts.strict = typeof opts.strict === 'boolean' ? opts.strict : true;
|
51 |
|
52 | if (opts.strict && !ipRegex().test(ip)) {
|
53 | throw new Error('ip-filter: expect only valid IPs when `opts.strict` mode');
|
54 | }
|
55 |
|
56 | const id = opts.strict ? tofp(ip) : ip;
|
57 | const globs = opts.strict ? tofp(patterns) : patterns;
|
58 |
|
59 | const matches = micromatch(id, globs, opts);
|
60 | return matches.length > 0 ? ip : null;
|
61 | };
|
62 |
|
63 | function tofp(val) {
|
64 | const value = typeof val === 'string' ? toPath(val) : val;
|
65 | return Array.isArray(value) ? value.map((p) => toPath(p)) : value;
|
66 | }
|