ayiin 2.0.43 → 2.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/methods/limiter.js +17 -17
- package/dist/types.d.ts +0 -2
- package/package.json +1 -1
package/dist/methods/limiter.js
CHANGED
|
@@ -50,8 +50,9 @@ class Limiter extends tools_1.default {
|
|
|
50
50
|
const store = options.store ?? new MemoryStore();
|
|
51
51
|
if (options.refreshOnStart) {
|
|
52
52
|
if (typeof store.refresh === "function") {
|
|
53
|
-
store.refresh()
|
|
54
|
-
|
|
53
|
+
Promise.resolve(store.refresh()).then(() => {
|
|
54
|
+
console.log(`[RateLimiter] ${store.constructor.name} refreshed on start.`);
|
|
55
|
+
});
|
|
55
56
|
}
|
|
56
57
|
else {
|
|
57
58
|
console.warn(`[RateLimiter] ${store.constructor.name} does not implement refresh() method.`);
|
|
@@ -62,8 +63,11 @@ class Limiter extends tools_1.default {
|
|
|
62
63
|
const userId = options.identifyUser
|
|
63
64
|
? options.identifyUser(req, res)
|
|
64
65
|
: (req.ip ?? "unknown");
|
|
66
|
+
// key storage
|
|
65
67
|
const floodKey = `${options.keyPrefix}:flood:${userId}`;
|
|
66
68
|
const levelKey = `${options.keyPrefix}:level:${userId}`;
|
|
69
|
+
const rateKey = `${options.keyPrefix}:rate:${userId}`;
|
|
70
|
+
// cek jika user terblock atau tidak
|
|
67
71
|
const blockedUntilStr = await store.get(floodKey);
|
|
68
72
|
if (blockedUntilStr) {
|
|
69
73
|
const blockedUntil = new Date(blockedUntilStr).getTime();
|
|
@@ -74,41 +78,39 @@ class Limiter extends tools_1.default {
|
|
|
74
78
|
api: options.keyPrefix,
|
|
75
79
|
remainMs: remainingMs,
|
|
76
80
|
remain: this.formatRemainingTime(remainingMs),
|
|
77
|
-
limit: Array.isArray(options.limit)
|
|
78
|
-
? options.limit[0]
|
|
79
|
-
: options.limit,
|
|
80
81
|
})
|
|
81
82
|
: (options.messageFormat ??
|
|
82
83
|
`[FloodWait] - Silakan coba lagi dalam ${this.formatRemainingTime(remainingMs)}.`);
|
|
83
84
|
return res.status(429).json({ success: false, error: msg });
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
|
-
const rateKey = `${options.keyPrefix}:rate:${userId}`;
|
|
87
|
-
const hits = await store.incr(rateKey);
|
|
88
87
|
const windowMs = this.toMilliseconds(options.windowMs);
|
|
89
88
|
const refreshAtMs = this.toMilliseconds(options.refreshAt ?? { hours: 24 });
|
|
90
|
-
if (hits === 1) {
|
|
91
|
-
await store.expire(rateKey, windowMs);
|
|
92
|
-
}
|
|
93
89
|
// ambil level sekarang
|
|
94
90
|
let level = parseInt((await store.get(levelKey)) ?? "0", 10);
|
|
95
91
|
// tentukan limit sesuai level
|
|
96
92
|
let currentLimit;
|
|
97
93
|
if (Array.isArray(options.limit)) {
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
currentLimit = limit;
|
|
94
|
+
// gunakan level sebagai offset - 1
|
|
95
|
+
const limitIdx = Math.min(level - 1, options.limit.length - 1);
|
|
96
|
+
currentLimit = options.limit[limitIdx];
|
|
101
97
|
}
|
|
102
98
|
else {
|
|
103
99
|
currentLimit = Number(options.limit);
|
|
104
100
|
}
|
|
101
|
+
// hitung permintaan sekarang
|
|
102
|
+
const hits = await store.incr(rateKey);
|
|
103
|
+
if (hits === 1) {
|
|
104
|
+
await store.expire(rateKey, windowMs);
|
|
105
|
+
}
|
|
106
|
+
// cek level jika permintaan melebihi limit
|
|
105
107
|
if (hits > currentLimit) {
|
|
106
108
|
level += 1;
|
|
107
109
|
await store.set(levelKey, level.toString(), refreshAtMs);
|
|
108
110
|
let floodwaitMs;
|
|
109
111
|
if (Array.isArray(options.floodwaitMs)) {
|
|
110
|
-
const
|
|
111
|
-
const floodwait = options.floodwaitMs[
|
|
112
|
+
const floodIdx = Math.min(level - 1, options.floodwaitMs.length - 1);
|
|
113
|
+
const floodwait = options.floodwaitMs[floodIdx];
|
|
112
114
|
floodwaitMs = this.toMilliseconds(floodwait ?? options.floodwaitMs[0]);
|
|
113
115
|
}
|
|
114
116
|
else {
|
|
@@ -121,8 +123,6 @@ class Limiter extends tools_1.default {
|
|
|
121
123
|
api: options.keyPrefix,
|
|
122
124
|
remainMs: floodwaitMs,
|
|
123
125
|
remain: this.formatRemainingTime(floodwaitMs),
|
|
124
|
-
level,
|
|
125
|
-
limit: currentLimit,
|
|
126
126
|
})
|
|
127
127
|
: (options.messageFormat ??
|
|
128
128
|
`[FloodWait] - Terlalu banyak permintaan. Silakan coba lagi dalam ${this.formatRemainingTime(floodwaitMs)}.`);
|
package/dist/types.d.ts
CHANGED