From e00d6ad62a7e6f9f13589f0b40b8612f0aa25157 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sun, 12 May 2024 19:02:53 -0500 Subject: [PATCH] Anonymize photo upload storage urls --- src/photo/actions.ts | 10 ++++++- src/services/storage/index.ts | 51 ++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/photo/actions.ts b/src/photo/actions.ts index 80f03e77..7757a4e2 100644 --- a/src/photo/actions.ts +++ b/src/photo/actions.ts @@ -49,7 +49,7 @@ export const createPhotoAction = async (formData: FormData) => safelyRunAdminServerAction(async () => { const photo = convertFormDataToPhotoDbInsert(formData, true); - const updatedUrl = await convertUploadToPhoto(photo.url, photo.id); + const updatedUrl = await convertUploadToPhoto(photo.url); if (updatedUrl) { photo.url = updatedUrl; } @@ -64,6 +64,14 @@ export const updatePhotoAction = async (formData: FormData) => safelyRunAdminServerAction(async () => { const photo = convertFormDataToPhotoDbInsert(formData); + let url: string | undefined; + if (photo.hidden && photo.url.includes(photo.id)) { + // Anonymize storage url on update if necessary by + // re-running image upload transfer logic + url = await convertUploadToPhoto(photo.url); + if (url) { photo.url = url; } + } + await sqlUpdatePhoto(photo); revalidatePhoto(photo.id); diff --git a/src/services/storage/index.ts b/src/services/storage/index.ts index 0f3e008e..481cff36 100644 --- a/src/services/storage/index.ts +++ b/src/services/storage/index.ts @@ -129,53 +129,66 @@ export const uploadPhotoFromClient = async ( ? uploadFromClientViaPresignedUrl(file, PREFIX_UPLOAD, extension, true) : vercelBlobUploadFromClient(file, `${PREFIX_UPLOAD}.${extension}`); -export const convertUploadToPhoto = async ( - uploadUrl: string, - photoId?: string, -): Promise => { - const fileName = photoId ? `${PREFIX_PHOTO}-${photoId}` : `${PREFIX_PHOTO}`; - const fileExtension = getExtensionFromStorageUrl(uploadUrl); - const photoPath = `${fileName}.${fileExtension ?? 'jpg'}`; - - const storageType = storageTypeFromUrl(uploadUrl); +const moveFile = async ( + originUrl: string, + destinationFileName: string, +) => { + const storageType = storageTypeFromUrl(originUrl); let url: string | undefined; // Copy file switch (storageType) { case 'vercel-blob': - url = await vercelBlobCopy(uploadUrl, photoPath, photoId === undefined); + url = await vercelBlobCopy( + originUrl, + destinationFileName, + false, + ); break; case 'cloudflare-r2': url = await cloudflareR2Copy( - getFileNameFromStorageUrl(uploadUrl), - photoPath, - photoId === undefined, + getFileNameFromStorageUrl(originUrl), + destinationFileName, + false, ); break; case 'aws-s3': - url = await awsS3Copy(uploadUrl, photoPath, photoId === undefined); + url = await awsS3Copy( + originUrl, + destinationFileName, + false, + ); break; } - + // If successful, delete original file if (url) { switch (storageType) { case 'vercel-blob': - await vercelBlobDelete(uploadUrl); + await vercelBlobDelete(originUrl); break; case 'cloudflare-r2': - await cloudflareR2Delete(getFileNameFromStorageUrl(uploadUrl)); + await cloudflareR2Delete(getFileNameFromStorageUrl(originUrl)); break; case 'aws-s3': - await awsS3Delete(getFileNameFromStorageUrl(uploadUrl)); + await awsS3Delete(getFileNameFromStorageUrl(originUrl)); break; } } - + return url; }; +export const convertUploadToPhoto = async ( + urlOrigin: string, +): Promise => { + const fileName = `${PREFIX_PHOTO}-${generateStorageId()}`; + const fileExtension = getExtensionFromStorageUrl(urlOrigin); + const photoPath = `${fileName}.${fileExtension || 'jpg'}`; + return moveFile(urlOrigin, photoPath); +}; + export const deleteStorageUrl = (url: string) => { switch (storageTypeFromUrl(url)) { case 'vercel-blob':