Files
zeekay d0736c16fd feat: zoo.computer — decentralized AI supercomputing landing page
Forked from hanzo.computer, fully rebranded for Zoo Labs Foundation.
Vite + React + Tailwind. Deploys to GitHub Pages.
2026-03-31 13:25:51 -07:00

61 lines
2.2 KiB
TypeScript

import { checkRateLimit, addRateLimitHeaders } from '../src/lib/rateLimit';
export const config = {
matcher: '/api/:path*',
};
export default async function middleware(req: Request): Promise<Response> {
// Skip rate limiting if disabled
if (process.env.RATE_LIMIT_ENABLED !== 'true') {
return new Response(null, { status: 200 });
}
try {
// Check rate limit
const rateLimitResult = await checkRateLimit(req);
// If rate limit exceeded, return 429
if (!rateLimitResult.success) {
return new Response(
JSON.stringify({
error: 'Too Many Requests',
message: `Rate limit exceeded. Please try again in ${Math.ceil((rateLimitResult.reset - Date.now()) / 1000)} seconds.`,
limit: rateLimitResult.limit,
remaining: rateLimitResult.remaining,
reset: new Date(rateLimitResult.reset).toISOString(),
retryAfter: Math.ceil((rateLimitResult.reset - Date.now()) / 1000),
}),
{
status: 429,
headers: {
'Content-Type': 'application/json',
'X-RateLimit-Limit': rateLimitResult.limit.toString(),
'X-RateLimit-Remaining': rateLimitResult.remaining.toString(),
'X-RateLimit-Reset': rateLimitResult.reset.toString(),
'X-RateLimit-Reset-After': Math.ceil((rateLimitResult.reset - Date.now()) / 1000).toString(),
'Retry-After': Math.ceil((rateLimitResult.reset - Date.now()) / 1000).toString(),
},
}
);
}
// Log rate limit usage for monitoring
if (rateLimitResult.remaining < 10) {
console.warn(`Rate limit warning: ${rateLimitResult.identifier} has ${rateLimitResult.remaining} requests remaining`);
}
// Continue with the request and add rate limit headers to the response
return new Response(null, {
status: 200,
headers: {
'X-RateLimit-Limit': rateLimitResult.limit.toString(),
'X-RateLimit-Remaining': rateLimitResult.remaining.toString(),
'X-RateLimit-Reset': rateLimitResult.reset.toString(),
},
});
} catch (error) {
console.error('Middleware error:', error);
// Fail open - allow request if middleware fails
return new Response(null, { status: 200 });
}
}