MovixOpenSource/API/Mainapi/utils/redisRateLimitStore.js
Movix 1401dc20f3 tird release
mon compte github a été détecté comme du spam je crois
2026-04-28 17:55:00 +02:00

110 lines
2.3 KiB
JavaScript

const { redis } = require('../config/redis');
function buildResetTime(ttlMs, windowMs) {
const safeTtlMs = Number.isFinite(ttlMs) && ttlMs > 0 ? ttlMs : windowMs;
return new Date(Date.now() + safeTtlMs);
}
class RedisRateLimitStore {
constructor(options = {}) {
this.windowMs = Number(options.windowMs) || 60_000;
this.prefix = String(options.prefix || 'rate-limit:');
this.localKeys = false;
}
init(options) {
if (options?.windowMs) {
this.windowMs = Number(options.windowMs);
}
}
getKey(key) {
return `${this.prefix}${key}`;
}
async get(key) {
const redisKey = this.getKey(key);
try {
const [rawHits, rawTtlMs] = await redis
.multi()
.get(redisKey)
.pttl(redisKey)
.exec();
const totalHits = Number(rawHits?.[1] || 0);
const ttlMs = Number(rawTtlMs?.[1] || 0);
if (!Number.isFinite(totalHits) || totalHits <= 0) {
return undefined;
}
return {
totalHits,
resetTime: buildResetTime(ttlMs, this.windowMs)
};
} catch {
return undefined;
}
}
async increment(key) {
const redisKey = this.getKey(key);
try {
const [rawHits, rawTtlMs] = await redis
.multi()
.incr(redisKey)
.pttl(redisKey)
.exec();
const totalHits = Number(rawHits?.[1] || 1);
let ttlMs = Number(rawTtlMs?.[1] || 0);
if (!Number.isFinite(ttlMs) || ttlMs <= 0 || totalHits === 1) {
ttlMs = this.windowMs;
await redis.pexpire(redisKey, this.windowMs);
}
return {
totalHits,
resetTime: buildResetTime(ttlMs, this.windowMs)
};
} catch {
return {
totalHits: 1,
resetTime: buildResetTime(this.windowMs, this.windowMs)
};
}
}
async decrement(key) {
const redisKey = this.getKey(key);
try {
const remaining = Number(await redis.decr(redisKey));
if (Number.isFinite(remaining) && remaining <= 0) {
await redis.del(redisKey);
}
} catch {
// ignore
}
}
async resetKey(key) {
try {
await redis.del(this.getKey(key));
} catch {
// ignore
}
}
}
function createRedisRateLimitStore(options) {
return new RedisRateLimitStore(options);
}
module.exports = {
RedisRateLimitStore,
createRedisRateLimitStore
};