mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(files): RFC 5987 encode Content-Disposition filenames (#4713)
This commit is contained in:
@@ -13,6 +13,7 @@ import { USE_BLOB_STORAGE } from '@/lib/uploads/config'
|
||||
import { downloadFile } from '@/lib/uploads/core/storage-service'
|
||||
import { getFileMetadataById } from '@/lib/uploads/server/metadata'
|
||||
import { verifyFileAccess } from '@/app/api/files/authorization'
|
||||
import { encodeFilenameForHeader } from '@/app/api/files/utils'
|
||||
|
||||
const logger = createLogger('FilesExportAPI')
|
||||
|
||||
@@ -95,7 +96,7 @@ export const GET = withRouteHandler(
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'text/markdown; charset=utf-8',
|
||||
'Content-Disposition': `attachment; filename="${mdName}"`,
|
||||
'Content-Disposition': `attachment; ${encodeFilenameForHeader(mdName)}`,
|
||||
'Content-Length': String(mdBytes.length),
|
||||
},
|
||||
})
|
||||
@@ -158,7 +159,7 @@ export const GET = withRouteHandler(
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/zip',
|
||||
'Content-Disposition': `attachment; filename="${zipName}"`,
|
||||
'Content-Disposition': `attachment; ${encodeFilenameForHeader(zipName)}`,
|
||||
'Content-Length': String(zipBuffer.length),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -191,7 +191,7 @@ function getSecureFileHeaders(filename: string, originalContentType: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function encodeFilenameForHeader(storageKey: string): string {
|
||||
export function encodeFilenameForHeader(storageKey: string): string {
|
||||
const filename = storageKey.split('/').pop() || storageKey
|
||||
|
||||
const hasNonAscii = /[^\x00-\x7F]/.test(filename)
|
||||
|
||||
@@ -21,6 +21,7 @@ import { parseRequest } from '@/lib/api/server'
|
||||
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
|
||||
import { exportFolderToZip, sanitizePathSegment } from '@/lib/workflows/operations/import-export'
|
||||
import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/persistence/utils'
|
||||
import { encodeFilenameForHeader } from '@/app/api/files/utils'
|
||||
import { withAdminAuthParams } from '@/app/api/v1/admin/middleware'
|
||||
import {
|
||||
internalErrorResponse,
|
||||
@@ -242,7 +243,7 @@ export const GET = withRouteHandler(
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/zip',
|
||||
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||
'Content-Disposition': `attachment; ${encodeFilenameForHeader(filename)}`,
|
||||
'Content-Length': arrayBuffer.byteLength.toString(),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -21,6 +21,7 @@ import { parseRequest } from '@/lib/api/server'
|
||||
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
|
||||
import { exportWorkspaceToZip, sanitizePathSegment } from '@/lib/workflows/operations/import-export'
|
||||
import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/persistence/utils'
|
||||
import { encodeFilenameForHeader } from '@/app/api/files/utils'
|
||||
import { withAdminAuthParams } from '@/app/api/v1/admin/middleware'
|
||||
import {
|
||||
internalErrorResponse,
|
||||
@@ -162,7 +163,7 @@ export const GET = withRouteHandler(
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/zip',
|
||||
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||
'Content-Disposition': `attachment; ${encodeFilenameForHeader(filename)}`,
|
||||
'Content-Length': arrayBuffer.byteLength.toString(),
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user