Skip to content

Commit 2a0d76b

Browse files
committed
fix byok issue
1 parent 88d9fb0 commit 2a0d76b

17 files changed

Lines changed: 454 additions & 72 deletions

File tree

apps/sim/app/api/workflows/[id]/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export const GET = withRouteHandler(
8383

8484
// Stamp `workflowId` from the path param on each variable so the
8585
// global client-side variables store can filter by workflow without
86-
// requiring the wire contract to carry a redundant `workflowId`.
86+
// requiring persisted variables to carry a redundant `workflowId`.
8787
// The persisted blob may or may not include `workflowId` depending on
8888
// when the variable was last written; the path param is authoritative.
8989
const persistedVariables =

apps/sim/app/api/workflows/[id]/state/route.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ export const GET = withRouteHandler(
5555

5656
// Stamp `workflowId` from the path param on each variable so the
5757
// global client-side variables store can filter by workflow without
58-
// requiring clients to thread the path param through. The wire
59-
// contract (`workflowVariableSchema`) intentionally omits
60-
// `workflowId`; the server is the single source of truth.
58+
// requiring clients to thread the path param through. The read
59+
// contract requires this server-stamped field.
6160
const persistedVariables =
6261
(authorization.workflow?.variables as Record<string, Record<string, unknown>>) || {}
6362
const variables: Record<string, Record<string, unknown>> = {}
@@ -131,7 +130,7 @@ export const PUT = withRouteHandler(
131130
}
132131

133132
// Note: prior versions cross-checked that each variable's `workflowId`
134-
// equalled the path param. The contract no longer carries `workflowId`
133+
// equalled the path param. The write contract does not carry `workflowId`
135134
// per variable (the path param is the source of truth), so the check
136135
// is unreachable and was removed.
137136

apps/sim/app/api/workflows/[id]/variables/route.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from '@sim/testing'
1313
import { NextRequest } from 'next/server'
1414
import { beforeEach, describe, expect, it, vi } from 'vitest'
15+
import { getWorkflowVariablesContract } from '@/lib/api/contracts/workflows'
1516

1617
vi.mock('@sim/audit', () => auditMock)
1718

@@ -103,6 +104,8 @@ describe('Workflow Variables API Route', () => {
103104
workflowId: 'workflow-123',
104105
},
105106
})
107+
const parsed = getWorkflowVariablesContract.response.schema.parse(data)
108+
expect(parsed.data['var-1'].workflowId).toBe('workflow-123')
106109
})
107110

