From 5b7e9e7a829f7725d06f13f18531bcd98f990f20 Mon Sep 17 00:00:00 2001 From: Izan Gil <66965250+SrIzan10@users.noreply.github.com> Date: Sat, 28 Mar 2026 15:25:34 +0100 Subject: [PATCH] chore(ut): add prefixes for all user uploaded files --- apps/web/src/lib/form/actions.ts | 4 +- .../lib/services/uploadthing/fileRouter.ts | 37 ++++++++++++++----- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/apps/web/src/lib/form/actions.ts b/apps/web/src/lib/form/actions.ts index 8af8068..0e0509e 100644 --- a/apps/web/src/lib/form/actions.ts +++ b/apps/web/src/lib/form/actions.ts @@ -650,8 +650,8 @@ export async function editBot(prev: any, formData: FormData) { } if (zod.data.pfpUrl === '') { - const identicon = await genIdenticonUpload(zod.data.name, 'pfp'); - zod.data.pfpUrl = identicon; + const identicon = await genIdenticonUpload(zod.data.name, 'pfp'); + zod.data.pfpUrl = identicon; } // i feel like you could just append the data instead of manually changing each field but oh well diff --git a/apps/web/src/lib/services/uploadthing/fileRouter.ts b/apps/web/src/lib/services/uploadthing/fileRouter.ts index 3dfcef7..45b2225 100644 --- a/apps/web/src/lib/services/uploadthing/fileRouter.ts +++ b/apps/web/src/lib/services/uploadthing/fileRouter.ts @@ -1,6 +1,6 @@ -import { createUploadthing, type FileRouter } from "uploadthing/next"; -import { UploadThingError } from "uploadthing/server"; -import { validateRequest } from "../../auth/validate"; +import { createUploadthing, type FileRouter } from 'uploadthing/next'; +import { UTFiles, UploadThingError } from 'uploadthing/server'; +import { validateRequest } from '../../auth/validate'; const f = createUploadthing(); @@ -9,6 +9,17 @@ const auth = async () => { return req.user; }; +const getRenamedFile = (file: { name: string }) => { + const suffix = crypto.randomUUID().replace(/-/g, '').slice(0, 4).toLowerCase(); + const dotIndex = file.name.lastIndexOf('.'); + const hasExtension = dotIndex > 0; + const rawBaseName = hasExtension ? file.name.slice(0, dotIndex) : file.name; + const extension = hasExtension ? file.name.slice(dotIndex) : ''; + const safeBaseName = rawBaseName.replace(/[^a-zA-Z0-9-_]/g, '-'); + + return `pfpup-${safeBaseName}-${suffix}${extension}`; +}; + // FileRouter for your app, can contain multiple FileRoutes export const ourFileRouter = { // Define as many FileRoutes as you like, each with a unique routeSlug @@ -18,26 +29,32 @@ export const ourFileRouter = { * For full list of options and defaults, see the File Route API reference * @see https://docs.uploadthing.com/file-routes#route-config */ - maxFileSize: "1MB", + maxFileSize: '1MB', maxFileCount: 1, - }, + }, }) // Set permissions and file types for this FileRoute - .middleware(async () => { + .middleware(async ({ files }) => { // This code runs on your server before upload const user = await auth(); // If you throw, the user will not be able to upload - if (!user) throw new UploadThingError("Unauthorized"); + if (!user) throw new UploadThingError('Unauthorized'); // Whatever is returned here is accessible in onUploadComplete as `metadata` - return { userId: user.id }; + return { + userId: user.id, + [UTFiles]: files.map((file) => ({ + ...file, + name: getRenamedFile(file), + })), + }; }) .onUploadComplete(async ({ metadata, file }) => { // This code RUNS ON YOUR SERVER after upload - console.log("Upload complete for userId:", metadata.userId); + console.log('Upload complete for userId:', metadata.userId); - console.log("file url", file.ufsUrl); + console.log('file url', file.ufsUrl); // !!! Whatever is returned here is sent to the clientside `onClientUploadComplete` callback return { uploadedBy: metadata.userId };