mirror of
https://github.com/MeshEnvy/mesh-forge.git
synced 2026-03-28 17:42:55 +01:00
37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3"
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
|
|
|
|
export async function generateSignedDownloadUrl(
|
|
objectKey: string,
|
|
filename: string,
|
|
contentType: string = "application/octet-stream"
|
|
): Promise<string> {
|
|
const accountId = process.env.R2_ACCOUNT_ID
|
|
const accessKeyId = process.env.R2_ACCESS_KEY_ID
|
|
const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY
|
|
const bucketName = process.env.R2_BUCKET_NAME
|
|
|
|
if (!accountId || !accessKeyId || !secretAccessKey || !bucketName) {
|
|
throw new Error("R2 credentials are not set")
|
|
}
|
|
|
|
const s3 = new S3Client({
|
|
region: "auto",
|
|
endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
|
|
credentials: {
|
|
accessKeyId,
|
|
secretAccessKey,
|
|
},
|
|
})
|
|
|
|
const command = new GetObjectCommand({
|
|
Bucket: bucketName,
|
|
Key: objectKey,
|
|
ResponseContentDisposition: `attachment; filename="${filename}"`,
|
|
ResponseContentType: contentType,
|
|
})
|
|
|
|
// URL expires in 1 hour (3600 seconds)
|
|
return await getSignedUrl(s3, command, { expiresIn: 3600 })
|
|
}
|