Skip to content

Commit df8b98f

Browse files
committed
fix
1 parent 135512e commit df8b98f

2 files changed

Lines changed: 54 additions & 10 deletions

File tree

apps/sim/app/api/files/download/route.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { fileDownloadContract } from '@/lib/api/contracts/storage-transfer'
44
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
55
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
66
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
7-
import type { StorageContext } from '@/lib/uploads/config'
87
import { hasCloudStorage } from '@/lib/uploads/core/storage-service'
8+
import { resolveTrustedFileContext } from '@/lib/uploads/utils/file-utils'
99
import { verifyFileAccess } from '@/app/api/files/authorization'
1010
import { createErrorResponse, FileNotFoundError } from '@/app/api/files/utils'
1111

@@ -58,12 +58,10 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
5858
})
5959
}
6060

61-
let storageContext: StorageContext | 'general' | undefined = context
62-
63-
if (isExecutionFile && !context) {
64-
storageContext = 'execution'
65-
logger.info(`Using execution context for file: ${key}`)
66-
}
61+
const storageContext = resolveTrustedFileContext(
62+
key,
63+
isExecutionFile && !context ? 'execution' : context
64+
)
6765

6866
const hasAccess = await verifyFileAccess(
6967
key,
@@ -79,10 +77,9 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
7977
}
8078

8179
const { getBaseUrl } = await import('@/lib/core/utils/urls')
82-
const contextQuery = storageContext ? `?context=${storageContext}` : ''
83-
const downloadUrl = `${getBaseUrl()}/api/files/serve/${encodeURIComponent(key)}${contextQuery}`
80+
const downloadUrl = `${getBaseUrl()}/api/files/serve/${encodeURIComponent(key)}?context=${storageContext}`
8481

85-
logger.info(`Generated download URL for ${storageContext ?? 'inferred'} file: ${key}`)
82+
logger.info(`Generated download URL for ${storageContext} file: ${key}`)
8683

8784
return NextResponse.json({
8885
downloadUrl,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @vitest-environment node
3+
*/
4+
import { beforeEach, describe, expect, it, vi } from 'vitest'
5+
6+
const { mockDownloadFile } = vi.hoisted(() => ({
7+
mockDownloadFile: vi.fn(),
8+
}))
9+
10+
vi.mock('@/lib/uploads/core/storage-service', () => ({
11+
downloadFile: mockDownloadFile,
12+
hasCloudStorage: vi.fn(() => true),
13+
}))
14+
15+
vi.mock('@/app/api/files/authorization', () => ({
16+
verifyFileAccess: vi.fn(),
17+
}))
18+
19+
import { createLogger } from '@sim/logger'
20+
import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server'
21+
import type { UserFile } from '@/executor/types'
22+
23+
describe('downloadFileFromStorage context derivation', () => {
24+
beforeEach(() => {
25+
vi.clearAllMocks()
26+
mockDownloadFile.mockResolvedValue(Buffer.from('bytes'))
27+
})
28+
29+
it('downloads with the key-derived context, ignoring a caller-supplied public context', async () => {
30+
const userFile: UserFile = {
31+
id: 'f1',
32+
name: 'report.pdf',
33+
url: '',
34+
size: 5,
35+
type: 'application/pdf',
36+
key: 'workspace/ws-1/1700000000000-abc1234-report.pdf',
37+
context: 'og-images',
38+
}
39+
40+
await downloadFileFromStorage(userFile, 'req-1', createLogger('test'))
41+
42+
expect(mockDownloadFile).toHaveBeenCalledTimes(1)
43+
expect(mockDownloadFile).toHaveBeenCalledWith(
44+
expect.objectContaining({ key: userFile.key, context: 'workspace' })
45+
)
46+
})
47+
})

0 commit comments

Comments
 (0)