44 lines
938 B
JavaScript
44 lines
938 B
JavaScript
/**
|
|
* Simple per-peer sliding window rate limiter.
|
|
*/
|
|
|
|
const WINDOW_MS = 60_000
|
|
const DEFAULT_RPM = Number(process.env.PEARDATA_RATE_LIMIT_RPM) || 120
|
|
|
|
/** @type {Map<string, number[]>} */
|
|
const hits = new Map()
|
|
|
|
const STREAM_METHODS = new Set([
|
|
'ping',
|
|
'queryData',
|
|
'subscribeMetrics',
|
|
'unsubscribeMetrics',
|
|
'getAllMetrics',
|
|
])
|
|
|
|
/**
|
|
* @param {{ id: string }} session
|
|
* @param {string} method
|
|
*/
|
|
export function isAllowed(session, method) {
|
|
if (STREAM_METHODS.has(method)) return true
|
|
const id = session?.id || 'anon'
|
|
const now = Date.now()
|
|
let list = hits.get(id)
|
|
if (!list) {
|
|
list = []
|
|
hits.set(id, list)
|
|
}
|
|
const cutoff = now - WINDOW_MS
|
|
while (list.length && list[0] < cutoff) list.shift()
|
|
if (list.length >= DEFAULT_RPM) return false
|
|
list.push(now)
|
|
return true
|
|
}
|
|
|
|
export function isStreamMethod(method) {
|
|
return STREAM_METHODS.has(method)
|
|
}
|
|
|
|
export default { isAllowed, isStreamMethod }
|