From 1027b45cdbca2d7c90b036fc162a61a35be90304 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 3 Jun 2025 13:45:26 +0100 Subject: [PATCH] feat: update image upload API with user authentication and validation --- apps/web/src/pages/api/upload/image.ts | 37 ++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/apps/web/src/pages/api/upload/image.ts b/apps/web/src/pages/api/upload/image.ts index 703d19a6..c4aae974 100644 --- a/apps/web/src/pages/api/upload/image.ts +++ b/apps/web/src/pages/api/upload/image.ts @@ -2,8 +2,12 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; +import { createNextApiContext } from "@kan/api/trpc"; + import { env } from "~/env"; +const allowedContentTypes = ["image/jpeg", "image/png"]; + export default async function handler( req: NextApiRequest, res: NextApiResponse, @@ -13,14 +17,37 @@ export default async function handler( } try { - const { filename, contentType } = req.body; + const { user } = await createNextApiContext(req); + + if (!user) { + return res.status(401).json({ error: "Unauthorized" }); + } + + const { filename, contentType } = req.body as { + filename: string; + contentType: string; + }; + + // Specific to avatar uploads for now + const filenameRegex = /^[a-f0-9\-]+\/[a-zA-Z0-9_\-]+(\.jpg|\.jpeg|\.png)$/; + + if (!filenameRegex.test(filename)) { + return res.status(400).json({ error: "Invalid filename" }); + } + + if ( + typeof contentType !== "string" || + !allowedContentTypes.includes(contentType) + ) { + return res.status(400).json({ error: "Invalid content type" }); + } const client = new S3Client({ - region: env.S3_REGION, - endpoint: env.S3_ENDPOINT, + region: env.S3_REGION ?? "", + endpoint: env.S3_ENDPOINT ?? "", credentials: { - accessKeyId: env.S3_ACCESS_KEY_ID, - secretAccessKey: env.S3_SECRET_ACCESS_KEY, + accessKeyId: env.S3_ACCESS_KEY_ID ?? "", + secretAccessKey: env.S3_SECRET_ACCESS_KEY ?? "", }, });