fix: rate limiting breaking smoke tests and backup routes 404 when disabled

- Exempt /healthz and /health from rate limiter
- Increase rate limit from 500 to 2000 req/min
- Register backup routes even when disabled (status shows disabled)
- Guard restore endpoints with 503 when backup not configured
- Add retry with backoff on 429 in audit smoke tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michal
2026-03-08 13:32:17 +00:00
parent af9f7458fc
commit 225e0dddfc
5 changed files with 41 additions and 20 deletions

View File

@@ -465,11 +465,13 @@ async function main(): Promise<void> {
}
};
gitBackup.setCallbacks(importResource, deleteResource);
registerGitBackupRoutes(app, gitBackup);
// Init async — don't block server startup
gitBackup.init().catch((err) => app.log.error({ err }, 'Git backup init failed'));
}
// Always register backup routes (status shows disabled when no repo configured)
registerGitBackupRoutes(app, gitBackup);
// ── RBAC list filtering hook ──
// Filters array responses to only include resources the user is allowed to see.
app.addHook('preSerialization', async (request, _reply, payload) => {

View File

@@ -20,5 +20,10 @@ export async function registerSecurityPlugins(
await app.register(rateLimit, {
max: config.rateLimitMax,
timeWindow: config.rateLimitWindowMs,
allowList: (req) => {
// Exempt health probes and internal monitoring from rate limiting
const url = req.url;
return url === '/healthz' || url === '/health';
},
});
}

View File

@@ -25,6 +25,9 @@ export function registerGitBackupRoutes(app: FastifyInstance, gitBackup: GitBack
// POST /api/v1/backup/restore/preview — preview restore
app.post<{ Body: { commit: string } }>('/api/v1/backup/restore/preview', async (request, reply) => {
if (!gitBackup.enabled) {
return reply.code(503).send({ error: 'Backup is not configured' });
}
const { commit } = request.body ?? {};
if (!commit) {
return reply.code(400).send({ error: 'commit is required' });
@@ -39,6 +42,9 @@ export function registerGitBackupRoutes(app: FastifyInstance, gitBackup: GitBack
// POST /api/v1/backup/restore — restore to a commit
app.post<{ Body: { commit: string } }>('/api/v1/backup/restore', async (request, reply) => {
if (!gitBackup.enabled) {
return reply.code(503).send({ error: 'Backup is not configured' });
}
const { commit } = request.body ?? {};
if (!commit) {
return reply.code(400).send({ error: 'commit is required' });