diff --git a/src/features/account/AccountProfileForm.tsx b/src/features/account/AccountProfileForm.tsx index a5c531d5b..4289fe154 100644 --- a/src/features/account/AccountProfileForm.tsx +++ b/src/features/account/AccountProfileForm.tsx @@ -33,7 +33,6 @@ export const AccountProfileForm = () => { }); const accountAvatar = useAvatarFetch(account.data?.image ?? ''); - const uploadFile = useAvatarUpload(); const updateAccount = trpc.account.update.useMutation({ diff --git a/src/files/schemas.ts b/src/files/schemas.ts index 9e40d5e4e..53a4bb068 100644 --- a/src/files/schemas.ts +++ b/src/files/schemas.ts @@ -4,14 +4,7 @@ import { z } from 'zod'; import { zu } from '@/lib/zod/zod-utils'; export type UploadFileType = z.infer; -export const zUploadFileType = z.enum([ - 'image', - 'video', - 'audio', - 'blob', - 'pdf', - 'text', -]); +export const zUploadFileType = z.enum(['image', 'application/pdf']); export type FieldUploadValue = z.infer>; export const zFieldUploadValue = (acceptedTypes?: UploadFileType[]) => diff --git a/src/files/utils.ts b/src/files/utils.ts index a6c2857d9..3cfcd4854 100644 --- a/src/files/utils.ts +++ b/src/files/utils.ts @@ -1,6 +1,8 @@ import { UseMutateAsyncFunction } from '@tanstack/react-query'; import { stringify } from 'superjson'; +import { env } from '@/env.mjs'; + import { UploadSignedUrlInput } from './schemas'; /** @@ -51,7 +53,7 @@ export const fetchFile = async (url: string, metadata?: string[]) => { /** * Asynchronously uploads a file to a server using a presigned URL. - * Designed to be used as a `mutationFn` in a `useMutation`. + * Designed to be used as a `mutationFn` in a `useMutation`. * * @param getPresignedUrl * - An asyncMutation that is used to obtain the presigned URL and the future URL where the file will be accessible. @@ -94,3 +96,7 @@ export const uploadFile = async ( fileUrl: futureFileUrl, } as const; }; + +export const isFileUrlValidBucket = async (url: string) => { + return url.startsWith(env.S3_BUCKET_PUBLIC_URL); +}; diff --git a/src/server/router.ts b/src/server/router.ts index 3b560f373..3ce18c905 100644 --- a/src/server/router.ts +++ b/src/server/router.ts @@ -1,7 +1,6 @@ import { createTRPCRouter } from '@/server/config/trpc'; import { accountRouter } from '@/server/routers/account'; import { authRouter } from '@/server/routers/auth'; -import { filesRouter } from '@/server/routers/files'; import { oauthRouter } from '@/server/routers/oauth'; import { repositoriesRouter } from '@/server/routers/repositories'; import { usersRouter } from '@/server/routers/users'; @@ -17,7 +16,6 @@ export const appRouter = createTRPCRouter({ oauth: oauthRouter, repositories: repositoriesRouter, users: usersRouter, - files: filesRouter, }); // export type definition of API diff --git a/src/server/routers/account.tsx b/src/server/routers/account.tsx index 2709fec32..7caaf02fd 100644 --- a/src/server/routers/account.tsx +++ b/src/server/routers/account.tsx @@ -15,6 +15,7 @@ import { import { zVerificationCodeValidate } from '@/features/auth/schemas'; import { VALIDATION_TOKEN_EXPIRATION_IN_MINUTES } from '@/features/auth/utils'; import { zUploadSignedUrlInput, zUploadSignedUrlOutput } from '@/files/schemas'; +import { isFileUrlValidBucket } from '@/files/utils'; import i18n from '@/lib/i18n/server'; import { deleteUsedCode, @@ -63,11 +64,22 @@ export const accountRouter = createTRPCRouter({ .mutation(async ({ ctx, input }) => { try { ctx.logger.info('Updating the user'); + + if (input.image && !isFileUrlValidBucket(input.image)) { + ctx.logger.error('Avatar URL do not match S3 bucket URL'); + throw new TRPCError({ + code: 'BAD_REQUEST', + message: 'Avatar URL do not match S3 bucket URL', + }); + } + return await ctx.db.user.update({ where: { id: ctx.user.id }, data: { ...input, - image: input.image ? `${input.image}?${Date.now()}` : null, + image: input.image + ? `${input.image}?${Date.now()}` // Allows to update the cache when the user changes his account + : null, }, }); } catch (e) { diff --git a/src/server/routers/files.ts b/src/server/routers/files.ts deleted file mode 100644 index bda8f6085..000000000 --- a/src/server/routers/files.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { randomUUID } from 'crypto'; -import { parse } from 'superjson'; - -import { env } from '@/env.mjs'; -import { zUploadSignedUrlInput, zUploadSignedUrlOutput } from '@/files/schemas'; -import { getS3UploadSignedUrl } from '@/server/config/s3'; -import { createTRPCRouter, protectedProcedure } from '@/server/config/trpc'; - -export const filesRouter = createTRPCRouter({ - uploadPresignedUrl: protectedProcedure() - .meta({ - openapi: { - method: 'GET', - path: '/files/upload-presigned-url', - tags: ['files'], - protect: true, - }, - }) - .input(zUploadSignedUrlInput()) - .output(zUploadSignedUrlOutput()) - .mutation(async ({ input }) => { - return await getS3UploadSignedUrl({ - key: randomUUID(), - host: env.S3_BUCKET_PUBLIC_URL, - metadata: parse(input?.metadata ?? ''), - }); - }), -});