Skip to content

Commit cb9fd08

Browse files
committed
fix(api): address PR review — boolean coercion, cursor validation, detail scope
1 parent 7ae3273 commit cb9fd08

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

apps/sim/app/api/v1/audit-logs/[id]/route.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
* Get a single audit log entry by ID, scoped to the authenticated user's organization.
55
* Requires enterprise subscription and org admin/owner role.
66
*
7+
* Scope includes logs from current org members AND logs within org workspaces
8+
* (including those from departed members or system actions with null actorId).
9+
*
710
* Response: { data: AuditLogEntry, limits: UserLimits }
811
*/
912

1013
import { db } from '@sim/db'
11-
import { auditLog } from '@sim/db/schema'
14+
import { auditLog, workspace } from '@sim/db/schema'
1215
import { createLogger } from '@sim/logger'
13-
import { and, eq, inArray } from 'drizzle-orm'
16+
import { and, eq, inArray, or } from 'drizzle-orm'
1417
import { type NextRequest, NextResponse } from 'next/server'
1518
import { validateEnterpriseAuditAccess } from '@/app/api/v1/audit-logs/auth'
1619
import { formatAuditLogEntry } from '@/app/api/v1/audit-logs/format'
@@ -43,13 +46,21 @@ export async function GET(
4346

4447
const { orgMemberIds } = authResult.context
4548

49+
const orgWorkspaceIds = db
50+
.select({ id: workspace.id })
51+
.from(workspace)
52+
.where(inArray(workspace.ownerId, orgMemberIds))
53+
4654
const [log] = await db
4755
.select()
4856
.from(auditLog)
4957
.where(
5058
and(
5159
eq(auditLog.id, id),
52-
inArray(auditLog.actorId, orgMemberIds)
60+
or(
61+
inArray(auditLog.actorId, orgMemberIds),
62+
inArray(auditLog.workspaceId, orgWorkspaceIds)
63+
)
5364
)
5465
)
5566
.limit(1)

apps/sim/app/api/v1/audit-logs/route.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ const QueryParamsSchema = z.object({
4747
actorId: z.string().optional(),
4848
startDate: isoDateString.optional(),
4949
endDate: isoDateString.optional(),
50-
includeDeparted: z.coerce.boolean().optional().default(false),
50+
includeDeparted: z
51+
.enum(['true', 'false'])
52+
.transform((val) => val === 'true')
53+
.optional()
54+
.default('false'),
5155
limit: z.coerce.number().min(1).max(100).optional().default(50),
5256
cursor: z.string().optional(),
5357
})
@@ -141,16 +145,19 @@ export async function GET(request: NextRequest) {
141145

142146
if (params.cursor) {
143147
const cursorData = decodeCursor(params.cursor)
144-
if (cursorData) {
145-
conditions.push(
146-
or(
147-
lt(auditLog.createdAt, new Date(cursorData.createdAt)),
148-
and(
149-
eq(auditLog.createdAt, new Date(cursorData.createdAt)),
150-
lt(auditLog.id, cursorData.id)
151-
)
152-
)!
153-
)
148+
if (cursorData && cursorData.createdAt && cursorData.id) {
149+
const cursorDate = new Date(cursorData.createdAt)
150+
if (!isNaN(cursorDate.getTime())) {
151+
conditions.push(
152+
or(
153+
lt(auditLog.createdAt, cursorDate),
154+
and(
155+
eq(auditLog.createdAt, cursorDate),
156+
lt(auditLog.id, cursorData.id)
157+
)
158+
)!
159+
)
160+
}
154161
}
155162
}
156163

0 commit comments

Comments
 (0)