108111
it('should allow access when user has workspace permissions', async () => {

apps/sim/app/api/workflows/[id]/variables/route.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const POST = withRouteHandler(
5454
if (!parsed.success) return parsed.response
5555
const { variables } = parsed.data.body
5656
// Note: prior versions cross-checked that each variable's `workflowId`
57-
// equalled the path param. The contract no longer carries `workflowId`
57+
// equalled the path param. The write contract does not carry `workflowId`
5858
// per variable (the path param is the source of truth), so the check
5959
// is unreachable and was removed.
6060

@@ -132,8 +132,7 @@ export const GET = withRouteHandler(
132132

133133
// Return variables if they exist. Stamp `workflowId` from the path
134134
// param on each entry so the global client-side variables store can
135-
// filter by workflow without requiring the wire contract to carry a
136-
// redundant `workflowId` field.
135+
// filter by workflow; the read contract requires this stamped field.
137136
const persistedVariables =
138137
(workflowData.variables as Record<string, Record<string, unknown>>) || {}
139138
const variables: Record<string, Variable> = {}

apps/sim/app/workspace/[workspaceId]/logs/components/logs-toolbar/components/notifications/notifications.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
44
import { createLogger } from '@sim/logger'
55
import { Plus, X } from 'lucide-react'
6-
import type { z } from 'zod'
76
import {
87
Badge,
98
Button,
@@ -25,9 +24,9 @@ import {
2524
} from '@/components/emcn'
2625
import { SlackIcon } from '@/components/icons'
2726
import type {
28-
alertRuleSchema,
29-
notificationLevelSchema,
30-
notificationTypeSchema,
27+
NotificationAlertRule,
28+
NotificationLogLevel,
29+
NotificationType,
3130
} from '@/lib/api/contracts/notifications'
3231
import { dollarsToCredits } from '@/lib/billing/credits/conversion'
3332
import { getTriggerOptions } from '@/lib/logs/get-trigger-options'
@@ -53,10 +52,9 @@ const logger = createLogger('NotificationSettings')
5352
const TRIGGER_OPTIONS = getTriggerOptions()
5453
const ALL_TRIGGER_VALUES = TRIGGER_OPTIONS.map((t) => t.value)
5554

56-
type NotificationType = z.output<typeof notificationTypeSchema>
57-
type LogLevel = z.output<typeof notificationLevelSchema>
55+
type LogLevel = NotificationLogLevel
5856
/** Contract alert rule plus a UI-only `'none'` sentinel meaning "no alert config". */
59-
type AlertRule = z.output<typeof alertRuleSchema> | 'none'
57+
type AlertRule = NotificationAlertRule | 'none'
6058

6159
const ALERT_RULES: { value: AlertRule; label: string; description: string }[] = [
6260
{ value: 'none', label: 'None', description: 'Notify on every matching execution' },

apps/sim/ee/access-control/hooks/permission-groups.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client'
22

33
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
4-
import type { z } from 'zod'
54
import { requestJson } from '@/lib/api/client/request'
65
import {
76
bulkAddPermissionGroupMembersContract,
@@ -10,17 +9,15 @@ import {
109
getUserPermissionConfigContract,
1110
listPermissionGroupMembersContract,
1211
listPermissionGroupsContract,
13-
type permissionGroupMemberSchema,
14-
type permissionGroupSchema,
12+
type PermissionGroup,
13+
type PermissionGroupMember,
1514
removePermissionGroupMemberContract,
15+
type UserPermissionConfig,
1616
updatePermissionGroupContract,
17-
type userPermissionConfigSchema,
1817
} from '@/lib/api/contracts'
1918
import type { PermissionGroupConfig } from '@/lib/permission-groups/types'
2019

21-
export type PermissionGroup = z.output<typeof permissionGroupSchema>
22-
export type PermissionGroupMember = z.output<typeof permissionGroupMemberSchema>
23-
export type UserPermissionConfig = z.output<typeof userPermissionConfigSchema>
20+
export type { PermissionGroup, PermissionGroupMember, UserPermissionConfig }
2421

2522
export const permissionGroupKeys = {
2623
all: ['permissionGroups'] as const,

apps/sim/ee/data-retention/hooks/data-retention.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,13 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
44
import { requestJson } from '@/lib/api/client/request'
55
import {
66
getOrganizationDataRetentionContract,
7+
type OrganizationDataRetention,
8+
type OrganizationRetentionValues,
79
updateOrganizationDataRetentionContract,
810
} from '@/lib/api/contracts/organization'
911

10-
export interface RetentionValues {
11-
logRetentionHours: number | null
12-
softDeleteRetentionHours: number | null
13-
taskCleanupHours: number | null
14-
}
15-
16-
export interface DataRetentionResponse {
17-
isEnterprise: boolean
18-
defaults: RetentionValues
19-
configured: RetentionValues
20-
effective: RetentionValues
21-
}
12+
export type RetentionValues = OrganizationRetentionValues
13+
export type DataRetentionResponse = OrganizationDataRetention
2214

2315
export const dataRetentionKeys = {
2416
all: ['dataRetention'] as const,

apps/sim/lib/api/contracts/audit-logs.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ export const v1AdminAuditLogsQuerySchema = z.object({
7777
endDate: z.preprocess((value) => (value === '' ? undefined : value), isoDateString.optional()),
7878
})
7979

80+
/**
81+
* Generic wrapper used by v1 admin audit-log responses. The `data` and
82+
* `limits` halves are intentionally `z.unknown()` because this proxy returns
83+
* provider-shaped payloads that vary per route family; tightening here would
84+
* require a discriminated union per route, which is tracked as a follow-up.
85+
*
86+
* boundary-policy: this is the "validates nothing" alias form that the audit
87+
* script's `untyped-response` regex doesn't currently catch. Treat any new
88+
* wrapper of this shape the same way and either annotate at the contract use
89+
* site with `// untyped-response: <reason>` or replace with a concrete schema.
90+
*/
8091
const apiResponseWithLimitsSchema = z
8192
.object({
8293
data: z.unknown(),

apps/sim/lib/api/contracts/organization.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,20 @@ const organizationRetentionValuesSchema = z.object({
113113
taskCleanupHours: z.number().int().nullable(),
114114
})
115115

116+
export type OrganizationRetentionValues = z.output<typeof organizationRetentionValuesSchema>
117+
118+
const organizationDataRetentionDataSchema = z.object({
119+
isEnterprise: z.boolean(),
120+
defaults: organizationRetentionValuesSchema,
121+
configured: organizationRetentionValuesSchema,
122+
effective: organizationRetentionValuesSchema,
123+
})
124+
125+
export type OrganizationDataRetention = z.output<typeof organizationDataRetentionDataSchema>
126+
116127
export const organizationDataRetentionResponseSchema = z.object({
117128
success: z.boolean(),
118-
data: z.object({
119-
isEnterprise: z.boolean(),
120-
defaults: organizationRetentionValuesSchema,
121-
configured: organizationRetentionValuesSchema,
122-
effective: organizationRetentionValuesSchema,
123-
}),
129+
data: organizationDataRetentionDataSchema,
124130
})
125131

126132
export const updateOrganizationWhitelabelBodySchema = z.object({

apps/sim/lib/api/contracts/permission-groups.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export const permissionGroupSchema = z.object({
5252
memberCount: z.number(),
5353
autoAddNewMembers: z.boolean(),
5454
})
55+
export type PermissionGroup = z.output<typeof permissionGroupSchema>
5556

5657
export const permissionGroupWriteSchema = z.object({
5758
id: z.string(),
@@ -64,6 +65,7 @@ export const permissionGroupWriteSchema = z.object({
6465
updatedAt: z.string(),
6566
autoAddNewMembers: z.boolean(),
6667
})
68+
export type PermissionGroupWrite = z.output<typeof permissionGroupWriteSchema>
6769

6870
export const permissionGroupMemberSchema = z.object({
6971
id: z.string(),
@@ -73,6 +75,7 @@ export const permissionGroupMemberSchema = z.object({
7375
userEmail: z.string().nullable(),
7476
userImage: z.string().nullable(),
7577
})
78+
export type PermissionGroupMember = z.output<typeof permissionGroupMemberSchema>
7679

7780
export const userPermissionConfigQuerySchema = z.object({
7881
workspaceId: z.string().min(1),
@@ -84,6 +87,7 @@ export const userPermissionConfigSchema = z.object({
8487
config: permissionGroupFullConfigSchema.nullable(),
8588
entitled: z.boolean(),
8689
})
90+
export type UserPermissionConfig = z.output<typeof userPermissionConfigSchema>
8791

8892
export const createPermissionGroupBodySchema = z.object({
8993
name: z.string().trim().min(1).max(100),

0 commit comments

Comments
 (0)