mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
- Add wildcard CORS headers in vercel.json for /api/* routes so Vercel infra 500s (which bypass edge function code) still include CORS headers - Bump rate limit from 300 to 600 req/60s in both rate-limit files to accommodate dashboard init burst (~30-40 parallel requests) - Add smartraveller.gov.au (bare + www) to Railway relay RSS allowlist - Add redirect hostname validation in fetchWithRedirects to prevent SSRF via open redirects on allowed domains
59 lines
1.4 KiB
JavaScript
59 lines
1.4 KiB
JavaScript
import { Ratelimit } from '@upstash/ratelimit';
|
|
import { Redis } from '@upstash/redis';
|
|
|
|
let ratelimit = null;
|
|
|
|
function getRatelimit() {
|
|
if (ratelimit) return ratelimit;
|
|
|
|
const url = process.env.UPSTASH_REDIS_REST_URL;
|
|
const token = process.env.UPSTASH_REDIS_REST_TOKEN;
|
|
if (!url || !token) return null;
|
|
|
|
ratelimit = new Ratelimit({
|
|
redis: new Redis({ url, token }),
|
|
limiter: Ratelimit.slidingWindow(600, '60 s'),
|
|
prefix: 'rl',
|
|
analytics: false,
|
|
});
|
|
|
|
return ratelimit;
|
|
}
|
|
|
|
function getClientIp(request) {
|
|
return (
|
|
request.headers.get('x-real-ip') ||
|
|
request.headers.get('cf-connecting-ip') ||
|
|
request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||
|
|
'0.0.0.0'
|
|
);
|
|
}
|
|
|
|
export async function checkRateLimit(request, corsHeaders) {
|
|
const rl = getRatelimit();
|
|
if (!rl) return null;
|
|
|
|
const ip = getClientIp(request);
|
|
try {
|
|
const { success, limit, reset } = await rl.limit(ip);
|
|
|
|
if (!success) {
|
|
return new Response(JSON.stringify({ error: 'Too many requests' }), {
|
|
status: 429,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-RateLimit-Limit': String(limit),
|
|
'X-RateLimit-Remaining': '0',
|
|
'X-RateLimit-Reset': String(reset),
|
|
'Retry-After': String(Math.ceil((reset - Date.now()) / 1000)),
|
|
...corsHeaders,
|
|
},
|
|
});
|
|
}
|
|
|
|
return null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|