75 lines
1.7 KiB
TypeScript
75 lines
1.7 KiB
TypeScript
import { DeleteObjectCommand, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3"
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
|
|
import { nanoid } from "nanoid"
|
|
|
|
import { getS3Client, getUploadBucket } from "@/lib/storage/s3"
|
|
|
|
function safeFilename(filename: string) {
|
|
const normalized = filename
|
|
.normalize("NFKD")
|
|
.replace(/[\u0300-\u036f]/g, "")
|
|
.replace(/[^a-zA-Z0-9._-]/g, "-")
|
|
.replace(/-+/g, "-")
|
|
.replace(/^-|-$/g, "")
|
|
|
|
return normalized || "upload"
|
|
}
|
|
|
|
export function createInvitationUploadKey(invitationId: string, filename: string) {
|
|
return `invitations/${invitationId}/${nanoid(12)}-${safeFilename(filename)}`
|
|
}
|
|
|
|
export function isObjectKeyForInvitation(objectKey: string, invitationId: string) {
|
|
return objectKey.startsWith(`invitations/${invitationId}/`)
|
|
}
|
|
|
|
export async function createPresignedUploadUrl({
|
|
objectKey,
|
|
contentType,
|
|
sizeBytes,
|
|
}: {
|
|
objectKey: string
|
|
contentType: string
|
|
sizeBytes: number
|
|
}) {
|
|
const client = getS3Client()
|
|
const bucket = getUploadBucket()
|
|
|
|
return getSignedUrl(
|
|
client,
|
|
new PutObjectCommand({
|
|
Bucket: bucket,
|
|
Key: objectKey,
|
|
ContentType: contentType,
|
|
ContentLength: sizeBytes,
|
|
}),
|
|
{ expiresIn: 60 * 5 },
|
|
)
|
|
}
|
|
|
|
export async function createPresignedDownloadUrl(objectKey: string) {
|
|
const client = getS3Client()
|
|
const bucket = getUploadBucket()
|
|
|
|
return getSignedUrl(
|
|
client,
|
|
new GetObjectCommand({
|
|
Bucket: bucket,
|
|
Key: objectKey,
|
|
}),
|
|
{ expiresIn: 60 * 10 },
|
|
)
|
|
}
|
|
|
|
export async function deleteUploadObject(objectKey: string) {
|
|
const client = getS3Client()
|
|
const bucket = getUploadBucket()
|
|
|
|
await client.send(
|
|
new DeleteObjectCommand({
|
|
Bucket: bucket,
|
|
Key: objectKey,
|
|
}),
|
|
)
|
|
}
|