Anonymize photo upload storage urls

This commit is contained in:
Sam Becker 2024-05-12 19:02:53 -05:00
parent 9c9541977f
commit e00d6ad62a
2 changed files with 41 additions and 20 deletions

View File

@ -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);

View File

@ -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<string> => {
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<string> => {
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':