Skip to content

Commit 8770cd5

Browse files
committed
fix(buffer): always mint fresh presigned URLs from verified storage keys for media
1 parent 4e20bc3 commit 8770cd5

1 file changed

Lines changed: 25 additions & 20 deletions

File tree

apps/sim/lib/uploads/utils/file-utils.server.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -83,25 +83,11 @@ export async function resolveFileInputToUrl(
8383
}
8484
}
8585

86-
let fileUrl = userFile.url || ''
87-
88-
// Handle internal URLs
89-
if (fileUrl && isInternalFileUrl(fileUrl)) {
90-
const resolution = await resolveInternalFileUrl(
91-
fileUrl,
92-
userId,
93-
requestId,
94-
logger,
95-
presignExpirySeconds
96-
)
97-
if (resolution.error) {
98-
return { error: resolution.error }
99-
}
100-
fileUrl = resolution.fileUrl || ''
101-
}
102-
103-
// Generate presigned URL if we have a key but no URL
104-
if (!fileUrl && userFile.key) {
86+
// A stored file always gets a freshly minted presigned URL scoped to the
87+
// requested expiry — an embedded url (internal serve path or a previously
88+
// minted presigned link) may be stale, shorter-lived than required, or
89+
// point at a different object than the verified key.
90+
if (userFile.key) {
10591
const context = resolveTrustedFileContext(userFile.key, userFile.context)
10692
const hasAccess = await verifyFileAccess(userFile.key, userId, undefined, context, false)
10793

@@ -114,11 +100,30 @@ export async function resolveFileInputToUrl(
114100
return { error: { status: 404, message: 'File not found' } }
115101
}
116102

117-
fileUrl = await StorageService.generatePresignedDownloadUrl(
103+
const fileUrl = await StorageService.generatePresignedDownloadUrl(
118104
userFile.key,
119105
context,
120106
presignExpirySeconds
121107
)
108+
return { fileUrl }
109+
}
110+
111+
let fileUrl = userFile.url || ''
112+
113+
// Without a key, the schema guarantees the url references an uploaded
114+
// file, so resolve the internal serve path to a presigned URL.
115+
if (fileUrl && isInternalFileUrl(fileUrl)) {
116+
const resolution = await resolveInternalFileUrl(
117+
fileUrl,
118+
userId,
119+
requestId,
120+
logger,
121+
presignExpirySeconds
122+
)
123+
if (resolution.error) {
124+
return { error: resolution.error }
125+
}
126+
fileUrl = resolution.fileUrl || ''
122127
}
123128

124129
return { fileUrl }

0 commit comments

Comments
 (0)