Files
documenso/apps/remix/server/router.ts
David Nguyen dc2042a1ee fix: rate limit api endpoints (#1863)
Rate limit API endpoint
2025-06-27 18:50:22 +10:00

71 lines
1.9 KiB
TypeScript

import { Hono } from 'hono';
import { rateLimiter } from 'hono-rate-limiter';
import { contextStorage } from 'hono/context-storage';
import { tsRestHonoApp } from '@documenso/api/hono';
import { auth } from '@documenso/auth/server';
import { API_V2_BETA_URL } from '@documenso/lib/constants/app';
import { jobsClient } from '@documenso/lib/jobs/client';
import { openApiDocument } from '@documenso/trpc/server/open-api';
import { filesRoute } from './api/files';
import { type AppContext, appContext } from './context';
import { appMiddleware } from './middleware';
import { openApiTrpcServerHandler } from './trpc/hono-trpc-open-api';
import { reactRouterTrpcServer } from './trpc/hono-trpc-remix';
export interface HonoEnv {
Variables: {
context: AppContext;
};
}
const app = new Hono<HonoEnv>();
/**
* Rate limiting for v1 and v2 API routes only.
* - 100 requests per minute per IP address
*/
const rateLimitMiddleware = rateLimiter({
windowMs: 60 * 1000, // 1 minute
limit: 100, // 100 requests per window
keyGenerator: (c) => {
return c.req.header('x-forwarded-for') || c.req.header('x-real-ip') || 'unknown';
},
message: {
error: 'Too many requests, please try again later.',
},
});
/**
* Attach session and context to requests.
*/
app.use(contextStorage());
app.use(appContext);
/**
* RR7 app middleware.
*/
app.use('*', appMiddleware);
// Apply rate limit to /api/v1/*
app.use('/api/v1/*', rateLimitMiddleware);
app.use('/api/v2/*', rateLimitMiddleware);
// Auth server.
app.route('/api/auth', auth);
// Files route.
app.route('/api/files', filesRoute);
// API servers.
app.route('/api/v1', tsRestHonoApp);
app.use('/api/jobs/*', jobsClient.getApiHandler());
app.use('/api/trpc/*', reactRouterTrpcServer);
// Unstable API server routes. Order matters for these two.
app.get(`${API_V2_BETA_URL}/openapi.json`, (c) => c.json(openApiDocument));
app.use(`${API_V2_BETA_URL}/*`, async (c) => openApiTrpcServerHandler(c));
export default app;