Initial commit
This commit is contained in:
959
node_modules/express-rate-limit/dist/index.cjs
generated
vendored
Normal file
959
node_modules/express-rate-limit/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,959 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// source/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
MemoryStore: () => MemoryStore,
|
||||
default: () => rate_limit_default,
|
||||
ipKeyGenerator: () => ipKeyGenerator,
|
||||
rateLimit: () => rate_limit_default
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// source/ip-key-generator.ts
|
||||
var import_node_net = require("node:net");
|
||||
var import_ip_address = require("ip-address");
|
||||
function ipKeyGenerator(ip, ipv6Subnet = 56) {
|
||||
if (ipv6Subnet && (0, import_node_net.isIPv6)(ip)) {
|
||||
return `${new import_ip_address.Address6(`${ip}/${ipv6Subnet}`).startAddress().correctForm()}/${ipv6Subnet}`;
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
// source/memory-store.ts
|
||||
var MemoryStore = class {
|
||||
constructor(validations2) {
|
||||
this.validations = validations2;
|
||||
/**
|
||||
* These two maps store usage (requests) and reset time by key (for example, IP
|
||||
* addresses or API keys).
|
||||
*
|
||||
* They are split into two to avoid having to iterate through the entire set to
|
||||
* determine which ones need reset. Instead, `Client`s are moved from `previous`
|
||||
* to `current` as they hit the endpoint. Once `windowMs` has elapsed, all clients
|
||||
* left in `previous`, i.e., those that have not made any recent requests, are
|
||||
* known to be expired and can be deleted in bulk.
|
||||
*/
|
||||
this.previous = /* @__PURE__ */ new Map();
|
||||
this.current = /* @__PURE__ */ new Map();
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
this.localKeys = true;
|
||||
}
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options) {
|
||||
this.windowMs = options.windowMs;
|
||||
this.validations?.windowMs(this.windowMs);
|
||||
if (this.interval) clearInterval(this.interval);
|
||||
this.interval = setInterval(() => {
|
||||
this.clearExpired();
|
||||
}, this.windowMs);
|
||||
this.interval.unref?.();
|
||||
}
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async get(key) {
|
||||
return this.current.get(key) ?? this.previous.get(key);
|
||||
}
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async increment(key) {
|
||||
const client = this.getClient(key);
|
||||
const now = Date.now();
|
||||
if (client.resetTime.getTime() <= now) {
|
||||
this.resetClient(client, now);
|
||||
}
|
||||
client.totalHits++;
|
||||
return client;
|
||||
}
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async decrement(key) {
|
||||
const client = this.getClient(key);
|
||||
if (client.totalHits > 0) client.totalHits--;
|
||||
}
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async resetKey(key) {
|
||||
this.current.delete(key);
|
||||
this.previous.delete(key);
|
||||
}
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async resetAll() {
|
||||
this.current.clear();
|
||||
this.previous.clear();
|
||||
}
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown() {
|
||||
clearInterval(this.interval);
|
||||
void this.resetAll();
|
||||
}
|
||||
/**
|
||||
* Recycles a client by setting its hit count to zero, and reset time to
|
||||
* `windowMs` milliseconds from now.
|
||||
*
|
||||
* NOT to be confused with `#resetKey()`, which removes a client from both the
|
||||
* `current` and `previous` maps.
|
||||
*
|
||||
* @param client {Client} - The client to recycle.
|
||||
* @param now {number} - The current time, to which the `windowMs` is added to get the `resetTime` for the client.
|
||||
*
|
||||
* @return {Client} - The modified client that was passed in, to allow for chaining.
|
||||
*/
|
||||
resetClient(client, now = Date.now()) {
|
||||
client.totalHits = 0;
|
||||
client.resetTime.setTime(now + this.windowMs);
|
||||
return client;
|
||||
}
|
||||
/**
|
||||
* Retrieves or creates a client, given a key. Also ensures that the client being
|
||||
* returned is in the `current` map.
|
||||
*
|
||||
* @param key {string} - The key under which the client is (or is to be) stored.
|
||||
*
|
||||
* @returns {Client} - The requested client.
|
||||
*/
|
||||
getClient(key) {
|
||||
if (this.current.has(key)) return this.current.get(key);
|
||||
let client;
|
||||
if (this.previous.has(key)) {
|
||||
client = this.previous.get(key);
|
||||
this.previous.delete(key);
|
||||
} else {
|
||||
client = { totalHits: 0, resetTime: /* @__PURE__ */ new Date() };
|
||||
this.resetClient(client);
|
||||
}
|
||||
this.current.set(key, client);
|
||||
return client;
|
||||
}
|
||||
/**
|
||||
* Move current clients to previous, create a new map for current.
|
||||
*
|
||||
* This function is called every `windowMs`.
|
||||
*/
|
||||
clearExpired() {
|
||||
this.previous = this.current;
|
||||
this.current = /* @__PURE__ */ new Map();
|
||||
}
|
||||
};
|
||||
|
||||
// source/rate-limit.ts
|
||||
var import_node_net3 = require("node:net");
|
||||
|
||||
// source/headers.ts
|
||||
var import_node_buffer = require("node:buffer");
|
||||
var import_node_crypto = require("node:crypto");
|
||||
var SUPPORTED_DRAFT_VERSIONS = [
|
||||
"draft-6",
|
||||
"draft-7",
|
||||
"draft-8"
|
||||
];
|
||||
var getResetSeconds = (windowMs, resetTime) => {
|
||||
let resetSeconds;
|
||||
if (resetTime) {
|
||||
const deltaSeconds = Math.ceil((resetTime.getTime() - Date.now()) / 1e3);
|
||||
resetSeconds = Math.max(0, deltaSeconds);
|
||||
} else {
|
||||
resetSeconds = Math.ceil(windowMs / 1e3);
|
||||
}
|
||||
return resetSeconds;
|
||||
};
|
||||
var getPartitionKey = (key) => {
|
||||
const hash = (0, import_node_crypto.createHash)("sha256");
|
||||
hash.update(key);
|
||||
const partitionKey = hash.digest("hex").slice(0, 12);
|
||||
return import_node_buffer.Buffer.from(partitionKey).toString("base64");
|
||||
};
|
||||
var setLegacyHeaders = (response, info) => {
|
||||
if (response.headersSent) return;
|
||||
response.setHeader("X-RateLimit-Limit", info.limit.toString());
|
||||
response.setHeader("X-RateLimit-Remaining", info.remaining.toString());
|
||||
if (info.resetTime instanceof Date) {
|
||||
response.setHeader("Date", (/* @__PURE__ */ new Date()).toUTCString());
|
||||
response.setHeader(
|
||||
"X-RateLimit-Reset",
|
||||
Math.ceil(info.resetTime.getTime() / 1e3).toString()
|
||||
);
|
||||
}
|
||||
};
|
||||
var setDraft6Headers = (response, info, windowMs) => {
|
||||
if (response.headersSent) return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
||||
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
||||
response.setHeader("RateLimit-Limit", info.limit.toString());
|
||||
response.setHeader("RateLimit-Remaining", info.remaining.toString());
|
||||
if (typeof resetSeconds === "number")
|
||||
response.setHeader("RateLimit-Reset", resetSeconds.toString());
|
||||
};
|
||||
var setDraft7Headers = (response, info, windowMs) => {
|
||||
if (response.headersSent) return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
||||
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
||||
response.setHeader(
|
||||
"RateLimit",
|
||||
`limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`
|
||||
);
|
||||
};
|
||||
var setDraft8Headers = (response, info, windowMs, name, key) => {
|
||||
if (response.headersSent) return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
||||
const partitionKey = getPartitionKey(key);
|
||||
const header = `r=${info.remaining}; t=${resetSeconds}`;
|
||||
const policy = `q=${info.limit}; w=${windowSeconds}; pk=:${partitionKey}:`;
|
||||
response.append("RateLimit", `"${name}"; ${header}`);
|
||||
response.append("RateLimit-Policy", `"${name}"; ${policy}`);
|
||||
};
|
||||
var setRetryAfterHeader = (response, info, windowMs) => {
|
||||
if (response.headersSent) return;
|
||||
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
||||
response.setHeader("Retry-After", resetSeconds.toString());
|
||||
};
|
||||
|
||||
// source/utils.ts
|
||||
var omitUndefinedProperties = (passedOptions) => {
|
||||
const omittedOptions = {};
|
||||
for (const k of Object.keys(passedOptions)) {
|
||||
const key = k;
|
||||
if (passedOptions[key] !== void 0) {
|
||||
omittedOptions[key] = passedOptions[key];
|
||||
}
|
||||
}
|
||||
return omittedOptions;
|
||||
};
|
||||
|
||||
// source/validations.ts
|
||||
var import_node_net2 = require("node:net");
|
||||
var ValidationError = class extends Error {
|
||||
/**
|
||||
* The code must be a string, in snake case and all capital, that starts with
|
||||
* the substring `ERR_ERL_`.
|
||||
*
|
||||
* The message must be a string, starting with an uppercase character,
|
||||
* describing the issue in detail.
|
||||
*/
|
||||
constructor(code, message) {
|
||||
const url = `https://express-rate-limit.github.io/${code}/`;
|
||||
super(`${message} See ${url} for more information.`);
|
||||
this.name = this.constructor.name;
|
||||
this.code = code;
|
||||
this.help = url;
|
||||
}
|
||||
};
|
||||
var ChangeWarning = class extends ValidationError {
|
||||
};
|
||||
var usedStores = /* @__PURE__ */ new Set();
|
||||
var singleCountKeys = /* @__PURE__ */ new WeakMap();
|
||||
var validations = {
|
||||
enabled: {
|
||||
default: true
|
||||
},
|
||||
// Should be EnabledValidations type, but that's a circular reference
|
||||
disable() {
|
||||
for (const k of Object.keys(this.enabled)) this.enabled[k] = false;
|
||||
},
|
||||
/**
|
||||
* Checks whether the IP address is valid, and that it does not have a port
|
||||
* number in it.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.
|
||||
*
|
||||
* @param ip {string | undefined} - The IP address provided by Express as request.ip.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
ip(ip) {
|
||||
if (ip === void 0) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNDEFINED_IP_ADDRESS",
|
||||
`An undefined 'request.ip' was detected. This might indicate a misconfiguration or the connection being destroyed prematurely.`
|
||||
);
|
||||
}
|
||||
if (!(0, import_node_net2.isIP)(ip)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_INVALID_IP_ADDRESS",
|
||||
`An invalid 'request.ip' (${ip}) was detected. Consider passing a custom 'keyGenerator' function to the rate limiter.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Makes sure the trust proxy setting is not set to `true`.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
trustProxy(request) {
|
||||
if (request.app.get("trust proxy") === true) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_PERMISSIVE_TRUST_PROXY",
|
||||
`The Express 'trust proxy' setting is true, which allows anyone to trivially bypass IP-based rate limiting.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Makes sure the trust proxy setting is set in case the `X-Forwarded-For`
|
||||
* header is present.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
xForwardedForHeader(request) {
|
||||
if (request.headers["x-forwarded-for"] && request.app.get("trust proxy") === false) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNEXPECTED_X_FORWARDED_FOR",
|
||||
`The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
forwardedHeader(request) {
|
||||
if (request.headers.forwarded && request.ip === request.socket?.remoteAddress) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_FORWARDED_HEADER",
|
||||
`The 'Forwarded' header (standardized X-Forwarded-For) is set but currently being ignored. Add a custom keyGenerator to use a value from this header.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Ensures totalHits value from store is a positive integer.
|
||||
*
|
||||
* @param hits {any} - The `totalHits` returned by the store.
|
||||
*/
|
||||
positiveHits(hits) {
|
||||
if (typeof hits !== "number" || hits < 1 || hits !== Math.round(hits)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_INVALID_HITS",
|
||||
`The totalHits value returned from the store must be a positive integer, got ${hits}`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Ensures a single store instance is not used with multiple express-rate-limit instances
|
||||
*/
|
||||
unsharedStore(store) {
|
||||
if (usedStores.has(store)) {
|
||||
const maybeUniquePrefix = store?.localKeys ? "" : " (with a unique prefix)";
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_STORE_REUSE",
|
||||
`A Store instance must not be shared across multiple rate limiters. Create a new instance of ${store.constructor.name}${maybeUniquePrefix} for each limiter instead.`
|
||||
);
|
||||
}
|
||||
usedStores.add(store);
|
||||
},
|
||||
/**
|
||||
* Ensures a given key is incremented only once per request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param store {Store} - The store class.
|
||||
* @param key {string} - The key used to store the client's hit count.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
singleCount(request, store, key) {
|
||||
let storeKeys = singleCountKeys.get(request);
|
||||
if (!storeKeys) {
|
||||
storeKeys = /* @__PURE__ */ new Map();
|
||||
singleCountKeys.set(request, storeKeys);
|
||||
}
|
||||
const storeKey = store.localKeys ? store : store.constructor.name;
|
||||
let keys = storeKeys.get(storeKey);
|
||||
if (!keys) {
|
||||
keys = [];
|
||||
storeKeys.set(storeKey, keys);
|
||||
}
|
||||
const prefixedKey = `${store.prefix ?? ""}${key}`;
|
||||
if (keys.includes(prefixedKey)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_DOUBLE_COUNT",
|
||||
`The hit count for ${key} was incremented more than once for a single request.`
|
||||
);
|
||||
}
|
||||
keys.push(prefixedKey);
|
||||
},
|
||||
/**
|
||||
* Warns the user that the behaviour for `max: 0` / `limit: 0` is
|
||||
* changing in the next major release.
|
||||
*
|
||||
* @param limit {number} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
limit(limit) {
|
||||
if (limit === 0) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_MAX_ZERO",
|
||||
"Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7"
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Warns the user that the `draft_polli_ratelimit_headers` option is deprecated
|
||||
* and will be removed in the next major release.
|
||||
*
|
||||
* @param draft_polli_ratelimit_headers {any | undefined} - The now-deprecated setting that was used to enable standard headers.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
draftPolliHeaders(draft_polli_ratelimit_headers) {
|
||||
if (draft_polli_ratelimit_headers) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_DEPRECATED_DRAFT_POLLI_HEADERS",
|
||||
`The draft_polli_ratelimit_headers configuration option is deprecated and has been removed in express-rate-limit v7, please set standardHeaders: 'draft-6' instead.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Warns the user that the `onLimitReached` option is deprecated and
|
||||
* will be removed in the next major release.
|
||||
*
|
||||
* @param onLimitReached {any | undefined} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onLimitReached(onLimitReached) {
|
||||
if (onLimitReached) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_DEPRECATED_ON_LIMIT_REACHED",
|
||||
"The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7."
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
||||
*
|
||||
* @param version {any | undefined} - The version passed by the user.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersDraftVersion(version) {
|
||||
if (typeof version !== "string" || // @ts-expect-error This is fine. If version is not in the array, it will just return false.
|
||||
!SUPPORTED_DRAFT_VERSIONS.includes(version)) {
|
||||
const versionString = SUPPORTED_DRAFT_VERSIONS.join(", ");
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION",
|
||||
`standardHeaders: only the following versions of the IETF draft specification are supported: ${versionString}.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Warns the user when the selected headers option requires a reset time but
|
||||
* the store does not provide one.
|
||||
*
|
||||
* @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersResetTime(resetTime) {
|
||||
if (!resetTime) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_HEADERS_NO_RESET",
|
||||
`standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.`
|
||||
);
|
||||
}
|
||||
},
|
||||
knownOptions(passedOptions) {
|
||||
if (!passedOptions) return;
|
||||
const optionsMap = {
|
||||
windowMs: true,
|
||||
limit: true,
|
||||
message: true,
|
||||
statusCode: true,
|
||||
legacyHeaders: true,
|
||||
standardHeaders: true,
|
||||
identifier: true,
|
||||
requestPropertyName: true,
|
||||
skipFailedRequests: true,
|
||||
skipSuccessfulRequests: true,
|
||||
keyGenerator: true,
|
||||
ipv6Subnet: true,
|
||||
handler: true,
|
||||
skip: true,
|
||||
requestWasSuccessful: true,
|
||||
store: true,
|
||||
validate: true,
|
||||
headers: true,
|
||||
max: true,
|
||||
passOnStoreError: true
|
||||
};
|
||||
const validOptions = Object.keys(optionsMap).concat(
|
||||
"draft_polli_ratelimit_headers",
|
||||
// not a valid option anymore, but we have a more specific check for this one, so don't warn for it here
|
||||
// from express-slow-down - https://github.com/express-rate-limit/express-slow-down/blob/main/source/types.ts#L65
|
||||
"delayAfter",
|
||||
"delayMs",
|
||||
"maxDelayMs"
|
||||
);
|
||||
for (const key of Object.keys(passedOptions)) {
|
||||
if (!validOptions.includes(key)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNKNOWN_OPTION",
|
||||
`Unexpected configuration option: ${key}`
|
||||
// todo: suggest a valid option with a short levenstein distance?
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Checks the options.validate setting to ensure that only recognized
|
||||
* validations are enabled or disabled.
|
||||
*
|
||||
* If any unrecognized values are found, an error is logged that
|
||||
* includes the list of supported validations.
|
||||
*/
|
||||
validationsConfig() {
|
||||
const supportedValidations = Object.keys(this).filter(
|
||||
(k) => !["enabled", "disable"].includes(k)
|
||||
);
|
||||
supportedValidations.push("default");
|
||||
for (const key of Object.keys(this.enabled)) {
|
||||
if (!supportedValidations.includes(key)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNKNOWN_VALIDATION",
|
||||
`options.validate.${key} is not recognized. Supported validate options are: ${supportedValidations.join(
|
||||
", "
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Checks to see if the instance was created inside of a request handler,
|
||||
* which would prevent it from working correctly, with the default memory
|
||||
* store (or any other store with localKeys.)
|
||||
*/
|
||||
creationStack(store) {
|
||||
const { stack } = new Error(
|
||||
"express-rate-limit validation check (set options.validate.creationStack=false to disable)"
|
||||
);
|
||||
if (stack?.includes("Layer.handle [as handle_request]") || // express v4
|
||||
stack?.includes("Layer.handleRequest")) {
|
||||
if (!store.localKeys) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_CREATED_IN_REQUEST_HANDLER",
|
||||
"express-rate-limit instance should *usually* be created at app initialization, not when responding to a request."
|
||||
);
|
||||
}
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_CREATED_IN_REQUEST_HANDLER",
|
||||
"express-rate-limit instance should be created at app initialization, not when responding to a request."
|
||||
);
|
||||
}
|
||||
},
|
||||
ipv6Subnet(ipv6Subnet) {
|
||||
if (ipv6Subnet === false) {
|
||||
return;
|
||||
}
|
||||
if (!Number.isInteger(ipv6Subnet) || ipv6Subnet < 32 || ipv6Subnet > 64) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_IPV6_SUBNET",
|
||||
`Unexpected ipv6Subnet value: ${ipv6Subnet}. Expected an integer between 32 and 64 (usually 48-64).`
|
||||
);
|
||||
}
|
||||
},
|
||||
ipv6SubnetOrKeyGenerator(options) {
|
||||
if (options.ipv6Subnet !== void 0 && options.keyGenerator) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_IPV6SUBNET_OR_KEYGENERATOR",
|
||||
`Incompatible options: the 'ipv6Subnet' option is ignored when a custom 'keyGenerator' function is also set.`
|
||||
);
|
||||
}
|
||||
},
|
||||
keyGeneratorIpFallback(keyGenerator) {
|
||||
if (!keyGenerator) {
|
||||
return;
|
||||
}
|
||||
const src = keyGenerator.toString();
|
||||
if ((src.includes("req.ip") || src.includes("request.ip")) && !src.includes("ipKeyGenerator")) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_KEY_GEN_IPV6",
|
||||
"Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits."
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Checks to see if the window duration is greater than 2^32 - 1. This is only
|
||||
* called by the default MemoryStore, since it uses Node's setInterval method.
|
||||
*
|
||||
* See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
|
||||
*/
|
||||
windowMs(windowMs) {
|
||||
const SET_TIMEOUT_MAX = 2 ** 31 - 1;
|
||||
if (typeof windowMs !== "number" || Number.isNaN(windowMs) || windowMs < 1 || windowMs > SET_TIMEOUT_MAX) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_WINDOW_MS",
|
||||
`Invalid windowMs value: ${windowMs}${typeof windowMs !== "number" ? ` (${typeof windowMs})` : ""}, must be a number between 1 and ${SET_TIMEOUT_MAX} when using the default MemoryStore`
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
var getValidations = (_enabled) => {
|
||||
let enabled;
|
||||
if (typeof _enabled === "boolean") {
|
||||
enabled = {
|
||||
default: _enabled
|
||||
};
|
||||
} else {
|
||||
enabled = {
|
||||
default: true,
|
||||
..._enabled
|
||||
};
|
||||
}
|
||||
const wrappedValidations = { enabled };
|
||||
for (const [name, validation] of Object.entries(validations)) {
|
||||
if (typeof validation === "function")
|
||||
wrappedValidations[name] = (...args) => {
|
||||
if (!(enabled[name] ?? enabled.default)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
;
|
||||
validation.apply(
|
||||
wrappedValidations,
|
||||
args
|
||||
);
|
||||
} catch (error) {
|
||||
if (error instanceof ChangeWarning) console.warn(error);
|
||||
else console.error(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
return wrappedValidations;
|
||||
};
|
||||
|
||||
// source/rate-limit.ts
|
||||
var isLegacyStore = (store) => (
|
||||
// Check that `incr` exists but `increment` does not - store authors might want
|
||||
// to keep both around for backwards compatibility.
|
||||
typeof store.incr === "function" && typeof store.increment !== "function"
|
||||
);
|
||||
var promisifyStore = (passedStore) => {
|
||||
if (!isLegacyStore(passedStore)) {
|
||||
return passedStore;
|
||||
}
|
||||
const legacyStore = passedStore;
|
||||
class PromisifiedStore {
|
||||
async increment(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
legacyStore.incr(
|
||||
key,
|
||||
(error, totalHits, resetTime) => {
|
||||
if (error) reject(error);
|
||||
resolve({ totalHits, resetTime });
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
async decrement(key) {
|
||||
return legacyStore.decrement(key);
|
||||
}
|
||||
async resetKey(key) {
|
||||
return legacyStore.resetKey(key);
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
async resetAll() {
|
||||
if (typeof legacyStore.resetAll === "function")
|
||||
return legacyStore.resetAll();
|
||||
}
|
||||
}
|
||||
return new PromisifiedStore();
|
||||
};
|
||||
var getOptionsFromConfig = (config) => {
|
||||
const { validations: validations2, ...directlyPassableEntries } = config;
|
||||
return {
|
||||
...directlyPassableEntries,
|
||||
validate: validations2.enabled
|
||||
};
|
||||
};
|
||||
var parseOptions = (passedOptions) => {
|
||||
const notUndefinedOptions = omitUndefinedProperties(passedOptions);
|
||||
const validations2 = getValidations(notUndefinedOptions?.validate ?? true);
|
||||
validations2.validationsConfig();
|
||||
validations2.knownOptions(passedOptions);
|
||||
validations2.draftPolliHeaders(
|
||||
// @ts-expect-error see the note above.
|
||||
notUndefinedOptions.draft_polli_ratelimit_headers
|
||||
);
|
||||
validations2.onLimitReached(notUndefinedOptions.onLimitReached);
|
||||
if (notUndefinedOptions.ipv6Subnet !== void 0 && typeof notUndefinedOptions.ipv6Subnet !== "function") {
|
||||
validations2.ipv6Subnet(notUndefinedOptions.ipv6Subnet);
|
||||
}
|
||||
validations2.keyGeneratorIpFallback(notUndefinedOptions.keyGenerator);
|
||||
validations2.ipv6SubnetOrKeyGenerator(notUndefinedOptions);
|
||||
let standardHeaders = notUndefinedOptions.standardHeaders ?? false;
|
||||
if (standardHeaders === true) standardHeaders = "draft-6";
|
||||
const config = {
|
||||
windowMs: 60 * 1e3,
|
||||
limit: passedOptions.max ?? 5,
|
||||
// `max` is deprecated, but support it anyways.
|
||||
message: "Too many requests, please try again later.",
|
||||
statusCode: 429,
|
||||
legacyHeaders: passedOptions.headers ?? true,
|
||||
identifier(request, _response) {
|
||||
let duration = "";
|
||||
const property = config.requestPropertyName;
|
||||
const { limit } = request[property];
|
||||
const seconds = config.windowMs / 1e3;
|
||||
const minutes = config.windowMs / (1e3 * 60);
|
||||
const hours = config.windowMs / (1e3 * 60 * 60);
|
||||
const days = config.windowMs / (1e3 * 60 * 60 * 24);
|
||||
if (seconds < 60) duration = `${seconds}sec`;
|
||||
else if (minutes < 60) duration = `${minutes}min`;
|
||||
else if (hours < 24) duration = `${hours}hr${hours > 1 ? "s" : ""}`;
|
||||
else duration = `${days}day${days > 1 ? "s" : ""}`;
|
||||
return `${limit}-in-${duration}`;
|
||||
},
|
||||
requestPropertyName: "rateLimit",
|
||||
skipFailedRequests: false,
|
||||
skipSuccessfulRequests: false,
|
||||
requestWasSuccessful: (_request, response) => response.statusCode < 400,
|
||||
skip: (_request, _response) => false,
|
||||
async keyGenerator(request, response) {
|
||||
validations2.ip(request.ip);
|
||||
validations2.trustProxy(request);
|
||||
validations2.xForwardedForHeader(request);
|
||||
validations2.forwardedHeader(request);
|
||||
const ip = request.ip;
|
||||
let subnet = 56;
|
||||
if ((0, import_node_net3.isIPv6)(ip)) {
|
||||
subnet = typeof config.ipv6Subnet === "function" ? await config.ipv6Subnet(request, response) : config.ipv6Subnet;
|
||||
if (typeof config.ipv6Subnet === "function")
|
||||
validations2.ipv6Subnet(subnet);
|
||||
}
|
||||
return ipKeyGenerator(ip, subnet);
|
||||
},
|
||||
ipv6Subnet: 56,
|
||||
async handler(request, response, _next, _optionsUsed) {
|
||||
response.status(config.statusCode);
|
||||
const message = typeof config.message === "function" ? await config.message(
|
||||
request,
|
||||
response
|
||||
) : config.message;
|
||||
if (!response.writableEnded) response.send(message);
|
||||
},
|
||||
passOnStoreError: false,
|
||||
// Allow the default options to be overridden by the passed options.
|
||||
...notUndefinedOptions,
|
||||
// `standardHeaders` is resolved into a draft version above, use that.
|
||||
standardHeaders,
|
||||
// Note that this field is declared after the user's options are spread in,
|
||||
// so that this field doesn't get overridden with an un-promisified store!
|
||||
store: promisifyStore(
|
||||
notUndefinedOptions.store ?? new MemoryStore(validations2)
|
||||
),
|
||||
// Print an error to the console if a few known misconfigurations are detected.
|
||||
validations: validations2
|
||||
};
|
||||
if (typeof config.store.increment !== "function" || typeof config.store.decrement !== "function" || typeof config.store.resetKey !== "function" || config.store.resetAll !== void 0 && typeof config.store.resetAll !== "function" || config.store.init !== void 0 && typeof config.store.init !== "function") {
|
||||
throw new TypeError(
|
||||
"An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface."
|
||||
);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
var handleAsyncErrors = (fn) => async (request, response, next) => {
|
||||
try {
|
||||
await Promise.resolve(fn(request, response, next)).catch(next);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
var rateLimit = (passedOptions) => {
|
||||
const config = parseOptions(passedOptions ?? {});
|
||||
const options = getOptionsFromConfig(config);
|
||||
config.validations.creationStack(config.store);
|
||||
config.validations.unsharedStore(config.store);
|
||||
if (typeof config.store.init === "function") config.store.init(options);
|
||||
const middleware = handleAsyncErrors(
|
||||
async (request, response, next) => {
|
||||
const skip = await config.skip(request, response);
|
||||
if (skip) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const augmentedRequest = request;
|
||||
const key = await config.keyGenerator(request, response);
|
||||
let totalHits = 0;
|
||||
let resetTime;
|
||||
try {
|
||||
const incrementResult = await config.store.increment(key);
|
||||
totalHits = incrementResult.totalHits;
|
||||
resetTime = incrementResult.resetTime;
|
||||
} catch (error) {
|
||||
if (config.passOnStoreError) {
|
||||
console.error(
|
||||
"express-rate-limit: error from store, allowing request without rate-limiting.",
|
||||
error
|
||||
);
|
||||
next();
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
config.validations.positiveHits(totalHits);
|
||||
config.validations.singleCount(request, config.store, key);
|
||||
const retrieveLimit = typeof config.limit === "function" ? config.limit(request, response) : config.limit;
|
||||
const limit = await retrieveLimit;
|
||||
config.validations.limit(limit);
|
||||
const info = {
|
||||
limit,
|
||||
used: totalHits,
|
||||
remaining: Math.max(limit - totalHits, 0),
|
||||
resetTime,
|
||||
key
|
||||
};
|
||||
Object.defineProperty(info, "current", {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
value: totalHits
|
||||
});
|
||||
augmentedRequest[config.requestPropertyName] = info;
|
||||
if (config.legacyHeaders && !response.headersSent) {
|
||||
setLegacyHeaders(response, info);
|
||||
}
|
||||
if (config.standardHeaders && !response.headersSent) {
|
||||
switch (config.standardHeaders) {
|
||||
case "draft-6": {
|
||||
setDraft6Headers(response, info, config.windowMs);
|
||||
break;
|
||||
}
|
||||
case "draft-7": {
|
||||
config.validations.headersResetTime(info.resetTime);
|
||||
setDraft7Headers(response, info, config.windowMs);
|
||||
break;
|
||||
}
|
||||
case "draft-8": {
|
||||
const retrieveName = typeof config.identifier === "function" ? config.identifier(request, response) : config.identifier;
|
||||
const name = await retrieveName;
|
||||
config.validations.headersResetTime(info.resetTime);
|
||||
setDraft8Headers(response, info, config.windowMs, name, key);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
config.validations.headersDraftVersion(config.standardHeaders);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.skipFailedRequests || config.skipSuccessfulRequests) {
|
||||
let decremented = false;
|
||||
const decrementKey = async () => {
|
||||
if (!decremented) {
|
||||
await config.store.decrement(key);
|
||||
decremented = true;
|
||||
}
|
||||
};
|
||||
if (config.skipFailedRequests) {
|
||||
response.on("finish", async () => {
|
||||
if (!await config.requestWasSuccessful(request, response))
|
||||
await decrementKey();
|
||||
});
|
||||
response.on("close", async () => {
|
||||
if (!response.writableEnded) await decrementKey();
|
||||
});
|
||||
response.on("error", async () => {
|
||||
await decrementKey();
|
||||
});
|
||||
}
|
||||
if (config.skipSuccessfulRequests) {
|
||||
response.on("finish", async () => {
|
||||
if (await config.requestWasSuccessful(request, response))
|
||||
await decrementKey();
|
||||
});
|
||||
}
|
||||
}
|
||||
config.validations.disable();
|
||||
if (totalHits > limit) {
|
||||
if (config.legacyHeaders || config.standardHeaders) {
|
||||
setRetryAfterHeader(response, info, config.windowMs);
|
||||
}
|
||||
config.handler(request, response, next, options);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
}
|
||||
);
|
||||
const getThrowFn = () => {
|
||||
throw new Error("The current store does not support the get/getKey method");
|
||||
};
|
||||
middleware.resetKey = config.store.resetKey.bind(config.store);
|
||||
middleware.getKey = typeof config.store.get === "function" ? config.store.get.bind(config.store) : getThrowFn;
|
||||
return middleware;
|
||||
};
|
||||
var rate_limit_default = rateLimit;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
MemoryStore,
|
||||
ipKeyGenerator,
|
||||
rateLimit
|
||||
});
|
||||
module.exports = Object.assign(rateLimit, module.exports);
|
||||
642
node_modules/express-rate-limit/dist/index.d.cts
generated
vendored
Normal file
642
node_modules/express-rate-limit/dist/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,642 @@
|
||||
// Generated by dts-bundle-generator v8.1.2
|
||||
|
||||
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
||||
|
||||
/**
|
||||
* Returns the IP address itself for IPv4, or a CIDR-notation subnet for IPv6.
|
||||
*
|
||||
* If you write a custom keyGenerator that allows a fallback to IP address for
|
||||
* unauthenticated users, return ipKeyGenerator(req.ip) rather than just req.ip.
|
||||
*
|
||||
* For more information, {@see Options.ipv6Subnet}.
|
||||
*
|
||||
* @param ip {string} - The IP address to process, usually request.ip.
|
||||
* @param ipv6Subnet {number | false} - The subnet mask for IPv6 addresses.
|
||||
*
|
||||
* @returns {string} - The key generated from the IP address
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare function ipKeyGenerator(ip: string, ipv6Subnet?: number | false): string;
|
||||
declare const SUPPORTED_DRAFT_VERSIONS: readonly [
|
||||
"draft-6",
|
||||
"draft-7",
|
||||
"draft-8"
|
||||
];
|
||||
declare const validations: {
|
||||
enabled: {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
disable(): void;
|
||||
/**
|
||||
* Checks whether the IP address is valid, and that it does not have a port
|
||||
* number in it.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.
|
||||
*
|
||||
* @param ip {string | undefined} - The IP address provided by Express as request.ip.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
ip(ip: string | undefined): void;
|
||||
/**
|
||||
* Makes sure the trust proxy setting is not set to `true`.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
trustProxy(request: Request): void;
|
||||
/**
|
||||
* Makes sure the trust proxy setting is set in case the `X-Forwarded-For`
|
||||
* header is present.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
xForwardedForHeader(request: Request): void;
|
||||
/**
|
||||
* Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
forwardedHeader(request: Request): void;
|
||||
/**
|
||||
* Ensures totalHits value from store is a positive integer.
|
||||
*
|
||||
* @param hits {any} - The `totalHits` returned by the store.
|
||||
*/
|
||||
positiveHits(hits: any): void;
|
||||
/**
|
||||
* Ensures a single store instance is not used with multiple express-rate-limit instances
|
||||
*/
|
||||
unsharedStore(store: Store): void;
|
||||
/**
|
||||
* Ensures a given key is incremented only once per request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param store {Store} - The store class.
|
||||
* @param key {string} - The key used to store the client's hit count.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
singleCount(request: Request, store: Store, key: string): void;
|
||||
/**
|
||||
* Warns the user that the behaviour for `max: 0` / `limit: 0` is
|
||||
* changing in the next major release.
|
||||
*
|
||||
* @param limit {number} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
limit(limit: number): void;
|
||||
/**
|
||||
* Warns the user that the `draft_polli_ratelimit_headers` option is deprecated
|
||||
* and will be removed in the next major release.
|
||||
*
|
||||
* @param draft_polli_ratelimit_headers {any | undefined} - The now-deprecated setting that was used to enable standard headers.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
draftPolliHeaders(draft_polli_ratelimit_headers?: any): void;
|
||||
/**
|
||||
* Warns the user that the `onLimitReached` option is deprecated and
|
||||
* will be removed in the next major release.
|
||||
*
|
||||
* @param onLimitReached {any | undefined} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onLimitReached(onLimitReached?: any): void;
|
||||
/**
|
||||
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
||||
*
|
||||
* @param version {any | undefined} - The version passed by the user.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersDraftVersion(version?: any): void;
|
||||
/**
|
||||
* Warns the user when the selected headers option requires a reset time but
|
||||
* the store does not provide one.
|
||||
*
|
||||
* @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersResetTime(resetTime?: Date): void;
|
||||
knownOptions(passedOptions?: Partial<Options>): void;
|
||||
/**
|
||||
* Checks the options.validate setting to ensure that only recognized
|
||||
* validations are enabled or disabled.
|
||||
*
|
||||
* If any unrecognized values are found, an error is logged that
|
||||
* includes the list of supported validations.
|
||||
*/
|
||||
validationsConfig(): void;
|
||||
/**
|
||||
* Checks to see if the instance was created inside of a request handler,
|
||||
* which would prevent it from working correctly, with the default memory
|
||||
* store (or any other store with localKeys.)
|
||||
*/
|
||||
creationStack(store: Store): void;
|
||||
ipv6Subnet(ipv6Subnet?: any): void;
|
||||
ipv6SubnetOrKeyGenerator(options: Partial<Options>): void;
|
||||
keyGeneratorIpFallback(keyGenerator?: ValueDeterminingMiddleware<string>): void;
|
||||
/**
|
||||
* Checks to see if the window duration is greater than 2^32 - 1. This is only
|
||||
* called by the default MemoryStore, since it uses Node's setInterval method.
|
||||
*
|
||||
* See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
|
||||
*/
|
||||
windowMs(windowMs: number): void;
|
||||
};
|
||||
export type Validations = typeof validations;
|
||||
/**
|
||||
* Callback that fires when a client's hit counter is incremented.
|
||||
*
|
||||
* @param error {Error | undefined} - The error that occurred, if any.
|
||||
* @param totalHits {number} - The number of hits for that client so far.
|
||||
* @param resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type IncrementCallback = (error: Error | undefined, totalHits: number, resetTime: Date | undefined) => void;
|
||||
/**
|
||||
* Method (in the form of middleware) to generate/retrieve a value based on the
|
||||
* incoming request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
*
|
||||
* @returns {T} - The value needed.
|
||||
*/
|
||||
export type ValueDeterminingMiddleware<T> = (request: Request, response: Response) => T | Promise<T>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param next {NextFunction} - The Express `next` function, can be called to skip responding.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitExceededEventHandler = (request: Request, response: Response, next: NextFunction, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Event callback that is triggered on a client's first request that exceeds the limit
|
||||
* but not for subsequent requests. May be used for logging, etc. Should *not*
|
||||
* send a response.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitReachedEventHandler = (request: Request, response: Response, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Data returned from the `Store` when a client's hit counter is incremented.
|
||||
*
|
||||
* @property totalHits {number} - The number of hits for that client so far.
|
||||
* @property resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type ClientRateLimitInfo = {
|
||||
totalHits: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
export type IncrementResponse = ClientRateLimitInfo;
|
||||
/**
|
||||
* A modified Express request handler with the rate limit functions.
|
||||
*/
|
||||
export type RateLimitRequestHandler = RequestHandler & {
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
getKey: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*
|
||||
* @deprecated 6.x - Implement the `Store` interface instead.
|
||||
*/
|
||||
export type LegacyStore = {
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
* @param callback {IncrementCallback} - The callback to call once the counter is incremented.
|
||||
*/
|
||||
incr: (key: string, callback: IncrementCallback) => void;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => void;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*/
|
||||
export type Store = {
|
||||
/**
|
||||
* Method that initializes the store, and has access to the options passed to
|
||||
* the middleware too.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init?: (options: Options) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
get?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {IncrementResponse | undefined} - The number of hits and reset time for that client.
|
||||
*/
|
||||
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => Promise<void> | void;
|
||||
/**
|
||||
* Method to shutdown the store, stop timers, and release all resources.
|
||||
*/
|
||||
shutdown?: () => Promise<void> | void;
|
||||
/**
|
||||
* Flag to indicate that keys incremented in one instance of this store can
|
||||
* not affect other instances. Typically false if a database is used, true for
|
||||
* MemoryStore.
|
||||
*
|
||||
* Used to help detect double-counting misconfigurations.
|
||||
*/
|
||||
localKeys?: boolean;
|
||||
/**
|
||||
* Optional value that the store prepends to keys
|
||||
*
|
||||
* Used by the double-count check to avoid false-positives when a key is counted
|
||||
* twice, but with different prefixes.
|
||||
*/
|
||||
prefix?: string;
|
||||
};
|
||||
export type DraftHeadersVersion = (typeof SUPPORTED_DRAFT_VERSIONS)[number];
|
||||
/**
|
||||
* Validate configuration object for enabling or disabling specific validations.
|
||||
*
|
||||
* The keys must also be keys in the validations object, except `enable`, `disable`,
|
||||
* and `default`.
|
||||
*/
|
||||
export type EnabledValidations = {
|
||||
[key in keyof Omit<Validations, "enabled" | "disable"> | "default"]?: boolean;
|
||||
};
|
||||
/**
|
||||
* The configuration options for the rate limiter.
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* How long we should remember the requests.
|
||||
*
|
||||
* Defaults to `60000` ms (= 1 minute).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* Defaults to `5`.
|
||||
*/
|
||||
limit: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* The response body to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `'Too many requests, please try again later.'`
|
||||
*/
|
||||
message: any | ValueDeterminingMiddleware<any>;
|
||||
/**
|
||||
* The HTTP status code to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `HTTP 429 Too Many Requests` (RFC 6585).
|
||||
*/
|
||||
statusCode: number;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* Defaults to `true` (for backward compatibility).
|
||||
*/
|
||||
legacyHeaders: boolean;
|
||||
/**
|
||||
* Whether to enable support for the standardized rate limit headers (`RateLimit-*`).
|
||||
*
|
||||
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
||||
*/
|
||||
standardHeaders: boolean | DraftHeadersVersion;
|
||||
/**
|
||||
* The name used to identify the quota policy in the `RateLimit` headers as per
|
||||
* the 8th draft of the IETF specification.
|
||||
*
|
||||
* Defaults to `{limit}-in-{window}`.
|
||||
*/
|
||||
identifier: string | ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* The name of the property on the request object to store the rate limit info.
|
||||
*
|
||||
* Defaults to `rateLimit`.
|
||||
*/
|
||||
requestPropertyName: string;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a 4XX
|
||||
* or 5XX status.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipFailedRequests: boolean;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a
|
||||
* status code less than 400.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipSuccessfulRequests: boolean;
|
||||
/**
|
||||
* Method to generate custom identifiers for clients.
|
||||
*
|
||||
* By default, the client's IP address is used.
|
||||
*/
|
||||
keyGenerator: ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* IPv6 subnet mask applied to IPv6 addresses in the default keyGenerator.
|
||||
*
|
||||
* Default is 56. The valid range is technically 1-128 but the value should
|
||||
* generally be in the 32-64 range.
|
||||
*
|
||||
* Smaller numbers are more aggressive, larger numbers are more lenient. Try
|
||||
* bumping to 60 or 64 if you see evidence of users being blocked incorrectly.
|
||||
*
|
||||
* May also be set to a function that returns a number based on the request.
|
||||
*
|
||||
* See the documentation for more info:
|
||||
* https://express-rate-limit.mintlify.app/reference/configuration#ipv6subnet.
|
||||
*/
|
||||
ipv6Subnet: 64 | 60 | 56 | 52 | 50 | 48 | 32 | number | ValueDeterminingMiddleware<number> | false;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* By default, sends back the `statusCode` and `message` set via the options.
|
||||
*/
|
||||
handler: RateLimitExceededEventHandler;
|
||||
/**
|
||||
* Method (in the form of middleware) to determine whether or not this request
|
||||
* counts towards a client's quota.
|
||||
*
|
||||
* By default, skips no requests.
|
||||
*/
|
||||
skip: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* Method to determine whether or not the request counts as 'successful'. Used
|
||||
* when either `skipSuccessfulRequests` or `skipFailedRequests` is set to true.
|
||||
*
|
||||
* By default, requests with a response status code less than 400 are considered
|
||||
* successful.
|
||||
*/
|
||||
requestWasSuccessful: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* The `Store` to use to store the hit count for each client.
|
||||
*
|
||||
* By default, the built-in `MemoryStore` will be used.
|
||||
*/
|
||||
store: Store | LegacyStore;
|
||||
/**
|
||||
* The list of validation checks that should run.
|
||||
*/
|
||||
validate: boolean | EnabledValidations;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `legacyHeaders`.
|
||||
*/
|
||||
headers?: boolean;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* @deprecated 7.x - This option was renamed to `limit`. However, it will not
|
||||
* be removed from the library in the foreseeable future.
|
||||
*/
|
||||
max?: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* If the Store generates an error, allow the request to pass.
|
||||
*/
|
||||
passOnStoreError: boolean;
|
||||
};
|
||||
/**
|
||||
* The extended request object that includes information about the client's
|
||||
* rate limit.
|
||||
*/
|
||||
export type AugmentedRequest = Request & {
|
||||
[key: string]: RateLimitInfo;
|
||||
};
|
||||
/**
|
||||
* The rate limit related information for each client included in the
|
||||
* Express request object.
|
||||
*/
|
||||
export type RateLimitInfo = {
|
||||
limit: number;
|
||||
used: number;
|
||||
remaining: number;
|
||||
resetTime: Date | undefined;
|
||||
key: string;
|
||||
};
|
||||
/**
|
||||
* The record that stores information about a client - namely, how many times
|
||||
* they have hit the endpoint, and when their hit count resets.
|
||||
*
|
||||
* Similar to `ClientRateLimitInfo`, except `resetTime` is a compulsory field.
|
||||
*/
|
||||
export type Client = {
|
||||
totalHits: number;
|
||||
resetTime: Date;
|
||||
};
|
||||
/**
|
||||
* A `Store` that stores the hit count for each client in memory.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare class MemoryStore implements Store {
|
||||
private validations?;
|
||||
/**
|
||||
* The duration of time before which all hit counts are reset (in milliseconds).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* These two maps store usage (requests) and reset time by key (for example, IP
|
||||
* addresses or API keys).
|
||||
*
|
||||
* They are split into two to avoid having to iterate through the entire set to
|
||||
* determine which ones need reset. Instead, `Client`s are moved from `previous`
|
||||
* to `current` as they hit the endpoint. Once `windowMs` has elapsed, all clients
|
||||
* left in `previous`, i.e., those that have not made any recent requests, are
|
||||
* known to be expired and can be deleted in bulk.
|
||||
*/
|
||||
previous: Map<string, Client>;
|
||||
current: Map<string, Client>;
|
||||
/**
|
||||
* A reference to the active timer.
|
||||
*/
|
||||
interval?: NodeJS.Timeout;
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
localKeys: boolean;
|
||||
constructor(validations?: Validations | undefined);
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options: Options): void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get(key: string): Promise<ClientRateLimitInfo | undefined>;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
increment(key: string): Promise<ClientRateLimitInfo>;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
decrement(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetKey(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetAll(): Promise<void>;
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown(): void;
|
||||
/**
|
||||
* Recycles a client by setting its hit count to zero, and reset time to
|
||||
* `windowMs` milliseconds from now.
|
||||
*
|
||||
* NOT to be confused with `#resetKey()`, which removes a client from both the
|
||||
* `current` and `previous` maps.
|
||||
*
|
||||
* @param client {Client} - The client to recycle.
|
||||
* @param now {number} - The current time, to which the `windowMs` is added to get the `resetTime` for the client.
|
||||
*
|
||||
* @return {Client} - The modified client that was passed in, to allow for chaining.
|
||||
*/
|
||||
private resetClient;
|
||||
/**
|
||||
* Retrieves or creates a client, given a key. Also ensures that the client being
|
||||
* returned is in the `current` map.
|
||||
*
|
||||
* @param key {string} - The key under which the client is (or is to be) stored.
|
||||
*
|
||||
* @returns {Client} - The requested client.
|
||||
*/
|
||||
private getClient;
|
||||
/**
|
||||
* Move current clients to previous, create a new map for current.
|
||||
*
|
||||
* This function is called every `windowMs`.
|
||||
*/
|
||||
private clearExpired;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Create an instance of IP rate-limiting middleware for Express.
|
||||
*
|
||||
* @param passedOptions {Options} - Options to configure the rate limiter.
|
||||
*
|
||||
* @returns {RateLimitRequestHandler} - The middleware that rate-limits clients based on your configuration.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare const rateLimit: (passedOptions?: Partial<Options>) => RateLimitRequestHandler;
|
||||
|
||||
export {
|
||||
rateLimit as default,
|
||||
};
|
||||
|
||||
export {};
|
||||
642
node_modules/express-rate-limit/dist/index.d.mts
generated
vendored
Normal file
642
node_modules/express-rate-limit/dist/index.d.mts
generated
vendored
Normal file
@@ -0,0 +1,642 @@
|
||||
// Generated by dts-bundle-generator v8.1.2
|
||||
|
||||
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
||||
|
||||
/**
|
||||
* Returns the IP address itself for IPv4, or a CIDR-notation subnet for IPv6.
|
||||
*
|
||||
* If you write a custom keyGenerator that allows a fallback to IP address for
|
||||
* unauthenticated users, return ipKeyGenerator(req.ip) rather than just req.ip.
|
||||
*
|
||||
* For more information, {@see Options.ipv6Subnet}.
|
||||
*
|
||||
* @param ip {string} - The IP address to process, usually request.ip.
|
||||
* @param ipv6Subnet {number | false} - The subnet mask for IPv6 addresses.
|
||||
*
|
||||
* @returns {string} - The key generated from the IP address
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare function ipKeyGenerator(ip: string, ipv6Subnet?: number | false): string;
|
||||
declare const SUPPORTED_DRAFT_VERSIONS: readonly [
|
||||
"draft-6",
|
||||
"draft-7",
|
||||
"draft-8"
|
||||
];
|
||||
declare const validations: {
|
||||
enabled: {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
disable(): void;
|
||||
/**
|
||||
* Checks whether the IP address is valid, and that it does not have a port
|
||||
* number in it.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.
|
||||
*
|
||||
* @param ip {string | undefined} - The IP address provided by Express as request.ip.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
ip(ip: string | undefined): void;
|
||||
/**
|
||||
* Makes sure the trust proxy setting is not set to `true`.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
trustProxy(request: Request): void;
|
||||
/**
|
||||
* Makes sure the trust proxy setting is set in case the `X-Forwarded-For`
|
||||
* header is present.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
xForwardedForHeader(request: Request): void;
|
||||
/**
|
||||
* Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
forwardedHeader(request: Request): void;
|
||||
/**
|
||||
* Ensures totalHits value from store is a positive integer.
|
||||
*
|
||||
* @param hits {any} - The `totalHits` returned by the store.
|
||||
*/
|
||||
positiveHits(hits: any): void;
|
||||
/**
|
||||
* Ensures a single store instance is not used with multiple express-rate-limit instances
|
||||
*/
|
||||
unsharedStore(store: Store): void;
|
||||
/**
|
||||
* Ensures a given key is incremented only once per request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param store {Store} - The store class.
|
||||
* @param key {string} - The key used to store the client's hit count.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
singleCount(request: Request, store: Store, key: string): void;
|
||||
/**
|
||||
* Warns the user that the behaviour for `max: 0` / `limit: 0` is
|
||||
* changing in the next major release.
|
||||
*
|
||||
* @param limit {number} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
limit(limit: number): void;
|
||||
/**
|
||||
* Warns the user that the `draft_polli_ratelimit_headers` option is deprecated
|
||||
* and will be removed in the next major release.
|
||||
*
|
||||
* @param draft_polli_ratelimit_headers {any | undefined} - The now-deprecated setting that was used to enable standard headers.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
draftPolliHeaders(draft_polli_ratelimit_headers?: any): void;
|
||||
/**
|
||||
* Warns the user that the `onLimitReached` option is deprecated and
|
||||
* will be removed in the next major release.
|
||||
*
|
||||
* @param onLimitReached {any | undefined} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onLimitReached(onLimitReached?: any): void;
|
||||
/**
|
||||
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
||||
*
|
||||
* @param version {any | undefined} - The version passed by the user.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersDraftVersion(version?: any): void;
|
||||
/**
|
||||
* Warns the user when the selected headers option requires a reset time but
|
||||
* the store does not provide one.
|
||||
*
|
||||
* @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersResetTime(resetTime?: Date): void;
|
||||
knownOptions(passedOptions?: Partial<Options>): void;
|
||||
/**
|
||||
* Checks the options.validate setting to ensure that only recognized
|
||||
* validations are enabled or disabled.
|
||||
*
|
||||
* If any unrecognized values are found, an error is logged that
|
||||
* includes the list of supported validations.
|
||||
*/
|
||||
validationsConfig(): void;
|
||||
/**
|
||||
* Checks to see if the instance was created inside of a request handler,
|
||||
* which would prevent it from working correctly, with the default memory
|
||||
* store (or any other store with localKeys.)
|
||||
*/
|
||||
creationStack(store: Store): void;
|
||||
ipv6Subnet(ipv6Subnet?: any): void;
|
||||
ipv6SubnetOrKeyGenerator(options: Partial<Options>): void;
|
||||
keyGeneratorIpFallback(keyGenerator?: ValueDeterminingMiddleware<string>): void;
|
||||
/**
|
||||
* Checks to see if the window duration is greater than 2^32 - 1. This is only
|
||||
* called by the default MemoryStore, since it uses Node's setInterval method.
|
||||
*
|
||||
* See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
|
||||
*/
|
||||
windowMs(windowMs: number): void;
|
||||
};
|
||||
export type Validations = typeof validations;
|
||||
/**
|
||||
* Callback that fires when a client's hit counter is incremented.
|
||||
*
|
||||
* @param error {Error | undefined} - The error that occurred, if any.
|
||||
* @param totalHits {number} - The number of hits for that client so far.
|
||||
* @param resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type IncrementCallback = (error: Error | undefined, totalHits: number, resetTime: Date | undefined) => void;
|
||||
/**
|
||||
* Method (in the form of middleware) to generate/retrieve a value based on the
|
||||
* incoming request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
*
|
||||
* @returns {T} - The value needed.
|
||||
*/
|
||||
export type ValueDeterminingMiddleware<T> = (request: Request, response: Response) => T | Promise<T>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param next {NextFunction} - The Express `next` function, can be called to skip responding.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitExceededEventHandler = (request: Request, response: Response, next: NextFunction, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Event callback that is triggered on a client's first request that exceeds the limit
|
||||
* but not for subsequent requests. May be used for logging, etc. Should *not*
|
||||
* send a response.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitReachedEventHandler = (request: Request, response: Response, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Data returned from the `Store` when a client's hit counter is incremented.
|
||||
*
|
||||
* @property totalHits {number} - The number of hits for that client so far.
|
||||
* @property resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type ClientRateLimitInfo = {
|
||||
totalHits: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
export type IncrementResponse = ClientRateLimitInfo;
|
||||
/**
|
||||
* A modified Express request handler with the rate limit functions.
|
||||
*/
|
||||
export type RateLimitRequestHandler = RequestHandler & {
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
getKey: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*
|
||||
* @deprecated 6.x - Implement the `Store` interface instead.
|
||||
*/
|
||||
export type LegacyStore = {
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
* @param callback {IncrementCallback} - The callback to call once the counter is incremented.
|
||||
*/
|
||||
incr: (key: string, callback: IncrementCallback) => void;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => void;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*/
|
||||
export type Store = {
|
||||
/**
|
||||
* Method that initializes the store, and has access to the options passed to
|
||||
* the middleware too.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init?: (options: Options) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
get?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {IncrementResponse | undefined} - The number of hits and reset time for that client.
|
||||
*/
|
||||
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => Promise<void> | void;
|
||||
/**
|
||||
* Method to shutdown the store, stop timers, and release all resources.
|
||||
*/
|
||||
shutdown?: () => Promise<void> | void;
|
||||
/**
|
||||
* Flag to indicate that keys incremented in one instance of this store can
|
||||
* not affect other instances. Typically false if a database is used, true for
|
||||
* MemoryStore.
|
||||
*
|
||||
* Used to help detect double-counting misconfigurations.
|
||||
*/
|
||||
localKeys?: boolean;
|
||||
/**
|
||||
* Optional value that the store prepends to keys
|
||||
*
|
||||
* Used by the double-count check to avoid false-positives when a key is counted
|
||||
* twice, but with different prefixes.
|
||||
*/
|
||||
prefix?: string;
|
||||
};
|
||||
export type DraftHeadersVersion = (typeof SUPPORTED_DRAFT_VERSIONS)[number];
|
||||
/**
|
||||
* Validate configuration object for enabling or disabling specific validations.
|
||||
*
|
||||
* The keys must also be keys in the validations object, except `enable`, `disable`,
|
||||
* and `default`.
|
||||
*/
|
||||
export type EnabledValidations = {
|
||||
[key in keyof Omit<Validations, "enabled" | "disable"> | "default"]?: boolean;
|
||||
};
|
||||
/**
|
||||
* The configuration options for the rate limiter.
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* How long we should remember the requests.
|
||||
*
|
||||
* Defaults to `60000` ms (= 1 minute).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* Defaults to `5`.
|
||||
*/
|
||||
limit: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* The response body to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `'Too many requests, please try again later.'`
|
||||
*/
|
||||
message: any | ValueDeterminingMiddleware<any>;
|
||||
/**
|
||||
* The HTTP status code to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `HTTP 429 Too Many Requests` (RFC 6585).
|
||||
*/
|
||||
statusCode: number;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* Defaults to `true` (for backward compatibility).
|
||||
*/
|
||||
legacyHeaders: boolean;
|
||||
/**
|
||||
* Whether to enable support for the standardized rate limit headers (`RateLimit-*`).
|
||||
*
|
||||
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
||||
*/
|
||||
standardHeaders: boolean | DraftHeadersVersion;
|
||||
/**
|
||||
* The name used to identify the quota policy in the `RateLimit` headers as per
|
||||
* the 8th draft of the IETF specification.
|
||||
*
|
||||
* Defaults to `{limit}-in-{window}`.
|
||||
*/
|
||||
identifier: string | ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* The name of the property on the request object to store the rate limit info.
|
||||
*
|
||||
* Defaults to `rateLimit`.
|
||||
*/
|
||||
requestPropertyName: string;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a 4XX
|
||||
* or 5XX status.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipFailedRequests: boolean;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a
|
||||
* status code less than 400.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipSuccessfulRequests: boolean;
|
||||
/**
|
||||
* Method to generate custom identifiers for clients.
|
||||
*
|
||||
* By default, the client's IP address is used.
|
||||
*/
|
||||
keyGenerator: ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* IPv6 subnet mask applied to IPv6 addresses in the default keyGenerator.
|
||||
*
|
||||
* Default is 56. The valid range is technically 1-128 but the value should
|
||||
* generally be in the 32-64 range.
|
||||
*
|
||||
* Smaller numbers are more aggressive, larger numbers are more lenient. Try
|
||||
* bumping to 60 or 64 if you see evidence of users being blocked incorrectly.
|
||||
*
|
||||
* May also be set to a function that returns a number based on the request.
|
||||
*
|
||||
* See the documentation for more info:
|
||||
* https://express-rate-limit.mintlify.app/reference/configuration#ipv6subnet.
|
||||
*/
|
||||
ipv6Subnet: 64 | 60 | 56 | 52 | 50 | 48 | 32 | number | ValueDeterminingMiddleware<number> | false;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* By default, sends back the `statusCode` and `message` set via the options.
|
||||
*/
|
||||
handler: RateLimitExceededEventHandler;
|
||||
/**
|
||||
* Method (in the form of middleware) to determine whether or not this request
|
||||
* counts towards a client's quota.
|
||||
*
|
||||
* By default, skips no requests.
|
||||
*/
|
||||
skip: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* Method to determine whether or not the request counts as 'successful'. Used
|
||||
* when either `skipSuccessfulRequests` or `skipFailedRequests` is set to true.
|
||||
*
|
||||
* By default, requests with a response status code less than 400 are considered
|
||||
* successful.
|
||||
*/
|
||||
requestWasSuccessful: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* The `Store` to use to store the hit count for each client.
|
||||
*
|
||||
* By default, the built-in `MemoryStore` will be used.
|
||||
*/
|
||||
store: Store | LegacyStore;
|
||||
/**
|
||||
* The list of validation checks that should run.
|
||||
*/
|
||||
validate: boolean | EnabledValidations;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `legacyHeaders`.
|
||||
*/
|
||||
headers?: boolean;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* @deprecated 7.x - This option was renamed to `limit`. However, it will not
|
||||
* be removed from the library in the foreseeable future.
|
||||
*/
|
||||
max?: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* If the Store generates an error, allow the request to pass.
|
||||
*/
|
||||
passOnStoreError: boolean;
|
||||
};
|
||||
/**
|
||||
* The extended request object that includes information about the client's
|
||||
* rate limit.
|
||||
*/
|
||||
export type AugmentedRequest = Request & {
|
||||
[key: string]: RateLimitInfo;
|
||||
};
|
||||
/**
|
||||
* The rate limit related information for each client included in the
|
||||
* Express request object.
|
||||
*/
|
||||
export type RateLimitInfo = {
|
||||
limit: number;
|
||||
used: number;
|
||||
remaining: number;
|
||||
resetTime: Date | undefined;
|
||||
key: string;
|
||||
};
|
||||
/**
|
||||
* The record that stores information about a client - namely, how many times
|
||||
* they have hit the endpoint, and when their hit count resets.
|
||||
*
|
||||
* Similar to `ClientRateLimitInfo`, except `resetTime` is a compulsory field.
|
||||
*/
|
||||
export type Client = {
|
||||
totalHits: number;
|
||||
resetTime: Date;
|
||||
};
|
||||
/**
|
||||
* A `Store` that stores the hit count for each client in memory.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare class MemoryStore implements Store {
|
||||
private validations?;
|
||||
/**
|
||||
* The duration of time before which all hit counts are reset (in milliseconds).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* These two maps store usage (requests) and reset time by key (for example, IP
|
||||
* addresses or API keys).
|
||||
*
|
||||
* They are split into two to avoid having to iterate through the entire set to
|
||||
* determine which ones need reset. Instead, `Client`s are moved from `previous`
|
||||
* to `current` as they hit the endpoint. Once `windowMs` has elapsed, all clients
|
||||
* left in `previous`, i.e., those that have not made any recent requests, are
|
||||
* known to be expired and can be deleted in bulk.
|
||||
*/
|
||||
previous: Map<string, Client>;
|
||||
current: Map<string, Client>;
|
||||
/**
|
||||
* A reference to the active timer.
|
||||
*/
|
||||
interval?: NodeJS.Timeout;
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
localKeys: boolean;
|
||||
constructor(validations?: Validations | undefined);
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options: Options): void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get(key: string): Promise<ClientRateLimitInfo | undefined>;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
increment(key: string): Promise<ClientRateLimitInfo>;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
decrement(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetKey(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetAll(): Promise<void>;
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown(): void;
|
||||
/**
|
||||
* Recycles a client by setting its hit count to zero, and reset time to
|
||||
* `windowMs` milliseconds from now.
|
||||
*
|
||||
* NOT to be confused with `#resetKey()`, which removes a client from both the
|
||||
* `current` and `previous` maps.
|
||||
*
|
||||
* @param client {Client} - The client to recycle.
|
||||
* @param now {number} - The current time, to which the `windowMs` is added to get the `resetTime` for the client.
|
||||
*
|
||||
* @return {Client} - The modified client that was passed in, to allow for chaining.
|
||||
*/
|
||||
private resetClient;
|
||||
/**
|
||||
* Retrieves or creates a client, given a key. Also ensures that the client being
|
||||
* returned is in the `current` map.
|
||||
*
|
||||
* @param key {string} - The key under which the client is (or is to be) stored.
|
||||
*
|
||||
* @returns {Client} - The requested client.
|
||||
*/
|
||||
private getClient;
|
||||
/**
|
||||
* Move current clients to previous, create a new map for current.
|
||||
*
|
||||
* This function is called every `windowMs`.
|
||||
*/
|
||||
private clearExpired;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Create an instance of IP rate-limiting middleware for Express.
|
||||
*
|
||||
* @param passedOptions {Options} - Options to configure the rate limiter.
|
||||
*
|
||||
* @returns {RateLimitRequestHandler} - The middleware that rate-limits clients based on your configuration.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare const rateLimit: (passedOptions?: Partial<Options>) => RateLimitRequestHandler;
|
||||
|
||||
export {
|
||||
rateLimit as default,
|
||||
};
|
||||
|
||||
export {};
|
||||
642
node_modules/express-rate-limit/dist/index.d.ts
generated
vendored
Normal file
642
node_modules/express-rate-limit/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,642 @@
|
||||
// Generated by dts-bundle-generator v8.1.2
|
||||
|
||||
import { NextFunction, Request, RequestHandler, Response } from 'express';
|
||||
|
||||
/**
|
||||
* Returns the IP address itself for IPv4, or a CIDR-notation subnet for IPv6.
|
||||
*
|
||||
* If you write a custom keyGenerator that allows a fallback to IP address for
|
||||
* unauthenticated users, return ipKeyGenerator(req.ip) rather than just req.ip.
|
||||
*
|
||||
* For more information, {@see Options.ipv6Subnet}.
|
||||
*
|
||||
* @param ip {string} - The IP address to process, usually request.ip.
|
||||
* @param ipv6Subnet {number | false} - The subnet mask for IPv6 addresses.
|
||||
*
|
||||
* @returns {string} - The key generated from the IP address
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare function ipKeyGenerator(ip: string, ipv6Subnet?: number | false): string;
|
||||
declare const SUPPORTED_DRAFT_VERSIONS: readonly [
|
||||
"draft-6",
|
||||
"draft-7",
|
||||
"draft-8"
|
||||
];
|
||||
declare const validations: {
|
||||
enabled: {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
disable(): void;
|
||||
/**
|
||||
* Checks whether the IP address is valid, and that it does not have a port
|
||||
* number in it.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.
|
||||
*
|
||||
* @param ip {string | undefined} - The IP address provided by Express as request.ip.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
ip(ip: string | undefined): void;
|
||||
/**
|
||||
* Makes sure the trust proxy setting is not set to `true`.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
trustProxy(request: Request): void;
|
||||
/**
|
||||
* Makes sure the trust proxy setting is set in case the `X-Forwarded-For`
|
||||
* header is present.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
xForwardedForHeader(request: Request): void;
|
||||
/**
|
||||
* Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
forwardedHeader(request: Request): void;
|
||||
/**
|
||||
* Ensures totalHits value from store is a positive integer.
|
||||
*
|
||||
* @param hits {any} - The `totalHits` returned by the store.
|
||||
*/
|
||||
positiveHits(hits: any): void;
|
||||
/**
|
||||
* Ensures a single store instance is not used with multiple express-rate-limit instances
|
||||
*/
|
||||
unsharedStore(store: Store): void;
|
||||
/**
|
||||
* Ensures a given key is incremented only once per request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param store {Store} - The store class.
|
||||
* @param key {string} - The key used to store the client's hit count.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
singleCount(request: Request, store: Store, key: string): void;
|
||||
/**
|
||||
* Warns the user that the behaviour for `max: 0` / `limit: 0` is
|
||||
* changing in the next major release.
|
||||
*
|
||||
* @param limit {number} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
limit(limit: number): void;
|
||||
/**
|
||||
* Warns the user that the `draft_polli_ratelimit_headers` option is deprecated
|
||||
* and will be removed in the next major release.
|
||||
*
|
||||
* @param draft_polli_ratelimit_headers {any | undefined} - The now-deprecated setting that was used to enable standard headers.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
draftPolliHeaders(draft_polli_ratelimit_headers?: any): void;
|
||||
/**
|
||||
* Warns the user that the `onLimitReached` option is deprecated and
|
||||
* will be removed in the next major release.
|
||||
*
|
||||
* @param onLimitReached {any | undefined} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onLimitReached(onLimitReached?: any): void;
|
||||
/**
|
||||
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
||||
*
|
||||
* @param version {any | undefined} - The version passed by the user.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersDraftVersion(version?: any): void;
|
||||
/**
|
||||
* Warns the user when the selected headers option requires a reset time but
|
||||
* the store does not provide one.
|
||||
*
|
||||
* @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersResetTime(resetTime?: Date): void;
|
||||
knownOptions(passedOptions?: Partial<Options>): void;
|
||||
/**
|
||||
* Checks the options.validate setting to ensure that only recognized
|
||||
* validations are enabled or disabled.
|
||||
*
|
||||
* If any unrecognized values are found, an error is logged that
|
||||
* includes the list of supported validations.
|
||||
*/
|
||||
validationsConfig(): void;
|
||||
/**
|
||||
* Checks to see if the instance was created inside of a request handler,
|
||||
* which would prevent it from working correctly, with the default memory
|
||||
* store (or any other store with localKeys.)
|
||||
*/
|
||||
creationStack(store: Store): void;
|
||||
ipv6Subnet(ipv6Subnet?: any): void;
|
||||
ipv6SubnetOrKeyGenerator(options: Partial<Options>): void;
|
||||
keyGeneratorIpFallback(keyGenerator?: ValueDeterminingMiddleware<string>): void;
|
||||
/**
|
||||
* Checks to see if the window duration is greater than 2^32 - 1. This is only
|
||||
* called by the default MemoryStore, since it uses Node's setInterval method.
|
||||
*
|
||||
* See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
|
||||
*/
|
||||
windowMs(windowMs: number): void;
|
||||
};
|
||||
export type Validations = typeof validations;
|
||||
/**
|
||||
* Callback that fires when a client's hit counter is incremented.
|
||||
*
|
||||
* @param error {Error | undefined} - The error that occurred, if any.
|
||||
* @param totalHits {number} - The number of hits for that client so far.
|
||||
* @param resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type IncrementCallback = (error: Error | undefined, totalHits: number, resetTime: Date | undefined) => void;
|
||||
/**
|
||||
* Method (in the form of middleware) to generate/retrieve a value based on the
|
||||
* incoming request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
*
|
||||
* @returns {T} - The value needed.
|
||||
*/
|
||||
export type ValueDeterminingMiddleware<T> = (request: Request, response: Response) => T | Promise<T>;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param next {NextFunction} - The Express `next` function, can be called to skip responding.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitExceededEventHandler = (request: Request, response: Response, next: NextFunction, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Event callback that is triggered on a client's first request that exceeds the limit
|
||||
* but not for subsequent requests. May be used for logging, etc. Should *not*
|
||||
* send a response.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param response {Response} - The Express response object.
|
||||
* @param optionsUsed {Options} - The options used to set up the middleware.
|
||||
*/
|
||||
export type RateLimitReachedEventHandler = (request: Request, response: Response, optionsUsed: Options) => void;
|
||||
/**
|
||||
* Data returned from the `Store` when a client's hit counter is incremented.
|
||||
*
|
||||
* @property totalHits {number} - The number of hits for that client so far.
|
||||
* @property resetTime {Date | undefined} - The time when the counter resets.
|
||||
*/
|
||||
export type ClientRateLimitInfo = {
|
||||
totalHits: number;
|
||||
resetTime: Date | undefined;
|
||||
};
|
||||
export type IncrementResponse = ClientRateLimitInfo;
|
||||
/**
|
||||
* A modified Express request handler with the rate limit functions.
|
||||
*/
|
||||
export type RateLimitRequestHandler = RequestHandler & {
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
getKey: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*
|
||||
* @deprecated 6.x - Implement the `Store` interface instead.
|
||||
*/
|
||||
export type LegacyStore = {
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
* @param callback {IncrementCallback} - The callback to call once the counter is incremented.
|
||||
*/
|
||||
incr: (key: string, callback: IncrementCallback) => void;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => void;
|
||||
};
|
||||
/**
|
||||
* An interface that all hit counter stores must implement.
|
||||
*/
|
||||
export type Store = {
|
||||
/**
|
||||
* Method that initializes the store, and has access to the options passed to
|
||||
* the middleware too.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init?: (options: Options) => void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*/
|
||||
get?: (key: string) => Promise<ClientRateLimitInfo | undefined> | ClientRateLimitInfo | undefined;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {IncrementResponse | undefined} - The number of hits and reset time for that client.
|
||||
*/
|
||||
increment: (key: string) => Promise<IncrementResponse> | IncrementResponse;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
decrement: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*/
|
||||
resetKey: (key: string) => Promise<void> | void;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*/
|
||||
resetAll?: () => Promise<void> | void;
|
||||
/**
|
||||
* Method to shutdown the store, stop timers, and release all resources.
|
||||
*/
|
||||
shutdown?: () => Promise<void> | void;
|
||||
/**
|
||||
* Flag to indicate that keys incremented in one instance of this store can
|
||||
* not affect other instances. Typically false if a database is used, true for
|
||||
* MemoryStore.
|
||||
*
|
||||
* Used to help detect double-counting misconfigurations.
|
||||
*/
|
||||
localKeys?: boolean;
|
||||
/**
|
||||
* Optional value that the store prepends to keys
|
||||
*
|
||||
* Used by the double-count check to avoid false-positives when a key is counted
|
||||
* twice, but with different prefixes.
|
||||
*/
|
||||
prefix?: string;
|
||||
};
|
||||
export type DraftHeadersVersion = (typeof SUPPORTED_DRAFT_VERSIONS)[number];
|
||||
/**
|
||||
* Validate configuration object for enabling or disabling specific validations.
|
||||
*
|
||||
* The keys must also be keys in the validations object, except `enable`, `disable`,
|
||||
* and `default`.
|
||||
*/
|
||||
export type EnabledValidations = {
|
||||
[key in keyof Omit<Validations, "enabled" | "disable"> | "default"]?: boolean;
|
||||
};
|
||||
/**
|
||||
* The configuration options for the rate limiter.
|
||||
*/
|
||||
export type Options = {
|
||||
/**
|
||||
* How long we should remember the requests.
|
||||
*
|
||||
* Defaults to `60000` ms (= 1 minute).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* Defaults to `5`.
|
||||
*/
|
||||
limit: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* The response body to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `'Too many requests, please try again later.'`
|
||||
*/
|
||||
message: any | ValueDeterminingMiddleware<any>;
|
||||
/**
|
||||
* The HTTP status code to send back when a client is rate limited.
|
||||
*
|
||||
* Defaults to `HTTP 429 Too Many Requests` (RFC 6585).
|
||||
*/
|
||||
statusCode: number;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* Defaults to `true` (for backward compatibility).
|
||||
*/
|
||||
legacyHeaders: boolean;
|
||||
/**
|
||||
* Whether to enable support for the standardized rate limit headers (`RateLimit-*`).
|
||||
*
|
||||
* Defaults to `false` (for backward compatibility, but its use is recommended).
|
||||
*/
|
||||
standardHeaders: boolean | DraftHeadersVersion;
|
||||
/**
|
||||
* The name used to identify the quota policy in the `RateLimit` headers as per
|
||||
* the 8th draft of the IETF specification.
|
||||
*
|
||||
* Defaults to `{limit}-in-{window}`.
|
||||
*/
|
||||
identifier: string | ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* The name of the property on the request object to store the rate limit info.
|
||||
*
|
||||
* Defaults to `rateLimit`.
|
||||
*/
|
||||
requestPropertyName: string;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a 4XX
|
||||
* or 5XX status.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipFailedRequests: boolean;
|
||||
/**
|
||||
* If `true`, the library will (by default) skip all requests that have a
|
||||
* status code less than 400.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
skipSuccessfulRequests: boolean;
|
||||
/**
|
||||
* Method to generate custom identifiers for clients.
|
||||
*
|
||||
* By default, the client's IP address is used.
|
||||
*/
|
||||
keyGenerator: ValueDeterminingMiddleware<string>;
|
||||
/**
|
||||
* IPv6 subnet mask applied to IPv6 addresses in the default keyGenerator.
|
||||
*
|
||||
* Default is 56. The valid range is technically 1-128 but the value should
|
||||
* generally be in the 32-64 range.
|
||||
*
|
||||
* Smaller numbers are more aggressive, larger numbers are more lenient. Try
|
||||
* bumping to 60 or 64 if you see evidence of users being blocked incorrectly.
|
||||
*
|
||||
* May also be set to a function that returns a number based on the request.
|
||||
*
|
||||
* See the documentation for more info:
|
||||
* https://express-rate-limit.mintlify.app/reference/configuration#ipv6subnet.
|
||||
*/
|
||||
ipv6Subnet: 64 | 60 | 56 | 52 | 50 | 48 | 32 | number | ValueDeterminingMiddleware<number> | false;
|
||||
/**
|
||||
* Express request handler that sends back a response when a client is
|
||||
* rate-limited.
|
||||
*
|
||||
* By default, sends back the `statusCode` and `message` set via the options.
|
||||
*/
|
||||
handler: RateLimitExceededEventHandler;
|
||||
/**
|
||||
* Method (in the form of middleware) to determine whether or not this request
|
||||
* counts towards a client's quota.
|
||||
*
|
||||
* By default, skips no requests.
|
||||
*/
|
||||
skip: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* Method to determine whether or not the request counts as 'successful'. Used
|
||||
* when either `skipSuccessfulRequests` or `skipFailedRequests` is set to true.
|
||||
*
|
||||
* By default, requests with a response status code less than 400 are considered
|
||||
* successful.
|
||||
*/
|
||||
requestWasSuccessful: ValueDeterminingMiddleware<boolean>;
|
||||
/**
|
||||
* The `Store` to use to store the hit count for each client.
|
||||
*
|
||||
* By default, the built-in `MemoryStore` will be used.
|
||||
*/
|
||||
store: Store | LegacyStore;
|
||||
/**
|
||||
* The list of validation checks that should run.
|
||||
*/
|
||||
validate: boolean | EnabledValidations;
|
||||
/**
|
||||
* Whether to send `X-RateLimit-*` headers with the rate limit and the number
|
||||
* of requests.
|
||||
*
|
||||
* @deprecated 6.x - This option was renamed to `legacyHeaders`.
|
||||
*/
|
||||
headers?: boolean;
|
||||
/**
|
||||
* The maximum number of connections to allow during the `window` before
|
||||
* rate limiting the client.
|
||||
*
|
||||
* Can be the limit itself as a number or express middleware that parses
|
||||
* the request and then figures out the limit.
|
||||
*
|
||||
* @deprecated 7.x - This option was renamed to `limit`. However, it will not
|
||||
* be removed from the library in the foreseeable future.
|
||||
*/
|
||||
max?: number | ValueDeterminingMiddleware<number>;
|
||||
/**
|
||||
* If the Store generates an error, allow the request to pass.
|
||||
*/
|
||||
passOnStoreError: boolean;
|
||||
};
|
||||
/**
|
||||
* The extended request object that includes information about the client's
|
||||
* rate limit.
|
||||
*/
|
||||
export type AugmentedRequest = Request & {
|
||||
[key: string]: RateLimitInfo;
|
||||
};
|
||||
/**
|
||||
* The rate limit related information for each client included in the
|
||||
* Express request object.
|
||||
*/
|
||||
export type RateLimitInfo = {
|
||||
limit: number;
|
||||
used: number;
|
||||
remaining: number;
|
||||
resetTime: Date | undefined;
|
||||
key: string;
|
||||
};
|
||||
/**
|
||||
* The record that stores information about a client - namely, how many times
|
||||
* they have hit the endpoint, and when their hit count resets.
|
||||
*
|
||||
* Similar to `ClientRateLimitInfo`, except `resetTime` is a compulsory field.
|
||||
*/
|
||||
export type Client = {
|
||||
totalHits: number;
|
||||
resetTime: Date;
|
||||
};
|
||||
/**
|
||||
* A `Store` that stores the hit count for each client in memory.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare class MemoryStore implements Store {
|
||||
private validations?;
|
||||
/**
|
||||
* The duration of time before which all hit counts are reset (in milliseconds).
|
||||
*/
|
||||
windowMs: number;
|
||||
/**
|
||||
* These two maps store usage (requests) and reset time by key (for example, IP
|
||||
* addresses or API keys).
|
||||
*
|
||||
* They are split into two to avoid having to iterate through the entire set to
|
||||
* determine which ones need reset. Instead, `Client`s are moved from `previous`
|
||||
* to `current` as they hit the endpoint. Once `windowMs` has elapsed, all clients
|
||||
* left in `previous`, i.e., those that have not made any recent requests, are
|
||||
* known to be expired and can be deleted in bulk.
|
||||
*/
|
||||
previous: Map<string, Client>;
|
||||
current: Map<string, Client>;
|
||||
/**
|
||||
* A reference to the active timer.
|
||||
*/
|
||||
interval?: NodeJS.Timeout;
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
localKeys: boolean;
|
||||
constructor(validations?: Validations | undefined);
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options: Options): void;
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get(key: string): Promise<ClientRateLimitInfo | undefined>;
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
increment(key: string): Promise<ClientRateLimitInfo>;
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
decrement(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetKey(key: string): Promise<void>;
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
resetAll(): Promise<void>;
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown(): void;
|
||||
/**
|
||||
* Recycles a client by setting its hit count to zero, and reset time to
|
||||
* `windowMs` milliseconds from now.
|
||||
*
|
||||
* NOT to be confused with `#resetKey()`, which removes a client from both the
|
||||
* `current` and `previous` maps.
|
||||
*
|
||||
* @param client {Client} - The client to recycle.
|
||||
* @param now {number} - The current time, to which the `windowMs` is added to get the `resetTime` for the client.
|
||||
*
|
||||
* @return {Client} - The modified client that was passed in, to allow for chaining.
|
||||
*/
|
||||
private resetClient;
|
||||
/**
|
||||
* Retrieves or creates a client, given a key. Also ensures that the client being
|
||||
* returned is in the `current` map.
|
||||
*
|
||||
* @param key {string} - The key under which the client is (or is to be) stored.
|
||||
*
|
||||
* @returns {Client} - The requested client.
|
||||
*/
|
||||
private getClient;
|
||||
/**
|
||||
* Move current clients to previous, create a new map for current.
|
||||
*
|
||||
* This function is called every `windowMs`.
|
||||
*/
|
||||
private clearExpired;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Create an instance of IP rate-limiting middleware for Express.
|
||||
*
|
||||
* @param passedOptions {Options} - Options to configure the rate limiter.
|
||||
*
|
||||
* @returns {RateLimitRequestHandler} - The middleware that rate-limits clients based on your configuration.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare const rateLimit: (passedOptions?: Partial<Options>) => RateLimitRequestHandler;
|
||||
|
||||
export {
|
||||
rateLimit as default,
|
||||
};
|
||||
|
||||
export {};
|
||||
929
node_modules/express-rate-limit/dist/index.mjs
generated
vendored
Normal file
929
node_modules/express-rate-limit/dist/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,929 @@
|
||||
// source/ip-key-generator.ts
|
||||
import { isIPv6 } from "node:net";
|
||||
import { Address6 } from "ip-address";
|
||||
function ipKeyGenerator(ip, ipv6Subnet = 56) {
|
||||
if (ipv6Subnet && isIPv6(ip)) {
|
||||
return `${new Address6(`${ip}/${ipv6Subnet}`).startAddress().correctForm()}/${ipv6Subnet}`;
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
// source/memory-store.ts
|
||||
var MemoryStore = class {
|
||||
constructor(validations2) {
|
||||
this.validations = validations2;
|
||||
/**
|
||||
* These two maps store usage (requests) and reset time by key (for example, IP
|
||||
* addresses or API keys).
|
||||
*
|
||||
* They are split into two to avoid having to iterate through the entire set to
|
||||
* determine which ones need reset. Instead, `Client`s are moved from `previous`
|
||||
* to `current` as they hit the endpoint. Once `windowMs` has elapsed, all clients
|
||||
* left in `previous`, i.e., those that have not made any recent requests, are
|
||||
* known to be expired and can be deleted in bulk.
|
||||
*/
|
||||
this.previous = /* @__PURE__ */ new Map();
|
||||
this.current = /* @__PURE__ */ new Map();
|
||||
/**
|
||||
* Confirmation that the keys incremented in once instance of MemoryStore
|
||||
* cannot affect other instances.
|
||||
*/
|
||||
this.localKeys = true;
|
||||
}
|
||||
/**
|
||||
* Method that initializes the store.
|
||||
*
|
||||
* @param options {Options} - The options used to setup the middleware.
|
||||
*/
|
||||
init(options) {
|
||||
this.windowMs = options.windowMs;
|
||||
this.validations?.windowMs(this.windowMs);
|
||||
if (this.interval) clearInterval(this.interval);
|
||||
this.interval = setInterval(() => {
|
||||
this.clearExpired();
|
||||
}, this.windowMs);
|
||||
this.interval.unref?.();
|
||||
}
|
||||
/**
|
||||
* Method to fetch a client's hit count and reset time.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo | undefined} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async get(key) {
|
||||
return this.current.get(key) ?? this.previous.get(key);
|
||||
}
|
||||
/**
|
||||
* Method to increment a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @returns {ClientRateLimitInfo} - The number of hits and reset time for that client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async increment(key) {
|
||||
const client = this.getClient(key);
|
||||
const now = Date.now();
|
||||
if (client.resetTime.getTime() <= now) {
|
||||
this.resetClient(client, now);
|
||||
}
|
||||
client.totalHits++;
|
||||
return client;
|
||||
}
|
||||
/**
|
||||
* Method to decrement a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async decrement(key) {
|
||||
const client = this.getClient(key);
|
||||
if (client.totalHits > 0) client.totalHits--;
|
||||
}
|
||||
/**
|
||||
* Method to reset a client's hit counter.
|
||||
*
|
||||
* @param key {string} - The identifier for a client.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async resetKey(key) {
|
||||
this.current.delete(key);
|
||||
this.previous.delete(key);
|
||||
}
|
||||
/**
|
||||
* Method to reset everyone's hit counter.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
async resetAll() {
|
||||
this.current.clear();
|
||||
this.previous.clear();
|
||||
}
|
||||
/**
|
||||
* Method to stop the timer (if currently running) and prevent any memory
|
||||
* leaks.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
shutdown() {
|
||||
clearInterval(this.interval);
|
||||
void this.resetAll();
|
||||
}
|
||||
/**
|
||||
* Recycles a client by setting its hit count to zero, and reset time to
|
||||
* `windowMs` milliseconds from now.
|
||||
*
|
||||
* NOT to be confused with `#resetKey()`, which removes a client from both the
|
||||
* `current` and `previous` maps.
|
||||
*
|
||||
* @param client {Client} - The client to recycle.
|
||||
* @param now {number} - The current time, to which the `windowMs` is added to get the `resetTime` for the client.
|
||||
*
|
||||
* @return {Client} - The modified client that was passed in, to allow for chaining.
|
||||
*/
|
||||
resetClient(client, now = Date.now()) {
|
||||
client.totalHits = 0;
|
||||
client.resetTime.setTime(now + this.windowMs);
|
||||
return client;
|
||||
}
|
||||
/**
|
||||
* Retrieves or creates a client, given a key. Also ensures that the client being
|
||||
* returned is in the `current` map.
|
||||
*
|
||||
* @param key {string} - The key under which the client is (or is to be) stored.
|
||||
*
|
||||
* @returns {Client} - The requested client.
|
||||
*/
|
||||
getClient(key) {
|
||||
if (this.current.has(key)) return this.current.get(key);
|
||||
let client;
|
||||
if (this.previous.has(key)) {
|
||||
client = this.previous.get(key);
|
||||
this.previous.delete(key);
|
||||
} else {
|
||||
client = { totalHits: 0, resetTime: /* @__PURE__ */ new Date() };
|
||||
this.resetClient(client);
|
||||
}
|
||||
this.current.set(key, client);
|
||||
return client;
|
||||
}
|
||||
/**
|
||||
* Move current clients to previous, create a new map for current.
|
||||
*
|
||||
* This function is called every `windowMs`.
|
||||
*/
|
||||
clearExpired() {
|
||||
this.previous = this.current;
|
||||
this.current = /* @__PURE__ */ new Map();
|
||||
}
|
||||
};
|
||||
|
||||
// source/rate-limit.ts
|
||||
import { isIPv6 as isIPv62 } from "node:net";
|
||||
|
||||
// source/headers.ts
|
||||
import { Buffer } from "node:buffer";
|
||||
import { createHash } from "node:crypto";
|
||||
var SUPPORTED_DRAFT_VERSIONS = [
|
||||
"draft-6",
|
||||
"draft-7",
|
||||
"draft-8"
|
||||
];
|
||||
var getResetSeconds = (windowMs, resetTime) => {
|
||||
let resetSeconds;
|
||||
if (resetTime) {
|
||||
const deltaSeconds = Math.ceil((resetTime.getTime() - Date.now()) / 1e3);
|
||||
resetSeconds = Math.max(0, deltaSeconds);
|
||||
} else {
|
||||
resetSeconds = Math.ceil(windowMs / 1e3);
|
||||
}
|
||||
return resetSeconds;
|
||||
};
|
||||
var getPartitionKey = (key) => {
|
||||
const hash = createHash("sha256");
|
||||
hash.update(key);
|
||||
const partitionKey = hash.digest("hex").slice(0, 12);
|
||||
return Buffer.from(partitionKey).toString("base64");
|
||||
};
|
||||
var setLegacyHeaders = (response, info) => {
|
||||
if (response.headersSent) return;
|
||||
response.setHeader("X-RateLimit-Limit", info.limit.toString());
|
||||
response.setHeader("X-RateLimit-Remaining", info.remaining.toString());
|
||||
if (info.resetTime instanceof Date) {
|
||||
response.setHeader("Date", (/* @__PURE__ */ new Date()).toUTCString());
|
||||
response.setHeader(
|
||||
"X-RateLimit-Reset",
|
||||
Math.ceil(info.resetTime.getTime() / 1e3).toString()
|
||||
);
|
||||
}
|
||||
};
|
||||
var setDraft6Headers = (response, info, windowMs) => {
|
||||
if (response.headersSent) return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
||||
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
||||
response.setHeader("RateLimit-Limit", info.limit.toString());
|
||||
response.setHeader("RateLimit-Remaining", info.remaining.toString());
|
||||
if (typeof resetSeconds === "number")
|
||||
response.setHeader("RateLimit-Reset", resetSeconds.toString());
|
||||
};
|
||||
var setDraft7Headers = (response, info, windowMs) => {
|
||||
if (response.headersSent) return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
||||
response.setHeader("RateLimit-Policy", `${info.limit};w=${windowSeconds}`);
|
||||
response.setHeader(
|
||||
"RateLimit",
|
||||
`limit=${info.limit}, remaining=${info.remaining}, reset=${resetSeconds}`
|
||||
);
|
||||
};
|
||||
var setDraft8Headers = (response, info, windowMs, name, key) => {
|
||||
if (response.headersSent) return;
|
||||
const windowSeconds = Math.ceil(windowMs / 1e3);
|
||||
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
||||
const partitionKey = getPartitionKey(key);
|
||||
const header = `r=${info.remaining}; t=${resetSeconds}`;
|
||||
const policy = `q=${info.limit}; w=${windowSeconds}; pk=:${partitionKey}:`;
|
||||
response.append("RateLimit", `"${name}"; ${header}`);
|
||||
response.append("RateLimit-Policy", `"${name}"; ${policy}`);
|
||||
};
|
||||
var setRetryAfterHeader = (response, info, windowMs) => {
|
||||
if (response.headersSent) return;
|
||||
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
||||
response.setHeader("Retry-After", resetSeconds.toString());
|
||||
};
|
||||
|
||||
// source/utils.ts
|
||||
var omitUndefinedProperties = (passedOptions) => {
|
||||
const omittedOptions = {};
|
||||
for (const k of Object.keys(passedOptions)) {
|
||||
const key = k;
|
||||
if (passedOptions[key] !== void 0) {
|
||||
omittedOptions[key] = passedOptions[key];
|
||||
}
|
||||
}
|
||||
return omittedOptions;
|
||||
};
|
||||
|
||||
// source/validations.ts
|
||||
import { isIP } from "node:net";
|
||||
var ValidationError = class extends Error {
|
||||
/**
|
||||
* The code must be a string, in snake case and all capital, that starts with
|
||||
* the substring `ERR_ERL_`.
|
||||
*
|
||||
* The message must be a string, starting with an uppercase character,
|
||||
* describing the issue in detail.
|
||||
*/
|
||||
constructor(code, message) {
|
||||
const url = `https://express-rate-limit.github.io/${code}/`;
|
||||
super(`${message} See ${url} for more information.`);
|
||||
this.name = this.constructor.name;
|
||||
this.code = code;
|
||||
this.help = url;
|
||||
}
|
||||
};
|
||||
var ChangeWarning = class extends ValidationError {
|
||||
};
|
||||
var usedStores = /* @__PURE__ */ new Set();
|
||||
var singleCountKeys = /* @__PURE__ */ new WeakMap();
|
||||
var validations = {
|
||||
enabled: {
|
||||
default: true
|
||||
},
|
||||
// Should be EnabledValidations type, but that's a circular reference
|
||||
disable() {
|
||||
for (const k of Object.keys(this.enabled)) this.enabled[k] = false;
|
||||
},
|
||||
/**
|
||||
* Checks whether the IP address is valid, and that it does not have a port
|
||||
* number in it.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_invalid_ip_address.
|
||||
*
|
||||
* @param ip {string | undefined} - The IP address provided by Express as request.ip.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
ip(ip) {
|
||||
if (ip === void 0) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNDEFINED_IP_ADDRESS",
|
||||
`An undefined 'request.ip' was detected. This might indicate a misconfiguration or the connection being destroyed prematurely.`
|
||||
);
|
||||
}
|
||||
if (!isIP(ip)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_INVALID_IP_ADDRESS",
|
||||
`An invalid 'request.ip' (${ip}) was detected. Consider passing a custom 'keyGenerator' function to the rate limiter.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Makes sure the trust proxy setting is not set to `true`.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_permissive_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
trustProxy(request) {
|
||||
if (request.app.get("trust proxy") === true) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_PERMISSIVE_TRUST_PROXY",
|
||||
`The Express 'trust proxy' setting is true, which allows anyone to trivially bypass IP-based rate limiting.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Makes sure the trust proxy setting is set in case the `X-Forwarded-For`
|
||||
* header is present.
|
||||
*
|
||||
* See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes#err_erl_unset_trust_proxy.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
xForwardedForHeader(request) {
|
||||
if (request.headers["x-forwarded-for"] && request.app.get("trust proxy") === false) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNEXPECTED_X_FORWARDED_FOR",
|
||||
`The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Alert the user if the Forwarded header is set (standardized version of X-Forwarded-For - not supported by express as of version 5.1.0)
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
forwardedHeader(request) {
|
||||
if (request.headers.forwarded && request.ip === request.socket?.remoteAddress) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_FORWARDED_HEADER",
|
||||
`The 'Forwarded' header (standardized X-Forwarded-For) is set but currently being ignored. Add a custom keyGenerator to use a value from this header.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Ensures totalHits value from store is a positive integer.
|
||||
*
|
||||
* @param hits {any} - The `totalHits` returned by the store.
|
||||
*/
|
||||
positiveHits(hits) {
|
||||
if (typeof hits !== "number" || hits < 1 || hits !== Math.round(hits)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_INVALID_HITS",
|
||||
`The totalHits value returned from the store must be a positive integer, got ${hits}`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Ensures a single store instance is not used with multiple express-rate-limit instances
|
||||
*/
|
||||
unsharedStore(store) {
|
||||
if (usedStores.has(store)) {
|
||||
const maybeUniquePrefix = store?.localKeys ? "" : " (with a unique prefix)";
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_STORE_REUSE",
|
||||
`A Store instance must not be shared across multiple rate limiters. Create a new instance of ${store.constructor.name}${maybeUniquePrefix} for each limiter instead.`
|
||||
);
|
||||
}
|
||||
usedStores.add(store);
|
||||
},
|
||||
/**
|
||||
* Ensures a given key is incremented only once per request.
|
||||
*
|
||||
* @param request {Request} - The Express request object.
|
||||
* @param store {Store} - The store class.
|
||||
* @param key {string} - The key used to store the client's hit count.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
singleCount(request, store, key) {
|
||||
let storeKeys = singleCountKeys.get(request);
|
||||
if (!storeKeys) {
|
||||
storeKeys = /* @__PURE__ */ new Map();
|
||||
singleCountKeys.set(request, storeKeys);
|
||||
}
|
||||
const storeKey = store.localKeys ? store : store.constructor.name;
|
||||
let keys = storeKeys.get(storeKey);
|
||||
if (!keys) {
|
||||
keys = [];
|
||||
storeKeys.set(storeKey, keys);
|
||||
}
|
||||
const prefixedKey = `${store.prefix ?? ""}${key}`;
|
||||
if (keys.includes(prefixedKey)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_DOUBLE_COUNT",
|
||||
`The hit count for ${key} was incremented more than once for a single request.`
|
||||
);
|
||||
}
|
||||
keys.push(prefixedKey);
|
||||
},
|
||||
/**
|
||||
* Warns the user that the behaviour for `max: 0` / `limit: 0` is
|
||||
* changing in the next major release.
|
||||
*
|
||||
* @param limit {number} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
limit(limit) {
|
||||
if (limit === 0) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_MAX_ZERO",
|
||||
"Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7"
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Warns the user that the `draft_polli_ratelimit_headers` option is deprecated
|
||||
* and will be removed in the next major release.
|
||||
*
|
||||
* @param draft_polli_ratelimit_headers {any | undefined} - The now-deprecated setting that was used to enable standard headers.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
draftPolliHeaders(draft_polli_ratelimit_headers) {
|
||||
if (draft_polli_ratelimit_headers) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_DEPRECATED_DRAFT_POLLI_HEADERS",
|
||||
`The draft_polli_ratelimit_headers configuration option is deprecated and has been removed in express-rate-limit v7, please set standardHeaders: 'draft-6' instead.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Warns the user that the `onLimitReached` option is deprecated and
|
||||
* will be removed in the next major release.
|
||||
*
|
||||
* @param onLimitReached {any | undefined} - The maximum number of hits per client.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onLimitReached(onLimitReached) {
|
||||
if (onLimitReached) {
|
||||
throw new ChangeWarning(
|
||||
"WRN_ERL_DEPRECATED_ON_LIMIT_REACHED",
|
||||
"The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7."
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Warns the user when an invalid/unsupported version of the draft spec is passed.
|
||||
*
|
||||
* @param version {any | undefined} - The version passed by the user.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersDraftVersion(version) {
|
||||
if (typeof version !== "string" || // @ts-expect-error This is fine. If version is not in the array, it will just return false.
|
||||
!SUPPORTED_DRAFT_VERSIONS.includes(version)) {
|
||||
const versionString = SUPPORTED_DRAFT_VERSIONS.join(", ");
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION",
|
||||
`standardHeaders: only the following versions of the IETF draft specification are supported: ${versionString}.`
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Warns the user when the selected headers option requires a reset time but
|
||||
* the store does not provide one.
|
||||
*
|
||||
* @param resetTime {Date | undefined} - The timestamp when the client's hit count will be reset.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
headersResetTime(resetTime) {
|
||||
if (!resetTime) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_HEADERS_NO_RESET",
|
||||
`standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.`
|
||||
);
|
||||
}
|
||||
},
|
||||
knownOptions(passedOptions) {
|
||||
if (!passedOptions) return;
|
||||
const optionsMap = {
|
||||
windowMs: true,
|
||||
limit: true,
|
||||
message: true,
|
||||
statusCode: true,
|
||||
legacyHeaders: true,
|
||||
standardHeaders: true,
|
||||
identifier: true,
|
||||
requestPropertyName: true,
|
||||
skipFailedRequests: true,
|
||||
skipSuccessfulRequests: true,
|
||||
keyGenerator: true,
|
||||
ipv6Subnet: true,
|
||||
handler: true,
|
||||
skip: true,
|
||||
requestWasSuccessful: true,
|
||||
store: true,
|
||||
validate: true,
|
||||
headers: true,
|
||||
max: true,
|
||||
passOnStoreError: true
|
||||
};
|
||||
const validOptions = Object.keys(optionsMap).concat(
|
||||
"draft_polli_ratelimit_headers",
|
||||
// not a valid option anymore, but we have a more specific check for this one, so don't warn for it here
|
||||
// from express-slow-down - https://github.com/express-rate-limit/express-slow-down/blob/main/source/types.ts#L65
|
||||
"delayAfter",
|
||||
"delayMs",
|
||||
"maxDelayMs"
|
||||
);
|
||||
for (const key of Object.keys(passedOptions)) {
|
||||
if (!validOptions.includes(key)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNKNOWN_OPTION",
|
||||
`Unexpected configuration option: ${key}`
|
||||
// todo: suggest a valid option with a short levenstein distance?
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Checks the options.validate setting to ensure that only recognized
|
||||
* validations are enabled or disabled.
|
||||
*
|
||||
* If any unrecognized values are found, an error is logged that
|
||||
* includes the list of supported validations.
|
||||
*/
|
||||
validationsConfig() {
|
||||
const supportedValidations = Object.keys(this).filter(
|
||||
(k) => !["enabled", "disable"].includes(k)
|
||||
);
|
||||
supportedValidations.push("default");
|
||||
for (const key of Object.keys(this.enabled)) {
|
||||
if (!supportedValidations.includes(key)) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_UNKNOWN_VALIDATION",
|
||||
`options.validate.${key} is not recognized. Supported validate options are: ${supportedValidations.join(
|
||||
", "
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Checks to see if the instance was created inside of a request handler,
|
||||
* which would prevent it from working correctly, with the default memory
|
||||
* store (or any other store with localKeys.)
|
||||
*/
|
||||
creationStack(store) {
|
||||
const { stack } = new Error(
|
||||
"express-rate-limit validation check (set options.validate.creationStack=false to disable)"
|
||||
);
|
||||
if (stack?.includes("Layer.handle [as handle_request]") || // express v4
|
||||
stack?.includes("Layer.handleRequest")) {
|
||||
if (!store.localKeys) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_CREATED_IN_REQUEST_HANDLER",
|
||||
"express-rate-limit instance should *usually* be created at app initialization, not when responding to a request."
|
||||
);
|
||||
}
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_CREATED_IN_REQUEST_HANDLER",
|
||||
"express-rate-limit instance should be created at app initialization, not when responding to a request."
|
||||
);
|
||||
}
|
||||
},
|
||||
ipv6Subnet(ipv6Subnet) {
|
||||
if (ipv6Subnet === false) {
|
||||
return;
|
||||
}
|
||||
if (!Number.isInteger(ipv6Subnet) || ipv6Subnet < 32 || ipv6Subnet > 64) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_IPV6_SUBNET",
|
||||
`Unexpected ipv6Subnet value: ${ipv6Subnet}. Expected an integer between 32 and 64 (usually 48-64).`
|
||||
);
|
||||
}
|
||||
},
|
||||
ipv6SubnetOrKeyGenerator(options) {
|
||||
if (options.ipv6Subnet !== void 0 && options.keyGenerator) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_IPV6SUBNET_OR_KEYGENERATOR",
|
||||
`Incompatible options: the 'ipv6Subnet' option is ignored when a custom 'keyGenerator' function is also set.`
|
||||
);
|
||||
}
|
||||
},
|
||||
keyGeneratorIpFallback(keyGenerator) {
|
||||
if (!keyGenerator) {
|
||||
return;
|
||||
}
|
||||
const src = keyGenerator.toString();
|
||||
if ((src.includes("req.ip") || src.includes("request.ip")) && !src.includes("ipKeyGenerator")) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_KEY_GEN_IPV6",
|
||||
"Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits."
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Checks to see if the window duration is greater than 2^32 - 1. This is only
|
||||
* called by the default MemoryStore, since it uses Node's setInterval method.
|
||||
*
|
||||
* See https://nodejs.org/api/timers.html#setintervalcallback-delay-args.
|
||||
*/
|
||||
windowMs(windowMs) {
|
||||
const SET_TIMEOUT_MAX = 2 ** 31 - 1;
|
||||
if (typeof windowMs !== "number" || Number.isNaN(windowMs) || windowMs < 1 || windowMs > SET_TIMEOUT_MAX) {
|
||||
throw new ValidationError(
|
||||
"ERR_ERL_WINDOW_MS",
|
||||
`Invalid windowMs value: ${windowMs}${typeof windowMs !== "number" ? ` (${typeof windowMs})` : ""}, must be a number between 1 and ${SET_TIMEOUT_MAX} when using the default MemoryStore`
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
var getValidations = (_enabled) => {
|
||||
let enabled;
|
||||
if (typeof _enabled === "boolean") {
|
||||
enabled = {
|
||||
default: _enabled
|
||||
};
|
||||
} else {
|
||||
enabled = {
|
||||
default: true,
|
||||
..._enabled
|
||||
};
|
||||
}
|
||||
const wrappedValidations = { enabled };
|
||||
for (const [name, validation] of Object.entries(validations)) {
|
||||
if (typeof validation === "function")
|
||||
wrappedValidations[name] = (...args) => {
|
||||
if (!(enabled[name] ?? enabled.default)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
;
|
||||
validation.apply(
|
||||
wrappedValidations,
|
||||
args
|
||||
);
|
||||
} catch (error) {
|
||||
if (error instanceof ChangeWarning) console.warn(error);
|
||||
else console.error(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
return wrappedValidations;
|
||||
};
|
||||
|
||||
// source/rate-limit.ts
|
||||
var isLegacyStore = (store) => (
|
||||
// Check that `incr` exists but `increment` does not - store authors might want
|
||||
// to keep both around for backwards compatibility.
|
||||
typeof store.incr === "function" && typeof store.increment !== "function"
|
||||
);
|
||||
var promisifyStore = (passedStore) => {
|
||||
if (!isLegacyStore(passedStore)) {
|
||||
return passedStore;
|
||||
}
|
||||
const legacyStore = passedStore;
|
||||
class PromisifiedStore {
|
||||
async increment(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
legacyStore.incr(
|
||||
key,
|
||||
(error, totalHits, resetTime) => {
|
||||
if (error) reject(error);
|
||||
resolve({ totalHits, resetTime });
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
async decrement(key) {
|
||||
return legacyStore.decrement(key);
|
||||
}
|
||||
async resetKey(key) {
|
||||
return legacyStore.resetKey(key);
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
async resetAll() {
|
||||
if (typeof legacyStore.resetAll === "function")
|
||||
return legacyStore.resetAll();
|
||||
}
|
||||
}
|
||||
return new PromisifiedStore();
|
||||
};
|
||||
var getOptionsFromConfig = (config) => {
|
||||
const { validations: validations2, ...directlyPassableEntries } = config;
|
||||
return {
|
||||
...directlyPassableEntries,
|
||||
validate: validations2.enabled
|
||||
};
|
||||
};
|
||||
var parseOptions = (passedOptions) => {
|
||||
const notUndefinedOptions = omitUndefinedProperties(passedOptions);
|
||||
const validations2 = getValidations(notUndefinedOptions?.validate ?? true);
|
||||
validations2.validationsConfig();
|
||||
validations2.knownOptions(passedOptions);
|
||||
validations2.draftPolliHeaders(
|
||||
// @ts-expect-error see the note above.
|
||||
notUndefinedOptions.draft_polli_ratelimit_headers
|
||||
);
|
||||
validations2.onLimitReached(notUndefinedOptions.onLimitReached);
|
||||
if (notUndefinedOptions.ipv6Subnet !== void 0 && typeof notUndefinedOptions.ipv6Subnet !== "function") {
|
||||
validations2.ipv6Subnet(notUndefinedOptions.ipv6Subnet);
|
||||
}
|
||||
validations2.keyGeneratorIpFallback(notUndefinedOptions.keyGenerator);
|
||||
validations2.ipv6SubnetOrKeyGenerator(notUndefinedOptions);
|
||||
let standardHeaders = notUndefinedOptions.standardHeaders ?? false;
|
||||
if (standardHeaders === true) standardHeaders = "draft-6";
|
||||
const config = {
|
||||
windowMs: 60 * 1e3,
|
||||
limit: passedOptions.max ?? 5,
|
||||
// `max` is deprecated, but support it anyways.
|
||||
message: "Too many requests, please try again later.",
|
||||
statusCode: 429,
|
||||
legacyHeaders: passedOptions.headers ?? true,
|
||||
identifier(request, _response) {
|
||||
let duration = "";
|
||||
const property = config.requestPropertyName;
|
||||
const { limit } = request[property];
|
||||
const seconds = config.windowMs / 1e3;
|
||||
const minutes = config.windowMs / (1e3 * 60);
|
||||
const hours = config.windowMs / (1e3 * 60 * 60);
|
||||
const days = config.windowMs / (1e3 * 60 * 60 * 24);
|
||||
if (seconds < 60) duration = `${seconds}sec`;
|
||||
else if (minutes < 60) duration = `${minutes}min`;
|
||||
else if (hours < 24) duration = `${hours}hr${hours > 1 ? "s" : ""}`;
|
||||
else duration = `${days}day${days > 1 ? "s" : ""}`;
|
||||
return `${limit}-in-${duration}`;
|
||||
},
|
||||
requestPropertyName: "rateLimit",
|
||||
skipFailedRequests: false,
|
||||
skipSuccessfulRequests: false,
|
||||
requestWasSuccessful: (_request, response) => response.statusCode < 400,
|
||||
skip: (_request, _response) => false,
|
||||
async keyGenerator(request, response) {
|
||||
validations2.ip(request.ip);
|
||||
validations2.trustProxy(request);
|
||||
validations2.xForwardedForHeader(request);
|
||||
validations2.forwardedHeader(request);
|
||||
const ip = request.ip;
|
||||
let subnet = 56;
|
||||
if (isIPv62(ip)) {
|
||||
subnet = typeof config.ipv6Subnet === "function" ? await config.ipv6Subnet(request, response) : config.ipv6Subnet;
|
||||
if (typeof config.ipv6Subnet === "function")
|
||||
validations2.ipv6Subnet(subnet);
|
||||
}
|
||||
return ipKeyGenerator(ip, subnet);
|
||||
},
|
||||
ipv6Subnet: 56,
|
||||
async handler(request, response, _next, _optionsUsed) {
|
||||
response.status(config.statusCode);
|
||||
const message = typeof config.message === "function" ? await config.message(
|
||||
request,
|
||||
response
|
||||
) : config.message;
|
||||
if (!response.writableEnded) response.send(message);
|
||||
},
|
||||
passOnStoreError: false,
|
||||
// Allow the default options to be overridden by the passed options.
|
||||
...notUndefinedOptions,
|
||||
// `standardHeaders` is resolved into a draft version above, use that.
|
||||
standardHeaders,
|
||||
// Note that this field is declared after the user's options are spread in,
|
||||
// so that this field doesn't get overridden with an un-promisified store!
|
||||
store: promisifyStore(
|
||||
notUndefinedOptions.store ?? new MemoryStore(validations2)
|
||||
),
|
||||
// Print an error to the console if a few known misconfigurations are detected.
|
||||
validations: validations2
|
||||
};
|
||||
if (typeof config.store.increment !== "function" || typeof config.store.decrement !== "function" || typeof config.store.resetKey !== "function" || config.store.resetAll !== void 0 && typeof config.store.resetAll !== "function" || config.store.init !== void 0 && typeof config.store.init !== "function") {
|
||||
throw new TypeError(
|
||||
"An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface."
|
||||
);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
var handleAsyncErrors = (fn) => async (request, response, next) => {
|
||||
try {
|
||||
await Promise.resolve(fn(request, response, next)).catch(next);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
var rateLimit = (passedOptions) => {
|
||||
const config = parseOptions(passedOptions ?? {});
|
||||
const options = getOptionsFromConfig(config);
|
||||
config.validations.creationStack(config.store);
|
||||
config.validations.unsharedStore(config.store);
|
||||
if (typeof config.store.init === "function") config.store.init(options);
|
||||
const middleware = handleAsyncErrors(
|
||||
async (request, response, next) => {
|
||||
const skip = await config.skip(request, response);
|
||||
if (skip) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const augmentedRequest = request;
|
||||
const key = await config.keyGenerator(request, response);
|
||||
let totalHits = 0;
|
||||
let resetTime;
|
||||
try {
|
||||
const incrementResult = await config.store.increment(key);
|
||||
totalHits = incrementResult.totalHits;
|
||||
resetTime = incrementResult.resetTime;
|
||||
} catch (error) {
|
||||
if (config.passOnStoreError) {
|
||||
console.error(
|
||||
"express-rate-limit: error from store, allowing request without rate-limiting.",
|
||||
error
|
||||
);
|
||||
next();
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
config.validations.positiveHits(totalHits);
|
||||
config.validations.singleCount(request, config.store, key);
|
||||
const retrieveLimit = typeof config.limit === "function" ? config.limit(request, response) : config.limit;
|
||||
const limit = await retrieveLimit;
|
||||
config.validations.limit(limit);
|
||||
const info = {
|
||||
limit,
|
||||
used: totalHits,
|
||||
remaining: Math.max(limit - totalHits, 0),
|
||||
resetTime,
|
||||
key
|
||||
};
|
||||
Object.defineProperty(info, "current", {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
value: totalHits
|
||||
});
|
||||
augmentedRequest[config.requestPropertyName] = info;
|
||||
if (config.legacyHeaders && !response.headersSent) {
|
||||
setLegacyHeaders(response, info);
|
||||
}
|
||||
if (config.standardHeaders && !response.headersSent) {
|
||||
switch (config.standardHeaders) {
|
||||
case "draft-6": {
|
||||
setDraft6Headers(response, info, config.windowMs);
|
||||
break;
|
||||
}
|
||||
case "draft-7": {
|
||||
config.validations.headersResetTime(info.resetTime);
|
||||
setDraft7Headers(response, info, config.windowMs);
|
||||
break;
|
||||
}
|
||||
case "draft-8": {
|
||||
const retrieveName = typeof config.identifier === "function" ? config.identifier(request, response) : config.identifier;
|
||||
const name = await retrieveName;
|
||||
config.validations.headersResetTime(info.resetTime);
|
||||
setDraft8Headers(response, info, config.windowMs, name, key);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
config.validations.headersDraftVersion(config.standardHeaders);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.skipFailedRequests || config.skipSuccessfulRequests) {
|
||||
let decremented = false;
|
||||
const decrementKey = async () => {
|
||||
if (!decremented) {
|
||||
await config.store.decrement(key);
|
||||
decremented = true;
|
||||
}
|
||||
};
|
||||
if (config.skipFailedRequests) {
|
||||
response.on("finish", async () => {
|
||||
if (!await config.requestWasSuccessful(request, response))
|
||||
await decrementKey();
|
||||
});
|
||||
response.on("close", async () => {
|
||||
if (!response.writableEnded) await decrementKey();
|
||||
});
|
||||
response.on("error", async () => {
|
||||
await decrementKey();
|
||||
});
|
||||
}
|
||||
if (config.skipSuccessfulRequests) {
|
||||
response.on("finish", async () => {
|
||||
if (await config.requestWasSuccessful(request, response))
|
||||
await decrementKey();
|
||||
});
|
||||
}
|
||||
}
|
||||
config.validations.disable();
|
||||
if (totalHits > limit) {
|
||||
if (config.legacyHeaders || config.standardHeaders) {
|
||||
setRetryAfterHeader(response, info, config.windowMs);
|
||||
}
|
||||
config.handler(request, response, next, options);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
}
|
||||
);
|
||||
const getThrowFn = () => {
|
||||
throw new Error("The current store does not support the get/getKey method");
|
||||
};
|
||||
middleware.resetKey = config.store.resetKey.bind(config.store);
|
||||
middleware.getKey = typeof config.store.get === "function" ? config.store.get.bind(config.store) : getThrowFn;
|
||||
return middleware;
|
||||
};
|
||||
var rate_limit_default = rateLimit;
|
||||
export {
|
||||
MemoryStore,
|
||||
rate_limit_default as default,
|
||||
ipKeyGenerator,
|
||||
rate_limit_default as rateLimit
|
||||
};
|
||||
20
node_modules/express-rate-limit/license.md
generated
vendored
Normal file
20
node_modules/express-rate-limit/license.md
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# MIT License
|
||||
|
||||
Copyright 2023 Nathan Friedly, Vedant K
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
19
node_modules/express-rate-limit/node_modules/ip-address/LICENSE
generated
vendored
Normal file
19
node_modules/express-rate-limit/node_modules/ip-address/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2011 by Beau Gunderson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
105
node_modules/express-rate-limit/node_modules/ip-address/README.md
generated
vendored
Normal file
105
node_modules/express-rate-limit/node_modules/ip-address/README.md
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
[](https://dl.circleci.com/status-badge/redirect/circleci/9fJmTZfn8d8p7GtVt688PY/JjriGjhcxBD6zYKygMZaet/tree/master)
|
||||
[![codecov]](https://codecov.io/github/beaugunderson/ip-address?branch=master)
|
||||
[![downloads]](https://www.npmjs.com/package/ip-address)
|
||||
[![npm]](https://www.npmjs.com/package/ip-address)
|
||||
[![snyk]](https://snyk.io/test/github/beaugunderson/ip-address)
|
||||
|
||||
[codecov]: https://codecov.io/github/beaugunderson/ip-address/coverage.svg?branch=master
|
||||
[downloads]: https://img.shields.io/npm/dm/ip-address.svg
|
||||
[npm]: https://img.shields.io/npm/v/ip-address.svg
|
||||
[snyk]: https://snyk.io/test/github/beaugunderson/ip-address/badge.svg
|
||||
|
||||
## ip-address
|
||||
|
||||
`ip-address` is a library for validating and manipulating IPv4 and IPv6
|
||||
addresses in JavaScript.
|
||||
|
||||
### Upgrading from 9.x to 10.x
|
||||
|
||||
The dependency on `jsbn` was removed thanks to
|
||||
[michal-kocarek](https://github.com/michal-kocarek). Thanks Michal! For
|
||||
clarity, all methods with BigInteger in the name were renamed to BigInt.
|
||||
|
||||
#### Breaking changes
|
||||
|
||||
- `#fromBigInteger()` → `#fromBigInt()`; now returns a native BigInt
|
||||
- `#bigInteger()` → `#bigInt()`; now returns a native BigInt
|
||||
|
||||
### Documentation
|
||||
|
||||
Documentation is available at [ip-address.js.org](http://ip-address.js.org/).
|
||||
|
||||
### Examples
|
||||
|
||||
```js
|
||||
var Address6 = require('ip-address').Address6;
|
||||
|
||||
var address = new Address6('2001:0:ce49:7601:e866:efff:62c3:fffe');
|
||||
|
||||
var teredo = address.inspectTeredo();
|
||||
|
||||
teredo.client4; // '157.60.0.1'
|
||||
```
|
||||
|
||||
### Features
|
||||
|
||||
- Usable via CommonJS or ESM
|
||||
- Parsing of all IPv6 notations
|
||||
- Parsing of IPv6 addresses and ports from URLs with `Address6.fromURL(url)`
|
||||
- Validity checking
|
||||
- Decoding of the [Teredo
|
||||
information](http://en.wikipedia.org/wiki/Teredo_tunneling#IPv6_addressing)
|
||||
in an address
|
||||
- Whether one address is a valid subnet of another
|
||||
- What special properties a given address has (multicast prefix, unique
|
||||
local address prefix, etc.)
|
||||
- Number of subnets of a certain size in a given address
|
||||
- Display methods
|
||||
- Hex, binary, and decimal
|
||||
- Canonical form
|
||||
- Correct form
|
||||
- IPv4-compatible (i.e. `::ffff:192.168.0.1`)
|
||||
- Works in [node](http://nodejs.org/) and the browser (with browserify)
|
||||
- ~1,600 test cases
|
||||
|
||||
### Used by
|
||||
|
||||
- [anon](https://github.com/edsu/anon) which powers
|
||||
[@congressedits](https://twitter.com/congressedits), among
|
||||
[many others](https://github.com/edsu/anon#community)
|
||||
- [base85](https://github.com/noseglid/base85): base85 encoding/decoding
|
||||
- [contrail-web-core](https://github.com/Juniper/contrail-web-core): part of
|
||||
Contrail, a network virtualization solution made by Juniper Networks
|
||||
- [dhcpjs](https://github.com/apaprocki/node-dhcpjs): a DHCP client and server
|
||||
- [epochtalk](https://github.com/epochtalk/epochtalk): next generation forum
|
||||
software
|
||||
- [geoip-web](https://github.com/tfrce/node-geoip-web): a server for
|
||||
quickly geolocating IP addresses
|
||||
- [hexabus](https://github.com/mysmartgrid/hexabus): an IPv6-based home
|
||||
automation bus
|
||||
- [hubot-deploy](https://github.com/atmos/hubot-deploy): GitHub Flow via hubot
|
||||
- [heroku-portscanner](https://github.com/robison/heroku-portscanner): nmap
|
||||
hosted on Heroku
|
||||
- [ipfs-swarm](https://github.com/diasdavid/node-ipfs-swarm): a swarm
|
||||
implementation based on IPFS
|
||||
- [javascript-x-server](https://github.com/GothAck/javascript-x-server): an X
|
||||
server written in JavaScript
|
||||
- [libnmap](https://github.com/jas-/node-libnmap): a node API for nmap
|
||||
- [mail-io](https://github.com/mofux/mail-io): a lightweight SMTP server
|
||||
- [maxmind-db-reader](https://github.com/PaddeK/node-maxmind-db): a library for
|
||||
reading MaxMind database files
|
||||
- [proxy-protocol-v2](https://github.com/ably/proxy-protocol-v2): a proxy
|
||||
protocol encoder/decoder built by [Ably](https://www.ably.io/)
|
||||
- [Samsara](https://github.com/mariusGundersen/Samsara): a Docker web interface
|
||||
- [sis-api](https://github.com/sis-cmdb/sis-api): a configuration management
|
||||
database API
|
||||
- [socks5-client](https://github.com/mattcg/socks5-client): a SOCKS v5 client
|
||||
- [socksified](https://github.com/vially/node-socksified): a SOCKS v5 client
|
||||
- [socksv5](https://github.com/mscdex/socksv5): a SOCKS v5 server/client
|
||||
- [ssdapi](https://github.com/rsolomou/ssdapi): an API created by the
|
||||
University of Portsmouth
|
||||
- [SwitchyOmega](https://github.com/FelisCatus/SwitchyOmega): a [Chrome
|
||||
extension](https://chrome.google.com/webstore/detail/padekgcemlokbadohgkifijomclgjgif)
|
||||
for switching between multiple proxies with ~311k users!
|
||||
- [swiz](https://github.com/racker/node-swiz): a serialization framework built
|
||||
and used by [Rackspace](http://www.rackspace.com/)
|
||||
5
node_modules/express-rate-limit/node_modules/ip-address/dist/address-error.d.ts
generated
vendored
Normal file
5
node_modules/express-rate-limit/node_modules/ip-address/dist/address-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export declare class AddressError extends Error {
|
||||
parseMessage?: string;
|
||||
constructor(message: string, parseMessage?: string);
|
||||
}
|
||||
//# sourceMappingURL=address-error.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/address-error.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/address-error.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"address-error.d.ts","sourceRoot":"","sources":["../src/address-error.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAa,SAAQ,KAAK;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAEV,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;CAOnD"}
|
||||
12
node_modules/express-rate-limit/node_modules/ip-address/dist/address-error.js
generated
vendored
Normal file
12
node_modules/express-rate-limit/node_modules/ip-address/dist/address-error.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AddressError = void 0;
|
||||
class AddressError extends Error {
|
||||
constructor(message, parseMessage) {
|
||||
super(message);
|
||||
this.name = 'AddressError';
|
||||
this.parseMessage = parseMessage;
|
||||
}
|
||||
}
|
||||
exports.AddressError = AddressError;
|
||||
//# sourceMappingURL=address-error.js.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/address-error.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/address-error.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"address-error.js","sourceRoot":"","sources":["../src/address-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,YAAa,SAAQ,KAAK;IAGrC,YAAY,OAAe,EAAE,YAAqB;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAE3B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;CACF;AAVD,oCAUC"}
|
||||
15
node_modules/express-rate-limit/node_modules/ip-address/dist/common.d.ts
generated
vendored
Normal file
15
node_modules/express-rate-limit/node_modules/ip-address/dist/common.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Address4 } from './ipv4';
|
||||
import { Address6 } from './ipv6';
|
||||
export interface ReverseFormOptions {
|
||||
omitSuffix?: boolean;
|
||||
}
|
||||
export declare function isInSubnet(this: Address4 | Address6, address: Address4 | Address6): boolean;
|
||||
export declare function isCorrect(defaultBits: number): (this: Address4 | Address6) => boolean;
|
||||
export declare function numberToPaddedHex(number: number): string;
|
||||
export declare function stringToPaddedHex(numberString: string): string;
|
||||
/**
|
||||
* @param binaryValue Binary representation of a value (e.g. `10`)
|
||||
* @param position Byte position, where 0 is the least significant bit
|
||||
*/
|
||||
export declare function testBit(binaryValue: string, position: number): boolean;
|
||||
//# sourceMappingURL=common.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/common.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/common.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,OAAO,EAAE,QAAQ,GAAG,QAAQ,WAUjF;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,UACpB,QAAQ,GAAG,QAAQ,aAW3C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,UAE/C;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,UAErD;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAStE"}
|
||||
46
node_modules/express-rate-limit/node_modules/ip-address/dist/common.js
generated
vendored
Normal file
46
node_modules/express-rate-limit/node_modules/ip-address/dist/common.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isInSubnet = isInSubnet;
|
||||
exports.isCorrect = isCorrect;
|
||||
exports.numberToPaddedHex = numberToPaddedHex;
|
||||
exports.stringToPaddedHex = stringToPaddedHex;
|
||||
exports.testBit = testBit;
|
||||
function isInSubnet(address) {
|
||||
if (this.subnetMask < address.subnetMask) {
|
||||
return false;
|
||||
}
|
||||
if (this.mask(address.subnetMask) === address.mask()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function isCorrect(defaultBits) {
|
||||
return function () {
|
||||
if (this.addressMinusSuffix !== this.correctForm()) {
|
||||
return false;
|
||||
}
|
||||
if (this.subnetMask === defaultBits && !this.parsedSubnet) {
|
||||
return true;
|
||||
}
|
||||
return this.parsedSubnet === String(this.subnetMask);
|
||||
};
|
||||
}
|
||||
function numberToPaddedHex(number) {
|
||||
return number.toString(16).padStart(2, '0');
|
||||
}
|
||||
function stringToPaddedHex(numberString) {
|
||||
return numberToPaddedHex(parseInt(numberString, 10));
|
||||
}
|
||||
/**
|
||||
* @param binaryValue Binary representation of a value (e.g. `10`)
|
||||
* @param position Byte position, where 0 is the least significant bit
|
||||
*/
|
||||
function testBit(binaryValue, position) {
|
||||
const { length } = binaryValue;
|
||||
if (position > length) {
|
||||
return false;
|
||||
}
|
||||
const positionInString = length - position;
|
||||
return binaryValue.substring(positionInString, positionInString + 1) === '1';
|
||||
}
|
||||
//# sourceMappingURL=common.js.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/common.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/common.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":";;AAOA,gCAUC;AAED,8BAYC;AAED,8CAEC;AAED,8CAEC;AAMD,0BASC;AA/CD,SAAgB,UAAU,CAA4B,OAA4B;IAChF,IAAI,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,SAAS,CAAC,WAAmB;IAC3C,OAAO;QACL,IAAI,IAAI,CAAC,kBAAkB,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,KAAK,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC;AAED,SAAgB,iBAAiB,CAAC,MAAc;IAC9C,OAAO,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,SAAgB,iBAAiB,CAAC,YAAoB;IACpD,OAAO,iBAAiB,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,WAAmB,EAAE,QAAgB;IAC3D,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC;IAE/B,IAAI,QAAQ,GAAG,MAAM,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC3C,OAAO,WAAW,CAAC,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;AAC/E,CAAC"}
|
||||
8
node_modules/express-rate-limit/node_modules/ip-address/dist/ip-address.d.ts
generated
vendored
Normal file
8
node_modules/express-rate-limit/node_modules/ip-address/dist/ip-address.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
export { Address4 } from './ipv4';
|
||||
export { Address6 } from './ipv6';
|
||||
export { AddressError } from './address-error';
|
||||
import * as helpers from './v6/helpers';
|
||||
export declare const v6: {
|
||||
helpers: typeof helpers;
|
||||
};
|
||||
//# sourceMappingURL=ip-address.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ip-address.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ip-address.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ip-address.d.ts","sourceRoot":"","sources":["../src/ip-address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AAExC,eAAO,MAAM,EAAE;;CAAc,CAAC"}
|
||||
35
node_modules/express-rate-limit/node_modules/ip-address/dist/ip-address.js
generated
vendored
Normal file
35
node_modules/express-rate-limit/node_modules/ip-address/dist/ip-address.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.v6 = exports.AddressError = exports.Address6 = exports.Address4 = void 0;
|
||||
var ipv4_1 = require("./ipv4");
|
||||
Object.defineProperty(exports, "Address4", { enumerable: true, get: function () { return ipv4_1.Address4; } });
|
||||
var ipv6_1 = require("./ipv6");
|
||||
Object.defineProperty(exports, "Address6", { enumerable: true, get: function () { return ipv6_1.Address6; } });
|
||||
var address_error_1 = require("./address-error");
|
||||
Object.defineProperty(exports, "AddressError", { enumerable: true, get: function () { return address_error_1.AddressError; } });
|
||||
const helpers = __importStar(require("./v6/helpers"));
|
||||
exports.v6 = { helpers };
|
||||
//# sourceMappingURL=ip-address.js.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ip-address.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ip-address.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ip-address.js","sourceRoot":"","sources":["../src/ip-address.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAAkC;AAAzB,gGAAA,QAAQ,OAAA;AACjB,+BAAkC;AAAzB,gGAAA,QAAQ,OAAA;AACjB,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AAErB,sDAAwC;AAE3B,QAAA,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC"}
|
||||
193
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv4.d.ts
generated
vendored
Normal file
193
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv4.d.ts
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
import * as common from './common';
|
||||
/**
|
||||
* Represents an IPv4 address
|
||||
* @class Address4
|
||||
* @param {string} address - An IPv4 address string
|
||||
*/
|
||||
export declare class Address4 {
|
||||
address: string;
|
||||
addressMinusSuffix?: string;
|
||||
groups: number;
|
||||
parsedAddress: string[];
|
||||
parsedSubnet: string;
|
||||
subnet: string;
|
||||
subnetMask: number;
|
||||
v4: boolean;
|
||||
constructor(address: string);
|
||||
static isValid(address: string): boolean;
|
||||
parse(address: string): string[];
|
||||
/**
|
||||
* Returns the correct form of an address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
correctForm(): string;
|
||||
/**
|
||||
* Returns true if the address is correct, false otherwise
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isCorrect: (this: Address4 | import("./ipv6").Address6) => boolean;
|
||||
/**
|
||||
* Converts a hex string to an IPv4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {string} hex - a hex string to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromHex(hex: string): Address4;
|
||||
/**
|
||||
* Converts an integer into a IPv4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {integer} integer - a number to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromInteger(integer: number): Address4;
|
||||
/**
|
||||
* Return an address from in-addr.arpa form
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address
|
||||
* @returns {Adress4}
|
||||
* @example
|
||||
* var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)
|
||||
* address.correctForm(); // '192.0.2.42'
|
||||
*/
|
||||
static fromArpa(arpaFormAddress: string): Address4;
|
||||
/**
|
||||
* Converts an IPv4 address object to a hex string
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
toHex(): string;
|
||||
/**
|
||||
* Converts an IPv4 address object to an array of bytes
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Array}
|
||||
*/
|
||||
toArray(): number[];
|
||||
/**
|
||||
* Converts an IPv4 address object to an IPv6 address group
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
toGroup6(): string;
|
||||
/**
|
||||
* Returns the address as a `bigint`
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
bigInt(): bigint;
|
||||
/**
|
||||
* Helper function getting start address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
_startAddress(): bigint;
|
||||
/**
|
||||
* The first address in the range given by this address' subnet.
|
||||
* Often referred to as the Network Address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
startAddress(): Address4;
|
||||
/**
|
||||
* The first host address in the range given by this address's subnet ie
|
||||
* the first address after the Network Address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
startAddressExclusive(): Address4;
|
||||
/**
|
||||
* Helper function getting end address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
_endAddress(): bigint;
|
||||
/**
|
||||
* The last address in the range given by this address' subnet
|
||||
* Often referred to as the Broadcast
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
endAddress(): Address4;
|
||||
/**
|
||||
* The last host address in the range given by this address's subnet ie
|
||||
* the last address prior to the Broadcast Address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
endAddressExclusive(): Address4;
|
||||
/**
|
||||
* Converts a BigInt to a v4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {bigint} bigInt - a BigInt to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromBigInt(bigInt: bigint): Address4;
|
||||
/**
|
||||
* Returns the first n bits of the address, defaulting to the
|
||||
* subnet mask
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
mask(mask?: number): string;
|
||||
/**
|
||||
* Returns the bits in the given range as a base-2 string
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {string}
|
||||
*/
|
||||
getBitsBase2(start: number, end: number): string;
|
||||
/**
|
||||
* Return the reversed ip6.arpa form of the address
|
||||
* @memberof Address4
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
reverseForm(options?: common.ReverseFormOptions): string;
|
||||
/**
|
||||
* Returns true if the given address is in the subnet of the current address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isInSubnet: typeof common.isInSubnet;
|
||||
/**
|
||||
* Returns true if the given address is a multicast address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMulticast(): boolean;
|
||||
/**
|
||||
* Returns a zero-padded base-2 string representation of the address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {string}
|
||||
*/
|
||||
binaryZeroPad(): string;
|
||||
/**
|
||||
* Groups an IPv4 address for inclusion at the end of an IPv6 address
|
||||
* @returns {String}
|
||||
*/
|
||||
groupForV6(): string;
|
||||
}
|
||||
//# sourceMappingURL=ipv4.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv4.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv4.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ipv4.d.ts","sourceRoot":"","sources":["../src/ipv4.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAInC;;;;GAIG;AACH,qBAAa,QAAQ;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAoB;IAClC,aAAa,EAAE,MAAM,EAAE,CAAM;IAC7B,YAAY,EAAE,MAAM,CAAM;IAC1B,MAAM,EAAE,MAAM,CAAS;IACvB,UAAU,EAAE,MAAM,CAAM;IACxB,EAAE,EAAE,OAAO,CAAQ;gBAEP,OAAO,EAAE,MAAM;IAsB3B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAcxC,KAAK,CAAC,OAAO,EAAE,MAAM;IAUrB;;;;;OAKG;IACH,WAAW,IAAI,MAAM;IAIrB;;;;;OAKG;IACH,SAAS,0DAAoC;IAE7C;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ;IAcrC;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ;IAI7C;;;;;;;;;OASG;IACH,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ;IASlD;;;;;OAKG;IACH,KAAK,IAAI,MAAM;IAIf;;;;;OAKG;IACH,OAAO,IAAI,MAAM,EAAE;IAInB;;;;;OAKG;IACH,QAAQ,IAAI,MAAM;IAelB;;;;;OAKG;IACH,MAAM,IAAI,MAAM;IAIhB;;;;;OAKG;IACH,aAAa,IAAI,MAAM;IAIvB;;;;;;OAMG;IACH,YAAY,IAAI,QAAQ;IAIxB;;;;;;OAMG;IACH,qBAAqB,IAAI,QAAQ;IAKjC;;;;;OAKG;IACH,WAAW,IAAI,MAAM;IAIrB;;;;;;OAMG;IACH,UAAU,IAAI,QAAQ;IAItB;;;;;;OAMG;IACH,mBAAmB,IAAI,QAAQ;IAK/B;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;IAI3C;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAQ3B;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAIhD;;;;;;;OAOG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,kBAAkB,GAAG,MAAM;IAcxD;;;;;OAKG;IACH,UAAU,2BAAqB;IAE/B;;;;;OAKG;IACH,WAAW,IAAI,OAAO;IAItB;;;;;OAKG;IACH,aAAa,IAAI,MAAM;IAIvB;;;OAGG;IACH,UAAU,IAAI,MAAM;CAYrB"}
|
||||
327
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv4.js
generated
vendored
Normal file
327
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv4.js
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
"use strict";
|
||||
/* eslint-disable no-param-reassign */
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Address4 = void 0;
|
||||
const common = __importStar(require("./common"));
|
||||
const constants = __importStar(require("./v4/constants"));
|
||||
const address_error_1 = require("./address-error");
|
||||
/**
|
||||
* Represents an IPv4 address
|
||||
* @class Address4
|
||||
* @param {string} address - An IPv4 address string
|
||||
*/
|
||||
class Address4 {
|
||||
constructor(address) {
|
||||
this.groups = constants.GROUPS;
|
||||
this.parsedAddress = [];
|
||||
this.parsedSubnet = '';
|
||||
this.subnet = '/32';
|
||||
this.subnetMask = 32;
|
||||
this.v4 = true;
|
||||
/**
|
||||
* Returns true if the address is correct, false otherwise
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
this.isCorrect = common.isCorrect(constants.BITS);
|
||||
/**
|
||||
* Returns true if the given address is in the subnet of the current address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
this.isInSubnet = common.isInSubnet;
|
||||
this.address = address;
|
||||
const subnet = constants.RE_SUBNET_STRING.exec(address);
|
||||
if (subnet) {
|
||||
this.parsedSubnet = subnet[0].replace('/', '');
|
||||
this.subnetMask = parseInt(this.parsedSubnet, 10);
|
||||
this.subnet = `/${this.subnetMask}`;
|
||||
if (this.subnetMask < 0 || this.subnetMask > constants.BITS) {
|
||||
throw new address_error_1.AddressError('Invalid subnet mask.');
|
||||
}
|
||||
address = address.replace(constants.RE_SUBNET_STRING, '');
|
||||
}
|
||||
this.addressMinusSuffix = address;
|
||||
this.parsedAddress = this.parse(address);
|
||||
}
|
||||
static isValid(address) {
|
||||
try {
|
||||
// eslint-disable-next-line no-new
|
||||
new Address4(address);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Parses a v4 address
|
||||
*/
|
||||
parse(address) {
|
||||
const groups = address.split('.');
|
||||
if (!address.match(constants.RE_ADDRESS)) {
|
||||
throw new address_error_1.AddressError('Invalid IPv4 address.');
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
/**
|
||||
* Returns the correct form of an address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
correctForm() {
|
||||
return this.parsedAddress.map((part) => parseInt(part, 10)).join('.');
|
||||
}
|
||||
/**
|
||||
* Converts a hex string to an IPv4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {string} hex - a hex string to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromHex(hex) {
|
||||
const padded = hex.replace(/:/g, '').padStart(8, '0');
|
||||
const groups = [];
|
||||
let i;
|
||||
for (i = 0; i < 8; i += 2) {
|
||||
const h = padded.slice(i, i + 2);
|
||||
groups.push(parseInt(h, 16));
|
||||
}
|
||||
return new Address4(groups.join('.'));
|
||||
}
|
||||
/**
|
||||
* Converts an integer into a IPv4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {integer} integer - a number to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromInteger(integer) {
|
||||
return Address4.fromHex(integer.toString(16));
|
||||
}
|
||||
/**
|
||||
* Return an address from in-addr.arpa form
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address
|
||||
* @returns {Adress4}
|
||||
* @example
|
||||
* var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)
|
||||
* address.correctForm(); // '192.0.2.42'
|
||||
*/
|
||||
static fromArpa(arpaFormAddress) {
|
||||
// remove ending ".in-addr.arpa." or just "."
|
||||
const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.$/, '');
|
||||
const address = leader.split('.').reverse().join('.');
|
||||
return new Address4(address);
|
||||
}
|
||||
/**
|
||||
* Converts an IPv4 address object to a hex string
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
toHex() {
|
||||
return this.parsedAddress.map((part) => common.stringToPaddedHex(part)).join(':');
|
||||
}
|
||||
/**
|
||||
* Converts an IPv4 address object to an array of bytes
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Array}
|
||||
*/
|
||||
toArray() {
|
||||
return this.parsedAddress.map((part) => parseInt(part, 10));
|
||||
}
|
||||
/**
|
||||
* Converts an IPv4 address object to an IPv6 address group
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
toGroup6() {
|
||||
const output = [];
|
||||
let i;
|
||||
for (i = 0; i < constants.GROUPS; i += 2) {
|
||||
output.push(`${common.stringToPaddedHex(this.parsedAddress[i])}${common.stringToPaddedHex(this.parsedAddress[i + 1])}`);
|
||||
}
|
||||
return output.join(':');
|
||||
}
|
||||
/**
|
||||
* Returns the address as a `bigint`
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
bigInt() {
|
||||
return BigInt(`0x${this.parsedAddress.map((n) => common.stringToPaddedHex(n)).join('')}`);
|
||||
}
|
||||
/**
|
||||
* Helper function getting start address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
_startAddress() {
|
||||
return BigInt(`0b${this.mask() + '0'.repeat(constants.BITS - this.subnetMask)}`);
|
||||
}
|
||||
/**
|
||||
* The first address in the range given by this address' subnet.
|
||||
* Often referred to as the Network Address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
startAddress() {
|
||||
return Address4.fromBigInt(this._startAddress());
|
||||
}
|
||||
/**
|
||||
* The first host address in the range given by this address's subnet ie
|
||||
* the first address after the Network Address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
startAddressExclusive() {
|
||||
const adjust = BigInt('1');
|
||||
return Address4.fromBigInt(this._startAddress() + adjust);
|
||||
}
|
||||
/**
|
||||
* Helper function getting end address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
_endAddress() {
|
||||
return BigInt(`0b${this.mask() + '1'.repeat(constants.BITS - this.subnetMask)}`);
|
||||
}
|
||||
/**
|
||||
* The last address in the range given by this address' subnet
|
||||
* Often referred to as the Broadcast
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
endAddress() {
|
||||
return Address4.fromBigInt(this._endAddress());
|
||||
}
|
||||
/**
|
||||
* The last host address in the range given by this address's subnet ie
|
||||
* the last address prior to the Broadcast Address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
endAddressExclusive() {
|
||||
const adjust = BigInt('1');
|
||||
return Address4.fromBigInt(this._endAddress() - adjust);
|
||||
}
|
||||
/**
|
||||
* Converts a BigInt to a v4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {bigint} bigInt - a BigInt to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromBigInt(bigInt) {
|
||||
return Address4.fromHex(bigInt.toString(16));
|
||||
}
|
||||
/**
|
||||
* Returns the first n bits of the address, defaulting to the
|
||||
* subnet mask
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
mask(mask) {
|
||||
if (mask === undefined) {
|
||||
mask = this.subnetMask;
|
||||
}
|
||||
return this.getBitsBase2(0, mask);
|
||||
}
|
||||
/**
|
||||
* Returns the bits in the given range as a base-2 string
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {string}
|
||||
*/
|
||||
getBitsBase2(start, end) {
|
||||
return this.binaryZeroPad().slice(start, end);
|
||||
}
|
||||
/**
|
||||
* Return the reversed ip6.arpa form of the address
|
||||
* @memberof Address4
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
reverseForm(options) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
const reversed = this.correctForm().split('.').reverse().join('.');
|
||||
if (options.omitSuffix) {
|
||||
return reversed;
|
||||
}
|
||||
return `${reversed}.in-addr.arpa.`;
|
||||
}
|
||||
/**
|
||||
* Returns true if the given address is a multicast address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMulticast() {
|
||||
return this.isInSubnet(new Address4('224.0.0.0/4'));
|
||||
}
|
||||
/**
|
||||
* Returns a zero-padded base-2 string representation of the address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {string}
|
||||
*/
|
||||
binaryZeroPad() {
|
||||
return this.bigInt().toString(2).padStart(constants.BITS, '0');
|
||||
}
|
||||
/**
|
||||
* Groups an IPv4 address for inclusion at the end of an IPv6 address
|
||||
* @returns {String}
|
||||
*/
|
||||
groupForV6() {
|
||||
const segments = this.parsedAddress;
|
||||
return this.address.replace(constants.RE_ADDRESS, `<span class="hover-group group-v4 group-6">${segments
|
||||
.slice(0, 2)
|
||||
.join('.')}</span>.<span class="hover-group group-v4 group-7">${segments
|
||||
.slice(2, 4)
|
||||
.join('.')}</span>`);
|
||||
}
|
||||
}
|
||||
exports.Address4 = Address4;
|
||||
//# sourceMappingURL=ipv4.js.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv4.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv4.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
428
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.d.ts
generated
vendored
Normal file
428
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.d.ts
generated
vendored
Normal file
@@ -0,0 +1,428 @@
|
||||
import * as common from './common';
|
||||
import { Address4 } from './ipv4';
|
||||
interface SixToFourProperties {
|
||||
prefix: string;
|
||||
gateway: string;
|
||||
}
|
||||
interface TeredoProperties {
|
||||
prefix: string;
|
||||
server4: string;
|
||||
client4: string;
|
||||
flags: string;
|
||||
coneNat: boolean;
|
||||
microsoft: {
|
||||
reserved: boolean;
|
||||
universalLocal: boolean;
|
||||
groupIndividual: boolean;
|
||||
nonce: string;
|
||||
};
|
||||
udpPort: string;
|
||||
}
|
||||
/**
|
||||
* Represents an IPv6 address
|
||||
* @class Address6
|
||||
* @param {string} address - An IPv6 address string
|
||||
* @param {number} [groups=8] - How many octets to parse
|
||||
* @example
|
||||
* var address = new Address6('2001::/32');
|
||||
*/
|
||||
export declare class Address6 {
|
||||
address4?: Address4;
|
||||
address: string;
|
||||
addressMinusSuffix: string;
|
||||
elidedGroups?: number;
|
||||
elisionBegin?: number;
|
||||
elisionEnd?: number;
|
||||
groups: number;
|
||||
parsedAddress4?: string;
|
||||
parsedAddress: string[];
|
||||
parsedSubnet: string;
|
||||
subnet: string;
|
||||
subnetMask: number;
|
||||
v4: boolean;
|
||||
zone: string;
|
||||
constructor(address: string, optionalGroups?: number);
|
||||
static isValid(address: string): boolean;
|
||||
/**
|
||||
* Convert a BigInt to a v6 address object
|
||||
* @memberof Address6
|
||||
* @static
|
||||
* @param {bigint} bigInt - a BigInt to convert
|
||||
* @returns {Address6}
|
||||
* @example
|
||||
* var bigInt = BigInt('1000000000000');
|
||||
* var address = Address6.fromBigInt(bigInt);
|
||||
* address.correctForm(); // '::e8:d4a5:1000'
|
||||
*/
|
||||
static fromBigInt(bigInt: bigint): Address6;
|
||||
/**
|
||||
* Convert a URL (with optional port number) to an address object
|
||||
* @memberof Address6
|
||||
* @static
|
||||
* @param {string} url - a URL with optional port number
|
||||
* @example
|
||||
* var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/');
|
||||
* addressAndPort.address.correctForm(); // 'ffff::'
|
||||
* addressAndPort.port; // 8080
|
||||
*/
|
||||
static fromURL(url: string): {
|
||||
error: string;
|
||||
address: null;
|
||||
port: null;
|
||||
} | {
|
||||
address: Address6;
|
||||
port: number | null;
|
||||
error?: undefined;
|
||||
};
|
||||
/**
|
||||
* Create an IPv6-mapped address given an IPv4 address
|
||||
* @memberof Address6
|
||||
* @static
|
||||
* @param {string} address - An IPv4 address string
|
||||
* @returns {Address6}
|
||||
* @example
|
||||
* var address = Address6.fromAddress4('192.168.0.1');
|
||||
* address.correctForm(); // '::ffff:c0a8:1'
|
||||
* address.to4in6(); // '::ffff:192.168.0.1'
|
||||
*/
|
||||
static fromAddress4(address: string): Address6;
|
||||
/**
|
||||
* Return an address from ip6.arpa form
|
||||
* @memberof Address6
|
||||
* @static
|
||||
* @param {string} arpaFormAddress - an 'ip6.arpa' form address
|
||||
* @returns {Adress6}
|
||||
* @example
|
||||
* var address = Address6.fromArpa(e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.e.1.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.)
|
||||
* address.correctForm(); // '2001:0:ce49:7601:e866:efff:62c3:fffe'
|
||||
*/
|
||||
static fromArpa(arpaFormAddress: string): Address6;
|
||||
/**
|
||||
* Return the Microsoft UNC transcription of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String} the Microsoft UNC transcription of the address
|
||||
*/
|
||||
microsoftTranscription(): string;
|
||||
/**
|
||||
* Return the first n bits of the address, defaulting to the subnet mask
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @param {number} [mask=subnet] - the number of bits to mask
|
||||
* @returns {String} the first n bits of the address as a string
|
||||
*/
|
||||
mask(mask?: number): string;
|
||||
/**
|
||||
* Return the number of possible subnets of a given size in the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @param {number} [subnetSize=128] - the subnet size
|
||||
* @returns {String}
|
||||
*/
|
||||
possibleSubnets(subnetSize?: number): string;
|
||||
/**
|
||||
* Helper function getting start address.
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
_startAddress(): bigint;
|
||||
/**
|
||||
* The first address in the range given by this address' subnet
|
||||
* Often referred to as the Network Address.
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Address6}
|
||||
*/
|
||||
startAddress(): Address6;
|
||||
/**
|
||||
* The first host address in the range given by this address's subnet ie
|
||||
* the first address after the Network Address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Address6}
|
||||
*/
|
||||
startAddressExclusive(): Address6;
|
||||
/**
|
||||
* Helper function getting end address.
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
_endAddress(): bigint;
|
||||
/**
|
||||
* The last address in the range given by this address' subnet
|
||||
* Often referred to as the Broadcast
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Address6}
|
||||
*/
|
||||
endAddress(): Address6;
|
||||
/**
|
||||
* The last host address in the range given by this address's subnet ie
|
||||
* the last address prior to the Broadcast Address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Address6}
|
||||
*/
|
||||
endAddressExclusive(): Address6;
|
||||
/**
|
||||
* Return the scope of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
getScope(): string;
|
||||
/**
|
||||
* Return the type of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
getType(): string;
|
||||
/**
|
||||
* Return the bits in the given range as a BigInt
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
getBits(start: number, end: number): bigint;
|
||||
/**
|
||||
* Return the bits in the given range as a base-2 string
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
getBitsBase2(start: number, end: number): string;
|
||||
/**
|
||||
* Return the bits in the given range as a base-16 string
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
getBitsBase16(start: number, end: number): string;
|
||||
/**
|
||||
* Return the bits that are set past the subnet mask length
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
getBitsPastSubnet(): string;
|
||||
/**
|
||||
* Return the reversed ip6.arpa form of the address
|
||||
* @memberof Address6
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.omitSuffix - omit the "ip6.arpa" suffix
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
reverseForm(options?: common.ReverseFormOptions): string;
|
||||
/**
|
||||
* Return the correct form of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
correctForm(): string;
|
||||
/**
|
||||
* Return a zero-padded base-2 string representation of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
* @example
|
||||
* var address = new Address6('2001:4860:4001:803::1011');
|
||||
* address.binaryZeroPad();
|
||||
* // '0010000000000001010010000110000001000000000000010000100000000011
|
||||
* // 0000000000000000000000000000000000000000000000000001000000010001'
|
||||
*/
|
||||
binaryZeroPad(): string;
|
||||
parse4in6(address: string): string;
|
||||
parse(address: string): string[];
|
||||
/**
|
||||
* Return the canonical form of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
canonicalForm(): string;
|
||||
/**
|
||||
* Return the decimal form of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
decimal(): string;
|
||||
/**
|
||||
* Return the address as a BigInt
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
bigInt(): bigint;
|
||||
/**
|
||||
* Return the last two groups of this address as an IPv4 address string
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
* @example
|
||||
* var address = new Address6('2001:4860:4001::1825:bf11');
|
||||
* address.to4().correctForm(); // '24.37.191.17'
|
||||
*/
|
||||
to4(): Address4;
|
||||
/**
|
||||
* Return the v4-in-v6 form of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
to4in6(): string;
|
||||
/**
|
||||
* Return an object containing the Teredo properties of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Object}
|
||||
*/
|
||||
inspectTeredo(): TeredoProperties;
|
||||
/**
|
||||
* Return an object containing the 6to4 properties of the address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Object}
|
||||
*/
|
||||
inspect6to4(): SixToFourProperties;
|
||||
/**
|
||||
* Return a v6 6to4 address from a v6 v4inv6 address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Address6}
|
||||
*/
|
||||
to6to4(): Address6 | null;
|
||||
/**
|
||||
* Return a byte array
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Array}
|
||||
*/
|
||||
toByteArray(): number[];
|
||||
/**
|
||||
* Return an unsigned byte array
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {Array}
|
||||
*/
|
||||
toUnsignedByteArray(): number[];
|
||||
/**
|
||||
* Convert a byte array to an Address6 object
|
||||
* @memberof Address6
|
||||
* @static
|
||||
* @returns {Address6}
|
||||
*/
|
||||
static fromByteArray(bytes: Array<any>): Address6;
|
||||
/**
|
||||
* Convert an unsigned byte array to an Address6 object
|
||||
* @memberof Address6
|
||||
* @static
|
||||
* @returns {Address6}
|
||||
*/
|
||||
static fromUnsignedByteArray(bytes: Array<any>): Address6;
|
||||
/**
|
||||
* Returns true if the given address is in the subnet of the current address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isInSubnet: typeof common.isInSubnet;
|
||||
/**
|
||||
* Returns true if the address is correct, false otherwise
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isCorrect: (this: Address4 | Address6) => boolean;
|
||||
/**
|
||||
* Returns true if the address is in the canonical form, false otherwise
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isCanonical(): boolean;
|
||||
/**
|
||||
* Returns true if the address is a link local address, false otherwise
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isLinkLocal(): boolean;
|
||||
/**
|
||||
* Returns true if the address is a multicast address, false otherwise
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMulticast(): boolean;
|
||||
/**
|
||||
* Returns true if the address is a v4-in-v6 address, false otherwise
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
is4(): boolean;
|
||||
/**
|
||||
* Returns true if the address is a Teredo address, false otherwise
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isTeredo(): boolean;
|
||||
/**
|
||||
* Returns true if the address is a 6to4 address, false otherwise
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
is6to4(): boolean;
|
||||
/**
|
||||
* Returns true if the address is a loopback address, false otherwise
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isLoopback(): boolean;
|
||||
/**
|
||||
* @returns {String} the address in link form with a default port of 80
|
||||
*/
|
||||
href(optionalPort?: number | string): string;
|
||||
/**
|
||||
* @returns {String} a link suitable for conveying the address via a URL hash
|
||||
*/
|
||||
link(options?: {
|
||||
className?: string;
|
||||
prefix?: string;
|
||||
v4?: boolean;
|
||||
}): string;
|
||||
/**
|
||||
* Groups an address
|
||||
* @returns {String}
|
||||
*/
|
||||
group(): string;
|
||||
/**
|
||||
* Generate a regular expression string that can be used to find or validate
|
||||
* all variations of this address
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @param {boolean} substringSearch
|
||||
* @returns {string}
|
||||
*/
|
||||
regularExpressionString(this: Address6, substringSearch?: boolean): string;
|
||||
/**
|
||||
* Generate a regular expression that can be used to find or validate all
|
||||
* variations of this address.
|
||||
* @memberof Address6
|
||||
* @instance
|
||||
* @param {boolean} substringSearch
|
||||
* @returns {RegExp}
|
||||
*/
|
||||
regularExpression(this: Address6, substringSearch?: boolean): RegExp;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=ipv6.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ipv6.d.ts","sourceRoot":"","sources":["../src/ipv6.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAInC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AA4DlC,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE;QACT,QAAQ,EAAE,OAAO,CAAC;QAClB,cAAc,EAAE,OAAO,CAAC;QACxB,eAAe,EAAE,OAAO,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,qBAAa,QAAQ;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAM;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAM;IAC1B,MAAM,EAAE,MAAM,CAAU;IACxB,UAAU,EAAE,MAAM,CAAO;IACzB,EAAE,EAAE,OAAO,CAAS;IACpB,IAAI,EAAE,MAAM,CAAM;gBAEN,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM;IA0CpD,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAWxC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;IAY3C;;;;;;;;;OASG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM;;;;;;;;;IA4D1B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ;IAQ9C;;;;;;;;;OASG;IACH,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ;IAsBlD;;;;;OAKG;IACH,sBAAsB,IAAI,MAAM;IAIhC;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,GAAE,MAAwB,GAAG,MAAM;IAI5C;;;;;;OAMG;IAEH,eAAe,CAAC,UAAU,GAAE,MAAY,GAAG,MAAM;IAYjD;;;;;OAKG;IACH,aAAa,IAAI,MAAM;IAIvB;;;;;;OAMG;IACH,YAAY,IAAI,QAAQ;IAIxB;;;;;;OAMG;IACH,qBAAqB,IAAI,QAAQ;IAKjC;;;;;OAKG;IACH,WAAW,IAAI,MAAM;IAIrB;;;;;;OAMG;IACH,UAAU,IAAI,QAAQ;IAItB;;;;;;OAMG;IACH,mBAAmB,IAAI,QAAQ;IAK/B;;;;;OAKG;IACH,QAAQ,IAAI,MAAM;IAUlB;;;;;OAKG;IACH,OAAO,IAAI,MAAM;IAUjB;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAI3C;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAIhD;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAYjD;;;;;OAKG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;;;;;;OAOG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,kBAAkB,GAAG,MAAM;IA6BxD;;;;;OAKG;IACH,WAAW,IAAI,MAAM;IAqDrB;;;;;;;;;;OAUG;IACH,aAAa,IAAI,MAAM;IAKvB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAiClC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IA0EhC;;;;;OAKG;IACH,aAAa,IAAI,MAAM;IAIvB;;;;;OAKG;IACH,OAAO,IAAI,MAAM;IAIjB;;;;;OAKG;IACH,MAAM,IAAI,MAAM;IAIhB;;;;;;;;OAQG;IACH,GAAG,IAAI,QAAQ;IAMf;;;;;OAKG;IACH,MAAM,IAAI,MAAM;IAehB;;;;;OAKG;IACH,aAAa,IAAI,gBAAgB;IA0DjC;;;;;OAKG;IACH,WAAW,IAAI,mBAAmB;IAgBlC;;;;;OAKG;IACH,MAAM,IAAI,QAAQ,GAAG,IAAI;IAgBzB;;;;;OAKG;IACH,WAAW,IAAI,MAAM,EAAE;IAcvB;;;;;OAKG;IACH,mBAAmB,IAAI,MAAM,EAAE;IAI/B;;;;;OAKG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ;IAIjD;;;;;OAKG;IACH,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ;IAezD;;;;;OAKG;IACH,UAAU,2BAAqB;IAE/B;;;;;OAKG;IACH,SAAS,yCAAqC;IAE9C;;;;;OAKG;IACH,WAAW,IAAI,OAAO;IAItB;;;;;OAKG;IACH,WAAW,IAAI,OAAO;IAYtB;;;;;OAKG;IACH,WAAW,IAAI,OAAO;IAItB;;;;;OAKG;IACH,GAAG,IAAI,OAAO;IAId;;;;;OAKG;IACH,QAAQ,IAAI,OAAO;IAInB;;;;;OAKG;IACH,MAAM,IAAI,OAAO;IAIjB;;;;;OAKG;IACH,UAAU,IAAI,OAAO;IAMrB;;OAEG;IACH,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAU5C;;OAEG;IACH,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM;IAgC7E;;;OAGG;IACH,KAAK,IAAI,MAAM;IA8Cf;;;;;;;OAOG;IACH,uBAAuB,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,GAAE,OAAe,GAAG,MAAM;IAgDjF;;;;;;;OAOG;IACH,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,GAAE,OAAe,GAAG,MAAM;CAI5E"}
|
||||
1003
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.js
generated
vendored
Normal file
1003
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
5
node_modules/express-rate-limit/node_modules/ip-address/dist/v4/constants.d.ts
generated
vendored
Normal file
5
node_modules/express-rate-limit/node_modules/ip-address/dist/v4/constants.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export declare const BITS = 32;
|
||||
export declare const GROUPS = 4;
|
||||
export declare const RE_ADDRESS: RegExp;
|
||||
export declare const RE_SUBNET_STRING: RegExp;
|
||||
//# sourceMappingURL=constants.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v4/constants.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v4/constants.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/v4/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,KAAK,CAAC;AACvB,eAAO,MAAM,MAAM,IAAI,CAAC;AAExB,eAAO,MAAM,UAAU,QAC8I,CAAC;AAEtK,eAAO,MAAM,gBAAgB,QAAe,CAAC"}
|
||||
8
node_modules/express-rate-limit/node_modules/ip-address/dist/v4/constants.js
generated
vendored
Normal file
8
node_modules/express-rate-limit/node_modules/ip-address/dist/v4/constants.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0;
|
||||
exports.BITS = 32;
|
||||
exports.GROUPS = 4;
|
||||
exports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g;
|
||||
exports.RE_SUBNET_STRING = /\/\d{1,2}$/;
|
||||
//# sourceMappingURL=constants.js.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v4/constants.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v4/constants.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/v4/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,IAAI,GAAG,EAAE,CAAC;AACV,QAAA,MAAM,GAAG,CAAC,CAAC;AAEX,QAAA,UAAU,GACrB,mKAAmK,CAAC;AAEzJ,QAAA,gBAAgB,GAAG,YAAY,CAAC"}
|
||||
45
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/constants.d.ts
generated
vendored
Normal file
45
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/constants.d.ts
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
export declare const BITS = 128;
|
||||
export declare const GROUPS = 8;
|
||||
/**
|
||||
* Represents IPv6 address scopes
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export declare const SCOPES: {
|
||||
[key: number]: string | undefined;
|
||||
};
|
||||
/**
|
||||
* Represents IPv6 address types
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export declare const TYPES: {
|
||||
[key: string]: string | undefined;
|
||||
};
|
||||
/**
|
||||
* A regular expression that matches bad characters in an IPv6 address
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export declare const RE_BAD_CHARACTERS: RegExp;
|
||||
/**
|
||||
* A regular expression that matches an incorrect IPv6 address
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export declare const RE_BAD_ADDRESS: RegExp;
|
||||
/**
|
||||
* A regular expression that matches an IPv6 subnet
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export declare const RE_SUBNET_STRING: RegExp;
|
||||
/**
|
||||
* A regular expression that matches an IPv6 zone
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export declare const RE_ZONE_STRING: RegExp;
|
||||
export declare const RE_URL: RegExp;
|
||||
export declare const RE_URL_WITH_PORT: RegExp;
|
||||
//# sourceMappingURL=constants.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/constants.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/constants.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/v6/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,MAAM,CAAC;AACxB,eAAO,MAAM,MAAM,IAAI,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAS9C,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,KAAK,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAuB7C,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,QAAqB,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAA6C,CAAC;AAEzE;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAqB,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAS,CAAC;AAErC,eAAO,MAAM,MAAM,QAAgC,CAAC;AACpD,eAAO,MAAM,gBAAgB,QAAkC,CAAC"}
|
||||
76
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/constants.js
generated
vendored
Normal file
76
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/constants.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RE_URL_WITH_PORT = exports.RE_URL = exports.RE_ZONE_STRING = exports.RE_SUBNET_STRING = exports.RE_BAD_ADDRESS = exports.RE_BAD_CHARACTERS = exports.TYPES = exports.SCOPES = exports.GROUPS = exports.BITS = void 0;
|
||||
exports.BITS = 128;
|
||||
exports.GROUPS = 8;
|
||||
/**
|
||||
* Represents IPv6 address scopes
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
exports.SCOPES = {
|
||||
0: 'Reserved',
|
||||
1: 'Interface local',
|
||||
2: 'Link local',
|
||||
4: 'Admin local',
|
||||
5: 'Site local',
|
||||
8: 'Organization local',
|
||||
14: 'Global',
|
||||
15: 'Reserved',
|
||||
};
|
||||
/**
|
||||
* Represents IPv6 address types
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
exports.TYPES = {
|
||||
'ff01::1/128': 'Multicast (All nodes on this interface)',
|
||||
'ff01::2/128': 'Multicast (All routers on this interface)',
|
||||
'ff02::1/128': 'Multicast (All nodes on this link)',
|
||||
'ff02::2/128': 'Multicast (All routers on this link)',
|
||||
'ff05::2/128': 'Multicast (All routers in this site)',
|
||||
'ff02::5/128': 'Multicast (OSPFv3 AllSPF routers)',
|
||||
'ff02::6/128': 'Multicast (OSPFv3 AllDR routers)',
|
||||
'ff02::9/128': 'Multicast (RIP routers)',
|
||||
'ff02::a/128': 'Multicast (EIGRP routers)',
|
||||
'ff02::d/128': 'Multicast (PIM routers)',
|
||||
'ff02::16/128': 'Multicast (MLDv2 reports)',
|
||||
'ff01::fb/128': 'Multicast (mDNSv6)',
|
||||
'ff02::fb/128': 'Multicast (mDNSv6)',
|
||||
'ff05::fb/128': 'Multicast (mDNSv6)',
|
||||
'ff02::1:2/128': 'Multicast (All DHCP servers and relay agents on this link)',
|
||||
'ff05::1:2/128': 'Multicast (All DHCP servers and relay agents in this site)',
|
||||
'ff02::1:3/128': 'Multicast (All DHCP servers on this link)',
|
||||
'ff05::1:3/128': 'Multicast (All DHCP servers in this site)',
|
||||
'::/128': 'Unspecified',
|
||||
'::1/128': 'Loopback',
|
||||
'ff00::/8': 'Multicast',
|
||||
'fe80::/10': 'Link-local unicast',
|
||||
};
|
||||
/**
|
||||
* A regular expression that matches bad characters in an IPv6 address
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
exports.RE_BAD_CHARACTERS = /([^0-9a-f:/%])/gi;
|
||||
/**
|
||||
* A regular expression that matches an incorrect IPv6 address
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
exports.RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi;
|
||||
/**
|
||||
* A regular expression that matches an IPv6 subnet
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
exports.RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/;
|
||||
/**
|
||||
* A regular expression that matches an IPv6 zone
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
exports.RE_ZONE_STRING = /%.*$/;
|
||||
exports.RE_URL = /^\[{0,1}([0-9a-f:]+)\]{0,1}/;
|
||||
exports.RE_URL_WITH_PORT = /\[([0-9a-f:]+)\]:([0-9]{1,5})/;
|
||||
//# sourceMappingURL=constants.js.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/constants.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/constants.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/v6/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,IAAI,GAAG,GAAG,CAAC;AACX,QAAA,MAAM,GAAG,CAAC,CAAC;AAExB;;;;GAIG;AACU,QAAA,MAAM,GAA0C;IAC3D,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,iBAAiB;IACpB,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,oBAAoB;IACvB,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,UAAU;CACN,CAAC;AAEX;;;;GAIG;AACU,QAAA,KAAK,GAA0C;IAC1D,aAAa,EAAE,yCAAyC;IACxD,aAAa,EAAE,2CAA2C;IAC1D,aAAa,EAAE,oCAAoC;IACnD,aAAa,EAAE,sCAAsC;IACrD,aAAa,EAAE,sCAAsC;IACrD,aAAa,EAAE,mCAAmC;IAClD,aAAa,EAAE,kCAAkC;IACjD,aAAa,EAAE,yBAAyB;IACxC,aAAa,EAAE,2BAA2B;IAC1C,aAAa,EAAE,yBAAyB;IACxC,cAAc,EAAE,2BAA2B;IAC3C,cAAc,EAAE,oBAAoB;IACpC,cAAc,EAAE,oBAAoB;IACpC,cAAc,EAAE,oBAAoB;IACpC,eAAe,EAAE,4DAA4D;IAC7E,eAAe,EAAE,4DAA4D;IAC7E,eAAe,EAAE,2CAA2C;IAC5D,eAAe,EAAE,2CAA2C;IAC5D,QAAQ,EAAE,aAAa;IACvB,SAAS,EAAE,UAAU;IACrB,UAAU,EAAE,WAAW;IACvB,WAAW,EAAE,oBAAoB;CACzB,CAAC;AAEX;;;;GAIG;AACU,QAAA,iBAAiB,GAAG,kBAAkB,CAAC;AAEpD;;;;GAIG;AACU,QAAA,cAAc,GAAG,0CAA0C,CAAC;AAEzE;;;;GAIG;AACU,QAAA,gBAAgB,GAAG,kBAAkB,CAAC;AAEnD;;;;GAIG;AACU,QAAA,cAAc,GAAG,MAAM,CAAC;AAExB,QAAA,MAAM,GAAG,6BAA6B,CAAC;AACvC,QAAA,gBAAgB,GAAG,+BAA+B,CAAC"}
|
||||
18
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/helpers.d.ts
generated
vendored
Normal file
18
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/helpers.d.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @returns {String} the string with all zeroes contained in a <span>
|
||||
*/
|
||||
export declare function spanAllZeroes(s: string): string;
|
||||
/**
|
||||
* @returns {String} the string with each character contained in a <span>
|
||||
*/
|
||||
export declare function spanAll(s: string, offset?: number): string;
|
||||
/**
|
||||
* @returns {String} the string with leading zeroes contained in a <span>
|
||||
*/
|
||||
export declare function spanLeadingZeroes(address: string): string;
|
||||
/**
|
||||
* Groups an address
|
||||
* @returns {String} a grouped address
|
||||
*/
|
||||
export declare function simpleGroup(addressString: string, offset?: number): string[];
|
||||
//# sourceMappingURL=helpers.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/helpers.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/helpers.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/v6/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM,CAQ7D;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM,EAAE,CAU/E"}
|
||||
45
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/helpers.js
generated
vendored
Normal file
45
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/helpers.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.spanAllZeroes = spanAllZeroes;
|
||||
exports.spanAll = spanAll;
|
||||
exports.spanLeadingZeroes = spanLeadingZeroes;
|
||||
exports.simpleGroup = simpleGroup;
|
||||
/**
|
||||
* @returns {String} the string with all zeroes contained in a <span>
|
||||
*/
|
||||
function spanAllZeroes(s) {
|
||||
return s.replace(/(0+)/g, '<span class="zero">$1</span>');
|
||||
}
|
||||
/**
|
||||
* @returns {String} the string with each character contained in a <span>
|
||||
*/
|
||||
function spanAll(s, offset = 0) {
|
||||
const letters = s.split('');
|
||||
return letters
|
||||
.map((n, i) => `<span class="digit value-${n} position-${i + offset}">${spanAllZeroes(n)}</span>`)
|
||||
.join('');
|
||||
}
|
||||
function spanLeadingZeroesSimple(group) {
|
||||
return group.replace(/^(0+)/, '<span class="zero">$1</span>');
|
||||
}
|
||||
/**
|
||||
* @returns {String} the string with leading zeroes contained in a <span>
|
||||
*/
|
||||
function spanLeadingZeroes(address) {
|
||||
const groups = address.split(':');
|
||||
return groups.map((g) => spanLeadingZeroesSimple(g)).join(':');
|
||||
}
|
||||
/**
|
||||
* Groups an address
|
||||
* @returns {String} a grouped address
|
||||
*/
|
||||
function simpleGroup(addressString, offset = 0) {
|
||||
const groups = addressString.split(':');
|
||||
return groups.map((g, i) => {
|
||||
if (/group-v4/.test(g)) {
|
||||
return g;
|
||||
}
|
||||
return `<span class="hover-group group-${i + offset}">${spanLeadingZeroesSimple(g)}</span>`;
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=helpers.js.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/helpers.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/helpers.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/v6/helpers.ts"],"names":[],"mappings":";;AAGA,sCAEC;AAKD,0BAQC;AASD,8CAIC;AAMD,kCAUC;AA/CD;;GAEG;AACH,SAAgB,aAAa,CAAC,CAAS;IACrC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,SAAgB,OAAO,CAAC,CAAS,EAAE,SAAiB,CAAC;IACnD,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAE5B,OAAO,OAAO;SACX,GAAG,CACF,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,4BAA4B,CAAC,aAAa,CAAC,GAAG,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,SAAS,CAC7F;SACA,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAa;IAC5C,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;AAChE,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,OAAe;IAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,SAAgB,WAAW,CAAC,aAAqB,EAAE,SAAiB,CAAC;IACnE,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAExC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACzB,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,kCAAkC,CAAC,GAAG,MAAM,KAAK,uBAAuB,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC"}
|
||||
6
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/regular-expressions.d.ts
generated
vendored
Normal file
6
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/regular-expressions.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export declare function groupPossibilities(possibilities: string[]): string;
|
||||
export declare function padGroup(group: string): string;
|
||||
export declare const ADDRESS_BOUNDARY = "[^A-Fa-f0-9:]";
|
||||
export declare function simpleRegularExpression(groups: string[]): string;
|
||||
export declare function possibleElisions(elidedGroups: number, moreLeft?: boolean, moreRight?: boolean): string;
|
||||
//# sourceMappingURL=regular-expressions.d.ts.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/regular-expressions.d.ts.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/regular-expressions.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"regular-expressions.d.ts","sourceRoot":"","sources":["../../src/v6/regular-expressions.ts"],"names":[],"mappings":"AAEA,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAElE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,UA+BvD;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,OAAO,EAClB,SAAS,CAAC,EAAE,OAAO,GAClB,MAAM,CAwCR"}
|
||||
95
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/regular-expressions.js
generated
vendored
Normal file
95
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/regular-expressions.js
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ADDRESS_BOUNDARY = void 0;
|
||||
exports.groupPossibilities = groupPossibilities;
|
||||
exports.padGroup = padGroup;
|
||||
exports.simpleRegularExpression = simpleRegularExpression;
|
||||
exports.possibleElisions = possibleElisions;
|
||||
const v6 = __importStar(require("./constants"));
|
||||
function groupPossibilities(possibilities) {
|
||||
return `(${possibilities.join('|')})`;
|
||||
}
|
||||
function padGroup(group) {
|
||||
if (group.length < 4) {
|
||||
return `0{0,${4 - group.length}}${group}`;
|
||||
}
|
||||
return group;
|
||||
}
|
||||
exports.ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]';
|
||||
function simpleRegularExpression(groups) {
|
||||
const zeroIndexes = [];
|
||||
groups.forEach((group, i) => {
|
||||
const groupInteger = parseInt(group, 16);
|
||||
if (groupInteger === 0) {
|
||||
zeroIndexes.push(i);
|
||||
}
|
||||
});
|
||||
// You can technically elide a single 0, this creates the regular expressions
|
||||
// to match that eventuality
|
||||
const possibilities = zeroIndexes.map((zeroIndex) => groups
|
||||
.map((group, i) => {
|
||||
if (i === zeroIndex) {
|
||||
const elision = i === 0 || i === v6.GROUPS - 1 ? ':' : '';
|
||||
return groupPossibilities([padGroup(group), elision]);
|
||||
}
|
||||
return padGroup(group);
|
||||
})
|
||||
.join(':'));
|
||||
// The simplest case
|
||||
possibilities.push(groups.map(padGroup).join(':'));
|
||||
return groupPossibilities(possibilities);
|
||||
}
|
||||
function possibleElisions(elidedGroups, moreLeft, moreRight) {
|
||||
const left = moreLeft ? '' : ':';
|
||||
const right = moreRight ? '' : ':';
|
||||
const possibilities = [];
|
||||
// 1. elision of everything (::)
|
||||
if (!moreLeft && !moreRight) {
|
||||
possibilities.push('::');
|
||||
}
|
||||
// 2. complete elision of the middle
|
||||
if (moreLeft && moreRight) {
|
||||
possibilities.push('');
|
||||
}
|
||||
if ((moreRight && !moreLeft) || (!moreRight && moreLeft)) {
|
||||
// 3. complete elision of one side
|
||||
possibilities.push(':');
|
||||
}
|
||||
// 4. elision from the left side
|
||||
possibilities.push(`${left}(:0{1,4}){1,${elidedGroups - 1}}`);
|
||||
// 5. elision from the right side
|
||||
possibilities.push(`(0{1,4}:){1,${elidedGroups - 1}}${right}`);
|
||||
// 6. no elision
|
||||
possibilities.push(`(0{1,4}:){${elidedGroups - 1}}0{1,4}`);
|
||||
// 7. elision (including sloppy elision) from the middle
|
||||
for (let groups = 1; groups < elidedGroups - 1; groups++) {
|
||||
for (let position = 1; position < elidedGroups - groups; position++) {
|
||||
possibilities.push(`(0{1,4}:){${position}}:(0{1,4}:){${elidedGroups - position - groups - 1}}0{1,4}`);
|
||||
}
|
||||
}
|
||||
return groupPossibilities(possibilities);
|
||||
}
|
||||
//# sourceMappingURL=regular-expressions.js.map
|
||||
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/regular-expressions.js.map
generated
vendored
Normal file
1
node_modules/express-rate-limit/node_modules/ip-address/dist/v6/regular-expressions.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"regular-expressions.js","sourceRoot":"","sources":["../../src/v6/regular-expressions.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,gDAEC;AAED,4BAMC;AAID,0DA+BC;AAED,4CA4CC;AA7FD,gDAAkC;AAElC,SAAgB,kBAAkB,CAAC,aAAuB;IACxD,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AACxC,CAAC;AAED,SAAgB,QAAQ,CAAC,KAAa;IACpC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAEY,QAAA,gBAAgB,GAAG,eAAe,CAAC;AAEhD,SAAgB,uBAAuB,CAAC,MAAgB;IACtD,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEzC,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;YACvB,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,4BAA4B;IAC5B,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAClD,MAAM;SACH,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAChB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAE1D,OAAO,kBAAkB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CACb,CAAC;IAEF,oBAAoB;IACpB,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAEnD,OAAO,kBAAkB,CAAC,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED,SAAgB,gBAAgB,CAC9B,YAAoB,EACpB,QAAkB,EAClB,SAAmB;IAEnB,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IACjC,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAEnC,MAAM,aAAa,GAAG,EAAE,CAAC;IAEzB,gCAAgC;IAChC,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,oCAAoC;IACpC,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;QAC1B,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;QACzD,kCAAkC;QAClC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,gCAAgC;IAChC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,eAAe,YAAY,GAAG,CAAC,GAAG,CAAC,CAAC;IAE9D,iCAAiC;IACjC,aAAa,CAAC,IAAI,CAAC,eAAe,YAAY,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;IAE/D,gBAAgB;IAChB,aAAa,CAAC,IAAI,CAAC,aAAa,YAAY,GAAG,CAAC,SAAS,CAAC,CAAC;IAE3D,wDAAwD;IACxD,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;QACzD,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;YACpE,aAAa,CAAC,IAAI,CAChB,aAAa,QAAQ,eAAe,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,CAAC,SAAS,CAClF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,kBAAkB,CAAC,aAAa,CAAC,CAAC;AAC3C,CAAC"}
|
||||
78
node_modules/express-rate-limit/node_modules/ip-address/package.json
generated
vendored
Normal file
78
node_modules/express-rate-limit/node_modules/ip-address/package.json
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"name": "ip-address",
|
||||
"description": "A library for parsing IPv4 and IPv6 IP addresses in node and the browser.",
|
||||
"keywords": [
|
||||
"ipv6",
|
||||
"ipv4",
|
||||
"browser",
|
||||
"validation"
|
||||
],
|
||||
"version": "10.0.1",
|
||||
"author": "Beau Gunderson <beau@beaugunderson.com> (https://beaugunderson.com/)",
|
||||
"license": "MIT",
|
||||
"main": "dist/ip-address.js",
|
||||
"types": "dist/ip-address.d.ts",
|
||||
"scripts": {
|
||||
"docs": "documentation build --github --output docs --format html ./ip-address.js",
|
||||
"build": "rm -rf dist; mkdir dist; tsc",
|
||||
"prepack": "npm run build",
|
||||
"release": "release-it",
|
||||
"test-ci": "nyc mocha",
|
||||
"test": "mocha",
|
||||
"watch": "mocha --watch"
|
||||
},
|
||||
"nyc": {
|
||||
"extension": [
|
||||
".ts"
|
||||
],
|
||||
"exclude": [
|
||||
"**/*.d.ts",
|
||||
".eslintrc.js",
|
||||
"coverage/",
|
||||
"dist/",
|
||||
"test/",
|
||||
"tmp/"
|
||||
],
|
||||
"reporter": [
|
||||
"html",
|
||||
"lcov",
|
||||
"text"
|
||||
],
|
||||
"all": true
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/beaugunderson/ip-address.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^5.0.0",
|
||||
"@types/mocha": "^10.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.8.0",
|
||||
"@typescript-eslint/parser": "^8.8.0",
|
||||
"chai": "^5.1.1",
|
||||
"documentation": "^14.0.3",
|
||||
"eslint": "^8.50.0",
|
||||
"eslint_d": "^14.0.4",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-filenames": "^1.3.2",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
|
||||
"mocha": "^10.7.3",
|
||||
"nyc": "^17.1.0",
|
||||
"prettier": "^3.3.3",
|
||||
"release-it": "^17.6.0",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tsx": "^4.19.1",
|
||||
"typescript": "<5.6.0"
|
||||
}
|
||||
}
|
||||
11
node_modules/express-rate-limit/node_modules/ip-address/src/address-error.ts
generated
vendored
Normal file
11
node_modules/express-rate-limit/node_modules/ip-address/src/address-error.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export class AddressError extends Error {
|
||||
parseMessage?: string;
|
||||
|
||||
constructor(message: string, parseMessage?: string) {
|
||||
super(message);
|
||||
|
||||
this.name = 'AddressError';
|
||||
|
||||
this.parseMessage = parseMessage;
|
||||
}
|
||||
}
|
||||
55
node_modules/express-rate-limit/node_modules/ip-address/src/common.ts
generated
vendored
Normal file
55
node_modules/express-rate-limit/node_modules/ip-address/src/common.ts
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Address4 } from './ipv4';
|
||||
import { Address6 } from './ipv6';
|
||||
|
||||
export interface ReverseFormOptions {
|
||||
omitSuffix?: boolean;
|
||||
}
|
||||
|
||||
export function isInSubnet(this: Address4 | Address6, address: Address4 | Address6) {
|
||||
if (this.subnetMask < address.subnetMask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.mask(address.subnetMask) === address.mask()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isCorrect(defaultBits: number) {
|
||||
return function (this: Address4 | Address6) {
|
||||
if (this.addressMinusSuffix !== this.correctForm()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.subnetMask === defaultBits && !this.parsedSubnet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.parsedSubnet === String(this.subnetMask);
|
||||
};
|
||||
}
|
||||
|
||||
export function numberToPaddedHex(number: number) {
|
||||
return number.toString(16).padStart(2, '0');
|
||||
}
|
||||
|
||||
export function stringToPaddedHex(numberString: string) {
|
||||
return numberToPaddedHex(parseInt(numberString, 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param binaryValue Binary representation of a value (e.g. `10`)
|
||||
* @param position Byte position, where 0 is the least significant bit
|
||||
*/
|
||||
export function testBit(binaryValue: string, position: number): boolean {
|
||||
const { length } = binaryValue;
|
||||
|
||||
if (position > length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const positionInString = length - position;
|
||||
return binaryValue.substring(positionInString, positionInString + 1) === '1';
|
||||
}
|
||||
7
node_modules/express-rate-limit/node_modules/ip-address/src/ip-address.ts
generated
vendored
Normal file
7
node_modules/express-rate-limit/node_modules/ip-address/src/ip-address.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export { Address4 } from './ipv4';
|
||||
export { Address6 } from './ipv6';
|
||||
export { AddressError } from './address-error';
|
||||
|
||||
import * as helpers from './v6/helpers';
|
||||
|
||||
export const v6 = { helpers };
|
||||
356
node_modules/express-rate-limit/node_modules/ip-address/src/ipv4.ts
generated
vendored
Normal file
356
node_modules/express-rate-limit/node_modules/ip-address/src/ipv4.ts
generated
vendored
Normal file
@@ -0,0 +1,356 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
import * as common from './common';
|
||||
import * as constants from './v4/constants';
|
||||
import { AddressError } from './address-error';
|
||||
|
||||
/**
|
||||
* Represents an IPv4 address
|
||||
* @class Address4
|
||||
* @param {string} address - An IPv4 address string
|
||||
*/
|
||||
export class Address4 {
|
||||
address: string;
|
||||
addressMinusSuffix?: string;
|
||||
groups: number = constants.GROUPS;
|
||||
parsedAddress: string[] = [];
|
||||
parsedSubnet: string = '';
|
||||
subnet: string = '/32';
|
||||
subnetMask: number = 32;
|
||||
v4: boolean = true;
|
||||
|
||||
constructor(address: string) {
|
||||
this.address = address;
|
||||
|
||||
const subnet = constants.RE_SUBNET_STRING.exec(address);
|
||||
|
||||
if (subnet) {
|
||||
this.parsedSubnet = subnet[0].replace('/', '');
|
||||
this.subnetMask = parseInt(this.parsedSubnet, 10);
|
||||
this.subnet = `/${this.subnetMask}`;
|
||||
|
||||
if (this.subnetMask < 0 || this.subnetMask > constants.BITS) {
|
||||
throw new AddressError('Invalid subnet mask.');
|
||||
}
|
||||
|
||||
address = address.replace(constants.RE_SUBNET_STRING, '');
|
||||
}
|
||||
|
||||
this.addressMinusSuffix = address;
|
||||
|
||||
this.parsedAddress = this.parse(address);
|
||||
}
|
||||
|
||||
static isValid(address: string): boolean {
|
||||
try {
|
||||
// eslint-disable-next-line no-new
|
||||
new Address4(address);
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses a v4 address
|
||||
*/
|
||||
parse(address: string) {
|
||||
const groups = address.split('.');
|
||||
|
||||
if (!address.match(constants.RE_ADDRESS)) {
|
||||
throw new AddressError('Invalid IPv4 address.');
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the correct form of an address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
correctForm(): string {
|
||||
return this.parsedAddress.map((part) => parseInt(part, 10)).join('.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the address is correct, false otherwise
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isCorrect = common.isCorrect(constants.BITS);
|
||||
|
||||
/**
|
||||
* Converts a hex string to an IPv4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {string} hex - a hex string to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromHex(hex: string): Address4 {
|
||||
const padded = hex.replace(/:/g, '').padStart(8, '0');
|
||||
const groups = [];
|
||||
let i;
|
||||
|
||||
for (i = 0; i < 8; i += 2) {
|
||||
const h = padded.slice(i, i + 2);
|
||||
|
||||
groups.push(parseInt(h, 16));
|
||||
}
|
||||
|
||||
return new Address4(groups.join('.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an integer into a IPv4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {integer} integer - a number to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromInteger(integer: number): Address4 {
|
||||
return Address4.fromHex(integer.toString(16));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an address from in-addr.arpa form
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address
|
||||
* @returns {Adress4}
|
||||
* @example
|
||||
* var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)
|
||||
* address.correctForm(); // '192.0.2.42'
|
||||
*/
|
||||
static fromArpa(arpaFormAddress: string): Address4 {
|
||||
// remove ending ".in-addr.arpa." or just "."
|
||||
const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.$/, '');
|
||||
|
||||
const address = leader.split('.').reverse().join('.');
|
||||
|
||||
return new Address4(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an IPv4 address object to a hex string
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
toHex(): string {
|
||||
return this.parsedAddress.map((part) => common.stringToPaddedHex(part)).join(':');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an IPv4 address object to an array of bytes
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Array}
|
||||
*/
|
||||
toArray(): number[] {
|
||||
return this.parsedAddress.map((part) => parseInt(part, 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an IPv4 address object to an IPv6 address group
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
toGroup6(): string {
|
||||
const output = [];
|
||||
let i;
|
||||
|
||||
for (i = 0; i < constants.GROUPS; i += 2) {
|
||||
output.push(
|
||||
`${common.stringToPaddedHex(this.parsedAddress[i])}${common.stringToPaddedHex(
|
||||
this.parsedAddress[i + 1],
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
return output.join(':');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address as a `bigint`
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
bigInt(): bigint {
|
||||
return BigInt(`0x${this.parsedAddress.map((n) => common.stringToPaddedHex(n)).join('')}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function getting start address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
_startAddress(): bigint {
|
||||
return BigInt(`0b${this.mask() + '0'.repeat(constants.BITS - this.subnetMask)}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* The first address in the range given by this address' subnet.
|
||||
* Often referred to as the Network Address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
startAddress(): Address4 {
|
||||
return Address4.fromBigInt(this._startAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* The first host address in the range given by this address's subnet ie
|
||||
* the first address after the Network Address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
startAddressExclusive(): Address4 {
|
||||
const adjust = BigInt('1');
|
||||
return Address4.fromBigInt(this._startAddress() + adjust);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function getting end address.
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {bigint}
|
||||
*/
|
||||
_endAddress(): bigint {
|
||||
return BigInt(`0b${this.mask() + '1'.repeat(constants.BITS - this.subnetMask)}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* The last address in the range given by this address' subnet
|
||||
* Often referred to as the Broadcast
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
endAddress(): Address4 {
|
||||
return Address4.fromBigInt(this._endAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* The last host address in the range given by this address's subnet ie
|
||||
* the last address prior to the Broadcast Address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {Address4}
|
||||
*/
|
||||
endAddressExclusive(): Address4 {
|
||||
const adjust = BigInt('1');
|
||||
return Address4.fromBigInt(this._endAddress() - adjust);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a BigInt to a v4 address object
|
||||
* @memberof Address4
|
||||
* @static
|
||||
* @param {bigint} bigInt - a BigInt to convert
|
||||
* @returns {Address4}
|
||||
*/
|
||||
static fromBigInt(bigInt: bigint): Address4 {
|
||||
return Address4.fromHex(bigInt.toString(16));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first n bits of the address, defaulting to the
|
||||
* subnet mask
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
mask(mask?: number): string {
|
||||
if (mask === undefined) {
|
||||
mask = this.subnetMask;
|
||||
}
|
||||
|
||||
return this.getBitsBase2(0, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bits in the given range as a base-2 string
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {string}
|
||||
*/
|
||||
getBitsBase2(start: number, end: number): string {
|
||||
return this.binaryZeroPad().slice(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reversed ip6.arpa form of the address
|
||||
* @memberof Address4
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix
|
||||
* @instance
|
||||
* @returns {String}
|
||||
*/
|
||||
reverseForm(options?: common.ReverseFormOptions): string {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
const reversed = this.correctForm().split('.').reverse().join('.');
|
||||
|
||||
if (options.omitSuffix) {
|
||||
return reversed;
|
||||
}
|
||||
|
||||
return `${reversed}.in-addr.arpa.`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given address is in the subnet of the current address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isInSubnet = common.isInSubnet;
|
||||
|
||||
/**
|
||||
* Returns true if the given address is a multicast address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMulticast(): boolean {
|
||||
return this.isInSubnet(new Address4('224.0.0.0/4'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a zero-padded base-2 string representation of the address
|
||||
* @memberof Address4
|
||||
* @instance
|
||||
* @returns {string}
|
||||
*/
|
||||
binaryZeroPad(): string {
|
||||
return this.bigInt().toString(2).padStart(constants.BITS, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups an IPv4 address for inclusion at the end of an IPv6 address
|
||||
* @returns {String}
|
||||
*/
|
||||
groupForV6(): string {
|
||||
const segments = this.parsedAddress;
|
||||
|
||||
return this.address.replace(
|
||||
constants.RE_ADDRESS,
|
||||
`<span class="hover-group group-v4 group-6">${segments
|
||||
.slice(0, 2)
|
||||
.join('.')}</span>.<span class="hover-group group-v4 group-7">${segments
|
||||
.slice(2, 4)
|
||||
.join('.')}</span>`,
|
||||
);
|
||||
}
|
||||
}
|
||||
1212
node_modules/express-rate-limit/node_modules/ip-address/src/ipv6.ts
generated
vendored
Normal file
1212
node_modules/express-rate-limit/node_modules/ip-address/src/ipv6.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
node_modules/express-rate-limit/node_modules/ip-address/src/v4/constants.ts
generated
vendored
Normal file
7
node_modules/express-rate-limit/node_modules/ip-address/src/v4/constants.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export const BITS = 32;
|
||||
export const GROUPS = 4;
|
||||
|
||||
export const RE_ADDRESS =
|
||||
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g;
|
||||
|
||||
export const RE_SUBNET_STRING = /\/\d{1,2}$/;
|
||||
79
node_modules/express-rate-limit/node_modules/ip-address/src/v6/constants.ts
generated
vendored
Normal file
79
node_modules/express-rate-limit/node_modules/ip-address/src/v6/constants.ts
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
export const BITS = 128;
|
||||
export const GROUPS = 8;
|
||||
|
||||
/**
|
||||
* Represents IPv6 address scopes
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export const SCOPES: { [key: number]: string | undefined } = {
|
||||
0: 'Reserved',
|
||||
1: 'Interface local',
|
||||
2: 'Link local',
|
||||
4: 'Admin local',
|
||||
5: 'Site local',
|
||||
8: 'Organization local',
|
||||
14: 'Global',
|
||||
15: 'Reserved',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Represents IPv6 address types
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export const TYPES: { [key: string]: string | undefined } = {
|
||||
'ff01::1/128': 'Multicast (All nodes on this interface)',
|
||||
'ff01::2/128': 'Multicast (All routers on this interface)',
|
||||
'ff02::1/128': 'Multicast (All nodes on this link)',
|
||||
'ff02::2/128': 'Multicast (All routers on this link)',
|
||||
'ff05::2/128': 'Multicast (All routers in this site)',
|
||||
'ff02::5/128': 'Multicast (OSPFv3 AllSPF routers)',
|
||||
'ff02::6/128': 'Multicast (OSPFv3 AllDR routers)',
|
||||
'ff02::9/128': 'Multicast (RIP routers)',
|
||||
'ff02::a/128': 'Multicast (EIGRP routers)',
|
||||
'ff02::d/128': 'Multicast (PIM routers)',
|
||||
'ff02::16/128': 'Multicast (MLDv2 reports)',
|
||||
'ff01::fb/128': 'Multicast (mDNSv6)',
|
||||
'ff02::fb/128': 'Multicast (mDNSv6)',
|
||||
'ff05::fb/128': 'Multicast (mDNSv6)',
|
||||
'ff02::1:2/128': 'Multicast (All DHCP servers and relay agents on this link)',
|
||||
'ff05::1:2/128': 'Multicast (All DHCP servers and relay agents in this site)',
|
||||
'ff02::1:3/128': 'Multicast (All DHCP servers on this link)',
|
||||
'ff05::1:3/128': 'Multicast (All DHCP servers in this site)',
|
||||
'::/128': 'Unspecified',
|
||||
'::1/128': 'Loopback',
|
||||
'ff00::/8': 'Multicast',
|
||||
'fe80::/10': 'Link-local unicast',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* A regular expression that matches bad characters in an IPv6 address
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export const RE_BAD_CHARACTERS = /([^0-9a-f:/%])/gi;
|
||||
|
||||
/**
|
||||
* A regular expression that matches an incorrect IPv6 address
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export const RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi;
|
||||
|
||||
/**
|
||||
* A regular expression that matches an IPv6 subnet
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export const RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/;
|
||||
|
||||
/**
|
||||
* A regular expression that matches an IPv6 zone
|
||||
* @memberof Address6
|
||||
* @static
|
||||
*/
|
||||
export const RE_ZONE_STRING = /%.*$/;
|
||||
|
||||
export const RE_URL = /^\[{0,1}([0-9a-f:]+)\]{0,1}/;
|
||||
export const RE_URL_WITH_PORT = /\[([0-9a-f:]+)\]:([0-9]{1,5})/;
|
||||
48
node_modules/express-rate-limit/node_modules/ip-address/src/v6/helpers.ts
generated
vendored
Normal file
48
node_modules/express-rate-limit/node_modules/ip-address/src/v6/helpers.ts
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @returns {String} the string with all zeroes contained in a <span>
|
||||
*/
|
||||
export function spanAllZeroes(s: string): string {
|
||||
return s.replace(/(0+)/g, '<span class="zero">$1</span>');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String} the string with each character contained in a <span>
|
||||
*/
|
||||
export function spanAll(s: string, offset: number = 0): string {
|
||||
const letters = s.split('');
|
||||
|
||||
return letters
|
||||
.map(
|
||||
(n, i) => `<span class="digit value-${n} position-${i + offset}">${spanAllZeroes(n)}</span>`,
|
||||
)
|
||||
.join('');
|
||||
}
|
||||
|
||||
function spanLeadingZeroesSimple(group: string): string {
|
||||
return group.replace(/^(0+)/, '<span class="zero">$1</span>');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String} the string with leading zeroes contained in a <span>
|
||||
*/
|
||||
export function spanLeadingZeroes(address: string): string {
|
||||
const groups = address.split(':');
|
||||
|
||||
return groups.map((g) => spanLeadingZeroesSimple(g)).join(':');
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups an address
|
||||
* @returns {String} a grouped address
|
||||
*/
|
||||
export function simpleGroup(addressString: string, offset: number = 0): string[] {
|
||||
const groups = addressString.split(':');
|
||||
|
||||
return groups.map((g, i) => {
|
||||
if (/group-v4/.test(g)) {
|
||||
return g;
|
||||
}
|
||||
|
||||
return `<span class="hover-group group-${i + offset}">${spanLeadingZeroesSimple(g)}</span>`;
|
||||
});
|
||||
}
|
||||
94
node_modules/express-rate-limit/node_modules/ip-address/src/v6/regular-expressions.ts
generated
vendored
Normal file
94
node_modules/express-rate-limit/node_modules/ip-address/src/v6/regular-expressions.ts
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
import * as v6 from './constants';
|
||||
|
||||
export function groupPossibilities(possibilities: string[]): string {
|
||||
return `(${possibilities.join('|')})`;
|
||||
}
|
||||
|
||||
export function padGroup(group: string): string {
|
||||
if (group.length < 4) {
|
||||
return `0{0,${4 - group.length}}${group}`;
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
export const ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]';
|
||||
|
||||
export function simpleRegularExpression(groups: string[]) {
|
||||
const zeroIndexes: number[] = [];
|
||||
|
||||
groups.forEach((group, i) => {
|
||||
const groupInteger = parseInt(group, 16);
|
||||
|
||||
if (groupInteger === 0) {
|
||||
zeroIndexes.push(i);
|
||||
}
|
||||
});
|
||||
|
||||
// You can technically elide a single 0, this creates the regular expressions
|
||||
// to match that eventuality
|
||||
const possibilities = zeroIndexes.map((zeroIndex) =>
|
||||
groups
|
||||
.map((group, i) => {
|
||||
if (i === zeroIndex) {
|
||||
const elision = i === 0 || i === v6.GROUPS - 1 ? ':' : '';
|
||||
|
||||
return groupPossibilities([padGroup(group), elision]);
|
||||
}
|
||||
|
||||
return padGroup(group);
|
||||
})
|
||||
.join(':'),
|
||||
);
|
||||
|
||||
// The simplest case
|
||||
possibilities.push(groups.map(padGroup).join(':'));
|
||||
|
||||
return groupPossibilities(possibilities);
|
||||
}
|
||||
|
||||
export function possibleElisions(
|
||||
elidedGroups: number,
|
||||
moreLeft?: boolean,
|
||||
moreRight?: boolean,
|
||||
): string {
|
||||
const left = moreLeft ? '' : ':';
|
||||
const right = moreRight ? '' : ':';
|
||||
|
||||
const possibilities = [];
|
||||
|
||||
// 1. elision of everything (::)
|
||||
if (!moreLeft && !moreRight) {
|
||||
possibilities.push('::');
|
||||
}
|
||||
|
||||
// 2. complete elision of the middle
|
||||
if (moreLeft && moreRight) {
|
||||
possibilities.push('');
|
||||
}
|
||||
|
||||
if ((moreRight && !moreLeft) || (!moreRight && moreLeft)) {
|
||||
// 3. complete elision of one side
|
||||
possibilities.push(':');
|
||||
}
|
||||
|
||||
// 4. elision from the left side
|
||||
possibilities.push(`${left}(:0{1,4}){1,${elidedGroups - 1}}`);
|
||||
|
||||
// 5. elision from the right side
|
||||
possibilities.push(`(0{1,4}:){1,${elidedGroups - 1}}${right}`);
|
||||
|
||||
// 6. no elision
|
||||
possibilities.push(`(0{1,4}:){${elidedGroups - 1}}0{1,4}`);
|
||||
|
||||
// 7. elision (including sloppy elision) from the middle
|
||||
for (let groups = 1; groups < elidedGroups - 1; groups++) {
|
||||
for (let position = 1; position < elidedGroups - groups; position++) {
|
||||
possibilities.push(
|
||||
`(0{1,4}:){${position}}:(0{1,4}:){${elidedGroups - position - groups - 1}}0{1,4}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return groupPossibilities(possibilities);
|
||||
}
|
||||
112
node_modules/express-rate-limit/package.json
generated
vendored
Normal file
112
node_modules/express-rate-limit/package.json
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"name": "express-rate-limit",
|
||||
"version": "8.2.1",
|
||||
"description": "Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.",
|
||||
"author": {
|
||||
"name": "Nathan Friedly",
|
||||
"url": "http://nfriedly.com/"
|
||||
},
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/express-rate-limit/express-rate-limit",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/express-rate-limit/express-rate-limit.git"
|
||||
},
|
||||
"funding": "https://github.com/sponsors/express-rate-limit",
|
||||
"keywords": [
|
||||
"express-rate-limit",
|
||||
"express",
|
||||
"rate",
|
||||
"limit",
|
||||
"ratelimit",
|
||||
"rate-limit",
|
||||
"middleware",
|
||||
"ip",
|
||||
"auth",
|
||||
"authorization",
|
||||
"security",
|
||||
"brute",
|
||||
"force",
|
||||
"bruteforce",
|
||||
"brute-force",
|
||||
"attack"
|
||||
],
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist/",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "del-cli dist/ coverage/ *.log *.tmp *.bak *.tgz",
|
||||
"build:cjs": "esbuild --packages=external --platform=node --bundle --target=es2022 --format=cjs --outfile=dist/index.cjs --footer:js=\"module.exports = Object.assign(rateLimit, module.exports);\" source/index.ts",
|
||||
"build:esm": "esbuild --packages=external --platform=node --bundle --target=es2022 --format=esm --outfile=dist/index.mjs source/index.ts",
|
||||
"build:types": "dts-bundle-generator --out-file=dist/index.d.ts source/index.ts && cp dist/index.d.ts dist/index.d.cts && cp dist/index.d.ts dist/index.d.mts",
|
||||
"compile": "run-s clean build:*",
|
||||
"docs": "cd docs && mintlify dev",
|
||||
"lint:code": "biome check",
|
||||
"lint:docs": "prettier --check docs/ *.md",
|
||||
"lint": "run-s lint:*",
|
||||
"format:code": "biome check --write",
|
||||
"format:docs": "prettier --write docs/ *.md",
|
||||
"format": "run-s format:*",
|
||||
"test:lib": "jest",
|
||||
"test:ext": "cd test/external/ && bash run-all-tests",
|
||||
"test": "run-s lint test:lib",
|
||||
"pre-commit": "lint-staged",
|
||||
"prepare": "run-s compile && husky"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"express": ">= 4.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.3.1",
|
||||
"@express-rate-limit/prettier": "1.1.1",
|
||||
"@express-rate-limit/tsconfig": "1.0.2",
|
||||
"@jest/globals": "30.2.0",
|
||||
"@types/express": "5.0.4",
|
||||
"@types/jest": "30.0.0",
|
||||
"@types/node": "24.9.1",
|
||||
"@types/supertest": "6.0.3",
|
||||
"del-cli": "6.0.0",
|
||||
"dts-bundle-generator": "8.1.2",
|
||||
"esbuild": "0.25.11",
|
||||
"express": "5.1.0",
|
||||
"husky": "9.1.7",
|
||||
"jest": "30.2.0",
|
||||
"lint-staged": "16.2.6",
|
||||
"mintlify": "4.2.179",
|
||||
"npm-run-all": "4.1.5",
|
||||
"prettier": "3.6.2",
|
||||
"ratelimit-header-parser": "0.1.0",
|
||||
"supertest": "7.1.4",
|
||||
"ts-jest": "29.4.5",
|
||||
"ts-node": "10.9.2",
|
||||
"typescript": "5.9.3"
|
||||
},
|
||||
"prettier": "@express-rate-limit/prettier",
|
||||
"lint-staged": {
|
||||
"*.{js,ts,json}": "biome check --write",
|
||||
"*.{md,yaml}": "prettier --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"ip-address": "10.0.1"
|
||||
}
|
||||
}
|
||||
151
node_modules/express-rate-limit/readme.md
generated
vendored
Normal file
151
node_modules/express-rate-limit/readme.md
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
<h1 align="center"> <code>express-rate-limit</code> </h1>
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://github.com/express-rate-limit/express-rate-limit/actions/workflows/ci.yaml)
|
||||
[](https://npmjs.org/package/express-rate-limit 'View this project on NPM')
|
||||
[](https://www.npmjs.com/package/express-rate-limit)
|
||||
[](license.md)
|
||||
|
||||
</div>
|
||||
|
||||
Basic rate-limiting middleware for [Express](http://expressjs.com/). Use to
|
||||
limit repeated requests to public APIs and/or endpoints such as password reset.
|
||||
Plays nice with
|
||||
[express-slow-down](https://www.npmjs.com/package/express-slow-down) and
|
||||
[ratelimit-header-parser](https://www.npmjs.com/package/ratelimit-header-parser).
|
||||
|
||||
## Usage
|
||||
|
||||
The [full documentation](https://express-rate-limit.mintlify.app/overview) is
|
||||
available on-line.
|
||||
|
||||
```ts
|
||||
import { rateLimit } from 'express-rate-limit'
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
limit: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes).
|
||||
standardHeaders: 'draft-8', // draft-6: `RateLimit-*` headers; draft-7 & draft-8: combined `RateLimit` header
|
||||
legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
|
||||
ipv6Subnet: 56, // Set to 60 or 64 to be less aggressive, or 52 or 48 to be more aggressive
|
||||
// store: ... , // Redis, Memcached, etc. See below.
|
||||
})
|
||||
|
||||
// Apply the rate limiting middleware to all requests.
|
||||
app.use(limiter)
|
||||
```
|
||||
|
||||
### Data Stores
|
||||
|
||||
The rate limiter comes with a built-in memory store, and supports a variety of
|
||||
[external data stores](https://express-rate-limit.mintlify.app/reference/stores).
|
||||
|
||||
### Configuration
|
||||
|
||||
All function options may be async. Click the name for additional info and
|
||||
default values.
|
||||
|
||||
| Option | Type | Remarks |
|
||||
| -------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| [`windowMs`] | `number` | How long to remember requests for, in milliseconds. |
|
||||
| [`limit`] | `number` \| `function` | How many requests to allow. |
|
||||
| [`message`] | `string` \| `json` \| `function` | Response to return after limit is reached. |
|
||||
| [`statusCode`] | `number` | HTTP status code after limit is reached (default is 429). |
|
||||
| [`handler`] | `function` | Function to run after limit is reached (overrides `message` and `statusCode` settings, if set). |
|
||||
| [`legacyHeaders`] | `boolean` | Enable the `X-Rate-Limit` header. |
|
||||
| [`standardHeaders`] | `'draft-6'` \| `'draft-7'` \| `'draft-8'` | Enable the `Ratelimit` header. |
|
||||
| [`identifier`] | `string` \| `function` | Name associated with the quota policy enforced by this rate limiter. |
|
||||
| [`store`] | `Store` | Use a custom store to share hit counts across multiple nodes. |
|
||||
| [`passOnStoreError`] | `boolean` | Allow (`true`) or block (`false`, default) traffic if the store becomes unavailable. |
|
||||
| [`keyGenerator`] | `function` | Identify users (defaults to IP address). |
|
||||
| [`ipv6Subnet`] | `number` (32-64) \| `function` \| `false` | How many bits of IPv6 addresses to use in default `keyGenerator` |
|
||||
| [`requestPropertyName`] | `string` | Add rate limit info to the `req` object. |
|
||||
| [`skip`] | `function` | Return `true` to bypass the limiter for the given request. |
|
||||
| [`skipSuccessfulRequests`] | `boolean` | Uncount 1xx/2xx/3xx responses. |
|
||||
| [`skipFailedRequests`] | `boolean` | Uncount 4xx/5xx responses. |
|
||||
| [`requestWasSuccessful`] | `function` | Used by `skipSuccessfulRequests` and `skipFailedRequests`. |
|
||||
| [`validate`] | `boolean` \| `object` | Enable or disable built-in validation checks. |
|
||||
|
||||
## Thank You
|
||||
|
||||
Sponsored by [Zuplo](https://zuplo.link/express-rate-limit) a fully-managed API
|
||||
Gateway for developers. Add
|
||||
[dynamic rate-limiting](https://zuplo.link/dynamic-rate-limiting),
|
||||
authentication and more to any API in minutes. Learn more at
|
||||
[zuplo.com](https://zuplo.link/express-rate-limit)
|
||||
|
||||
<p align="center">
|
||||
<a href="https://zuplo.link/express-rate-limit">
|
||||
<picture width="322">
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/express-rate-limit/express-rate-limit/assets/114976/cd2f6fa7-eae1-4fbb-be7d-b17df4c6f383">
|
||||
<img alt="zuplo-logo" src="https://github.com/express-rate-limit/express-rate-limit/assets/114976/66fd75fa-b39e-4a8c-8d7a-52369bf244dc" width="322">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
Thanks to Mintlify for hosting the documentation at
|
||||
[express-rate-limit.mintlify.app](https://express-rate-limit.mintlify.app)
|
||||
|
||||
<p align="center">
|
||||
<a href="https://mintlify.com/?utm_campaign=devmark&utm_medium=readme&utm_source=express-rate-limit">
|
||||
<img height="75" src="https://devmark-public-assets.s3.us-west-2.amazonaws.com/sponsorships/mintlify.svg" alt="Create your docs today">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
Finally, thank you to everyone who's contributed to this project in any way! 🫶
|
||||
|
||||
## Issues and Contributing
|
||||
|
||||
If you encounter a bug or want to see something added/changed, please go ahead
|
||||
and
|
||||
[open an issue](https://github.com/express-rate-limit/express-rate-limit/issues/new)!
|
||||
If you need help with something, feel free to
|
||||
[start a discussion](https://github.com/express-rate-limit/express-rate-limit/discussions/new)!
|
||||
|
||||
If you wish to contribute to the library, thanks! First, please read
|
||||
[the contributing guide](https://express-rate-limit.mintlify.app/docs/guides/contributing.mdx).
|
||||
Then you can pick up any issue and fix/implement it!
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Nathan Friedly](http://nfriedly.com/),
|
||||
[Vedant K](https://github.com/gamemaker1)
|
||||
|
||||
[`windowMs`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#windowms
|
||||
[`limit`]: https://express-rate-limit.mintlify.app/reference/configuration#limit
|
||||
[`message`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#message
|
||||
[`statusCode`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#statuscode
|
||||
[`handler`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#handler
|
||||
[`legacyHeaders`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#legacyheaders
|
||||
[`standardHeaders`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#standardheaders
|
||||
[`identifier`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#identifier
|
||||
[`store`]: https://express-rate-limit.mintlify.app/reference/configuration#store
|
||||
[`passOnStoreError`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#passonstoreerror
|
||||
[`keyGenerator`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#keygenerator
|
||||
[`ipv6Subnet`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#ipv6subnet
|
||||
[`requestPropertyName`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#requestpropertyname
|
||||
[`skip`]: https://express-rate-limit.mintlify.app/reference/configuration#skip
|
||||
[`skipSuccessfulRequests`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#skipsuccessfulrequests
|
||||
[`skipFailedRequests`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#skipfailedrequests
|
||||
[`requestWasSuccessful`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#requestwassuccessful
|
||||
[`validate`]:
|
||||
https://express-rate-limit.mintlify.app/reference/configuration#validate
|
||||
8
node_modules/express-rate-limit/tsconfig.json
generated
vendored
Normal file
8
node_modules/express-rate-limit/tsconfig.json
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"include": ["source/"],
|
||||
"exclude": ["node_modules/"],
|
||||
"extends": "@express-rate-limit/tsconfig",
|
||||
"compilerOptions": {
|
||||
"target": "ES2020"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user