@extend-therapy/elysia-db-ratelimiter 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Context } from
|
|
2
|
-
import type { Logger } from
|
|
3
|
-
import type { DBRLOptions } from
|
|
1
|
+
import type { Context } from "elysia";
|
|
2
|
+
import type { Logger } from "pino";
|
|
3
|
+
import type { DBRLOptions } from "./types";
|
|
4
4
|
export declare const dbRateLimitHandler: (options: DBRLOptions) => ({ cookie, log, path, request, set, query, ..._rest }: Context & {
|
|
5
5
|
log: Logger;
|
|
6
|
-
}) => Promise<string |
|
|
6
|
+
}) => Promise<string | undefined>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { InternalServerError } from
|
|
2
|
-
import { getIP } from
|
|
1
|
+
import { InternalServerError } from "elysia";
|
|
2
|
+
import { getIP } from "elysia-ip";
|
|
3
3
|
export const dbRateLimitHandler = (options) => {
|
|
4
4
|
return async ({ cookie, log, path, request, set, query, ..._rest }) => {
|
|
5
5
|
let currentLimit = options.limit;
|
|
@@ -7,13 +7,13 @@ export const dbRateLimitHandler = (options) => {
|
|
|
7
7
|
let currentPattern = options.pattern;
|
|
8
8
|
let shouldLimit = true;
|
|
9
9
|
if (options.routes) {
|
|
10
|
-
const match = options.routes.find(r => typeof r ===
|
|
10
|
+
const match = options.routes.find((r) => typeof r === "string" ? r === path : r.path === path);
|
|
11
11
|
if (!match) {
|
|
12
12
|
if (options.whitelistMode) {
|
|
13
13
|
shouldLimit = false;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
else if (typeof match !==
|
|
16
|
+
else if (typeof match !== "string") {
|
|
17
17
|
currentLimit = match.limit;
|
|
18
18
|
currentWindow = match.window;
|
|
19
19
|
if (match.pattern)
|
|
@@ -25,7 +25,7 @@ export const dbRateLimitHandler = (options) => {
|
|
|
25
25
|
}
|
|
26
26
|
// pathConfigs takes final precedence if present
|
|
27
27
|
if (options.pathConfigs) {
|
|
28
|
-
const pathConfig = options.pathConfigs.find(c => c.path === path);
|
|
28
|
+
const pathConfig = options.pathConfigs.find((c) => c.path === path);
|
|
29
29
|
if (pathConfig) {
|
|
30
30
|
currentLimit = pathConfig.limit;
|
|
31
31
|
currentWindow = pathConfig.window;
|
|
@@ -38,15 +38,14 @@ export const dbRateLimitHandler = (options) => {
|
|
|
38
38
|
const ip = getIP(request.headers);
|
|
39
39
|
if (!ip) {
|
|
40
40
|
// In test environment, use a default IP address to avoid log noise
|
|
41
|
-
const isTest = process.env.NODE_ENV ===
|
|
41
|
+
const isTest = process.env.NODE_ENV === "test" || process.env.isTest === "true";
|
|
42
42
|
if (isTest) {
|
|
43
|
-
baseId =
|
|
44
|
-
log.debug(
|
|
43
|
+
baseId = "127.0.0.1";
|
|
44
|
+
log.debug("Using default test IP for rate limiting");
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
|
-
const errorMsg =
|
|
47
|
+
const errorMsg = "Could not get IP address for rate limiting";
|
|
48
48
|
log.error(errorMsg);
|
|
49
|
-
return true;
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
else {
|
|
@@ -59,24 +58,24 @@ export const dbRateLimitHandler = (options) => {
|
|
|
59
58
|
let finalRateLimitId;
|
|
60
59
|
const safeBaseId = baseId;
|
|
61
60
|
switch (currentPattern) {
|
|
62
|
-
case
|
|
61
|
+
case "IP":
|
|
63
62
|
finalRateLimitId = safeBaseId;
|
|
64
63
|
break;
|
|
65
|
-
case
|
|
64
|
+
case "Route":
|
|
66
65
|
finalRateLimitId = path;
|
|
67
66
|
break;
|
|
68
|
-
case
|
|
67
|
+
case "IPRouteNoParams":
|
|
69
68
|
finalRateLimitId = `${safeBaseId}:${path}`;
|
|
70
69
|
break;
|
|
71
|
-
case
|
|
70
|
+
case "IPFullRoute":
|
|
72
71
|
default: {
|
|
73
72
|
const queryStr = new URLSearchParams(query).toString();
|
|
74
|
-
finalRateLimitId = `${safeBaseId}:${path}${queryStr ?
|
|
73
|
+
finalRateLimitId = `${safeBaseId}:${path}${queryStr ? "?" + queryStr : ""}`;
|
|
75
74
|
break;
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
77
|
if (!options.rateLimitStore) {
|
|
79
|
-
const errorMsg =
|
|
78
|
+
const errorMsg = "No rate limit store provided";
|
|
80
79
|
log.error(errorMsg);
|
|
81
80
|
if (options.failOpen === false) {
|
|
82
81
|
throw new InternalServerError(errorMsg);
|
|
@@ -90,7 +89,7 @@ export const dbRateLimitHandler = (options) => {
|
|
|
90
89
|
catch (e) {
|
|
91
90
|
log.error(`Rate limit store get error: ${e}`);
|
|
92
91
|
if (options.failOpen === false) {
|
|
93
|
-
throw new InternalServerError(
|
|
92
|
+
throw new InternalServerError("Rate limit service unavailable");
|
|
94
93
|
}
|
|
95
94
|
return;
|
|
96
95
|
}
|
|
@@ -100,18 +99,18 @@ export const dbRateLimitHandler = (options) => {
|
|
|
100
99
|
if (count >= currentLimit) {
|
|
101
100
|
log.warn(`Rate limit exceeded for ${finalRateLimitId}`);
|
|
102
101
|
set.status = options.status || 429;
|
|
103
|
-
return options.message ||
|
|
102
|
+
return options.message || "Too many requests";
|
|
104
103
|
}
|
|
105
104
|
try {
|
|
106
105
|
await options.rateLimitStore.set(finalRateLimitId, {
|
|
107
106
|
count: count + 1,
|
|
108
|
-
resetTime: resetTime
|
|
107
|
+
resetTime: resetTime,
|
|
109
108
|
}, Math.ceil((resetTime - now) / 1000));
|
|
110
109
|
}
|
|
111
110
|
catch (e) {
|
|
112
111
|
log.error(`Rate limit store set error: ${e}`);
|
|
113
112
|
if (options.failOpen === false) {
|
|
114
|
-
throw new InternalServerError(
|
|
113
|
+
throw new InternalServerError("Rate limit service unavailable");
|
|
115
114
|
}
|
|
116
115
|
return;
|
|
117
116
|
}
|
|
@@ -15,7 +15,7 @@ export declare const dbRateLimiter: (options?: Partial<DBRLOptions>, ignore?: bo
|
|
|
15
15
|
macroFn: {};
|
|
16
16
|
parser: {};
|
|
17
17
|
response: {
|
|
18
|
-
200: string
|
|
18
|
+
200: string;
|
|
19
19
|
};
|
|
20
20
|
}, {}, {
|
|
21
21
|
derive: {};
|
|
@@ -50,7 +50,7 @@ export declare const dbRateLimiter: (options?: Partial<DBRLOptions>, ignore?: bo
|
|
|
50
50
|
schema: {};
|
|
51
51
|
standaloneSchema: {};
|
|
52
52
|
response: {
|
|
53
|
-
200: string
|
|
53
|
+
200: string;
|
|
54
54
|
};
|
|
55
55
|
}, {
|
|
56
56
|
derive: {};
|