feat: added query size validation for audit log

This commit is contained in:
=
2025-07-02 20:16:10 +05:30
parent 5709afe0d3
commit b52ec37f76
2 changed files with 97 additions and 52 deletions

View File

@@ -111,15 +111,38 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
params: z.object({ params: z.object({
workspaceId: z.string().trim().describe(AUDIT_LOGS.EXPORT.projectId) workspaceId: z.string().trim().describe(AUDIT_LOGS.EXPORT.projectId)
}), }),
querystring: z.object({ querystring: z
eventType: z.nativeEnum(EventType).optional().describe(AUDIT_LOGS.EXPORT.eventType), .object({
userAgentType: z.nativeEnum(UserAgentType).optional().describe(AUDIT_LOGS.EXPORT.userAgentType), eventType: z.nativeEnum(EventType).optional().describe(AUDIT_LOGS.EXPORT.eventType),
startDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.startDate), userAgentType: z.nativeEnum(UserAgentType).optional().describe(AUDIT_LOGS.EXPORT.userAgentType),
endDate: z.string().datetime().default(new Date().toISOString()).describe(AUDIT_LOGS.EXPORT.endDate), startDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.startDate),
offset: z.coerce.number().default(0).describe(AUDIT_LOGS.EXPORT.offset), endDate: z.string().datetime().default(new Date().toISOString()).describe(AUDIT_LOGS.EXPORT.endDate),
limit: z.coerce.number().default(20).describe(AUDIT_LOGS.EXPORT.limit), offset: z.coerce.number().default(0).describe(AUDIT_LOGS.EXPORT.offset),
actor: z.string().optional().describe(AUDIT_LOGS.EXPORT.actor) limit: z.coerce.number().max(1000).default(20).describe(AUDIT_LOGS.EXPORT.limit),
}), actor: z.string().optional().describe(AUDIT_LOGS.EXPORT.actor)
})
.superRefine((el, ctx) => {
if (el.endDate && el.startDate) {
const startDate = new Date(el.startDate);
const endDate = new Date(el.endDate);
const maxAllowedDate = new Date(startDate);
maxAllowedDate.setMonth(maxAllowedDate.getMonth() + 3);
if (endDate < startDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["endDate"],
message: "End date cannot be before start date"
});
}
if (endDate > maxAllowedDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["endDate"],
message: "Dates must be within 3 months"
});
}
}
}),
response: { response: {
200: z.object({ 200: z.object({
auditLogs: AuditLogsSchema.omit({ auditLogs: AuditLogsSchema.omit({

View File

@@ -113,51 +113,73 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
hide: false, hide: false,
tags: [ApiDocsTags.AuditLogs], tags: [ApiDocsTags.AuditLogs],
description: "Get all audit logs for an organization", description: "Get all audit logs for an organization",
querystring: z.object({ querystring: z
projectId: z.string().optional().describe(AUDIT_LOGS.EXPORT.projectId), .object({
environment: z.string().optional().describe(AUDIT_LOGS.EXPORT.environment), projectId: z.string().optional().describe(AUDIT_LOGS.EXPORT.projectId),
actorType: z.nativeEnum(ActorType).optional(), environment: z.string().optional().describe(AUDIT_LOGS.EXPORT.environment),
secretPath: z actorType: z.nativeEnum(ActorType).optional(),
.string() secretPath: z
.optional() .string()
.transform((val) => (!val ? val : removeTrailingSlash(val))) .optional()
.describe(AUDIT_LOGS.EXPORT.secretPath), .transform((val) => (!val ? val : removeTrailingSlash(val)))
secretKey: z.string().optional().describe(AUDIT_LOGS.EXPORT.secretKey), .describe(AUDIT_LOGS.EXPORT.secretPath),
secretKey: z.string().optional().describe(AUDIT_LOGS.EXPORT.secretKey),
// eventType is split with , for multiple values, we need to transform it to array
eventType: z
.string()
.optional()
.transform((val) => (val ? val.split(",") : undefined)),
userAgentType: z.nativeEnum(UserAgentType).optional().describe(AUDIT_LOGS.EXPORT.userAgentType),
eventMetadata: z
.string()
.optional()
.transform((val) => {
if (!val) {
return undefined;
}
// eventType is split with , for multiple values, we need to transform it to array const pairs = val.split(",");
eventType: z
.string() return pairs.reduce(
.optional() (acc, pair) => {
.transform((val) => (val ? val.split(",") : undefined)), const [key, value] = pair.split("=");
userAgentType: z.nativeEnum(UserAgentType).optional().describe(AUDIT_LOGS.EXPORT.userAgentType), if (key && value) {
eventMetadata: z acc[key] = value;
.string() }
.optional() return acc;
.transform((val) => { },
if (!val) { {} as Record<string, string>
return undefined; );
})
.describe(AUDIT_LOGS.EXPORT.eventMetadata),
startDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.startDate),
endDate: z.string().datetime().default(new Date().toISOString()).describe(AUDIT_LOGS.EXPORT.endDate),
offset: z.coerce.number().default(0).describe(AUDIT_LOGS.EXPORT.offset),
limit: z.coerce.number().max(1000).default(20).describe(AUDIT_LOGS.EXPORT.limit),
actor: z.string().optional().describe(AUDIT_LOGS.EXPORT.actor)
})
.superRefine((el, ctx) => {
if (el.endDate && el.startDate) {
const startDate = new Date(el.startDate);
const endDate = new Date(el.endDate);
const maxAllowedDate = new Date(startDate);
maxAllowedDate.setMonth(maxAllowedDate.getMonth() + 3);
if (endDate < startDate) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ["endDate"],
message: "End date cannot be before start date"
});
} }
if (endDate > maxAllowedDate) {
const pairs = val.split(","); ctx.addIssue({
code: z.ZodIssueCode.custom,
return pairs.reduce( path: ["endDate"],
(acc, pair) => { message: "Dates must be within 3 months"
const [key, value] = pair.split("="); });
if (key && value) { }
acc[key] = value; }
} }),
return acc;
},
{} as Record<string, string>
);
})
.describe(AUDIT_LOGS.EXPORT.eventMetadata),
startDate: z.string().datetime().optional().describe(AUDIT_LOGS.EXPORT.startDate),
endDate: z.string().datetime().default(new Date().toISOString()).describe(AUDIT_LOGS.EXPORT.endDate),
offset: z.coerce.number().default(0).describe(AUDIT_LOGS.EXPORT.offset),
limit: z.coerce.number().default(20).describe(AUDIT_LOGS.EXPORT.limit),
actor: z.string().optional().describe(AUDIT_LOGS.EXPORT.actor)
}),
response: { response: {
200: z.object({ 200: z.object({
auditLogs: AuditLogsSchema.omit({ auditLogs: AuditLogsSchema.omit({