Skip to content

Commit b2ecf17

Browse files
committed
feat(cloudflare): expand API coverage and validate operations
1 parent 3aad201 commit b2ecf17

92 files changed

Lines changed: 24039 additions & 6443 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎apps/docs/content/docs/integrations/cloudflare.mdx‎

Lines changed: 8590 additions & 1113 deletions
Large diffs are not rendered by default.

‎apps/sim/blocks/blocks/cloudflare.ts‎

Lines changed: 3853 additions & 1186 deletions
Large diffs are not rendered by default.

‎apps/sim/lib/internal/cloudflare/operations/get-zone-settings.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getErrorMessage } from '@sim/utils/errors'
2+
import { readResponseJsonWithLimit } from '@/lib/core/utils/stream-limits'
23
import type { InternalToolOperationImplementation } from '@/lib/internal/tool-operations/types'
34
import { mapZoneSetting, zoneSettingUrl } from '@/tools/cloudflare/get_zone_settings'
45
import type {
@@ -36,8 +37,11 @@ export const executeGetZoneSettingsOperation: InternalToolOperationImplementatio
3637
headers,
3738
signal,
3839
})
39-
const data = (await response.json()) as CloudflareEnvelope<CloudflareRawZoneSetting>
40-
if (!data.success) {
40+
const data = await readResponseJsonWithLimit<CloudflareEnvelope<CloudflareRawZoneSetting>>(
41+
response,
42+
{ maxBytes: 1024 * 1024, label: 'Cloudflare zone setting' }
43+
)
44+
if (!response.ok || !data.success || !data.result) {
4145
return {
4246
settingId,
4347
error: cloudflareErrorMessage(data, `Failed to read zone setting ${settingId}`),

‎apps/sim/tools/cloudflare/cloudflare.test.ts‎

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,13 @@ describe('a shared subBlock id means the same thing everywhere', () => {
222222
'appId',
223223
'bucketName',
224224
'rulesetId',
225+
'recordId',
226+
'policyId',
227+
'serviceTokenId',
228+
'groupId',
229+
'routeId',
230+
'scriptName',
231+
'tunnelId',
225232
])
226233

227234
/**
@@ -848,21 +855,18 @@ describe('zone settings are read through the endpoints Cloudflare still supports
848855
])
849856
})
850857

851-
it('keeps a crafted zone ID inside the zone path segment', async () => {
858+
it('rejects a crafted zone ID before making a provider request', async () => {
852859
const fetchMock = vi
853860
.spyOn(globalThis, 'fetch')
854861
.mockImplementation(async (input) => settingEnvelope(String(input).split('/').pop()!, 'on'))
855862

856-
await executeGetZoneSettingsOperation({
863+
const result = await executeGetZoneSettingsOperation({
857864
zoneId: '../accounts',
858865
apiKey,
859866
settingIds: 'ssl',
860867
} as never)
861-
862-
expect(fetchMock).toHaveBeenCalledWith(
863-
'https://api.cloudflare.com/client/v4/zones/..%2Faccounts/settings/ssl',
864-
expect.any(Object)
865-
)
868+
expect(result.success).toBe(false)
869+
expect(fetchMock).not.toHaveBeenCalled()
866870
})
867871

868872
it('does not let a dot-segment setting ID escape the settings endpoint', async () => {
@@ -875,7 +879,7 @@ describe('zone settings are read through the endpoints Cloudflare still supports
875879
} as never)) as { success: boolean; error?: string }
876880

877881
expect(out.success).toBe(false)
878-
expect(out.error).toMatch(/setting ID must identify a resource/)
882+
expect(out.error).toMatch(/settingId/)
879883
expect(fetchMock).not.toHaveBeenCalled()
880884
})
881885

@@ -968,6 +972,21 @@ describe('zone settings are read through the endpoints Cloudflare still supports
968972
expect(out.error).toBe('Invalid zone identifier')
969973
})
970974

975+
it('rejects a setting response whose declared size exceeds the per-setting cap', async () => {
976+
vi.spyOn(globalThis, 'fetch').mockResolvedValue(
977+
new Response(JSON.stringify({ success: true, result: { id: 'ssl', value: 'full' } }), {
978+
headers: { 'Content-Length': String(1024 * 1024 + 1) },
979+
})
980+
)
981+
const result = await executeGetZoneSettingsOperation({
982+
zoneId: 'z1',
983+
apiKey,
984+
settingIds: 'ssl',
985+
} as never)
986+
expect(result.success).toBe(false)
987+
expect(result.error).toMatch(/exceed|limit|large/i)
988+
})
989+
971990
it('refuses an unbounded fan-out instead of issuing the requests', async () => {
972991
const fetchMock = vi.spyOn(globalThis, 'fetch')
973992

0 commit comments

Comments
 (0)