From f3367e9b7bdb7299a95e1fa9f22b764fa1f60db2 Mon Sep 17 00:00:00 2001 From: openhands Date: Fri, 3 Jul 2026 17:14:44 +0200 Subject: [PATCH] feat: save logos to media/logo/ subdir, add Logo generator link to admin dropdown --- .../images/media/logo-1783091166418-npn577.gif | Bin 0 -> 711 bytes src/actions/save-logo.ts | 10 ++++++---- src/app/api/media/{[name] => [...path]}/route.ts | 7 ++++--- src/components/top-header.tsx | 11 +++++++---- 4 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 public/assets/images/media/logo-1783091166418-npn577.gif rename src/app/api/media/{[name] => [...path]}/route.ts (86%) diff --git a/public/assets/images/media/logo-1783091166418-npn577.gif b/public/assets/images/media/logo-1783091166418-npn577.gif new file mode 100644 index 0000000000000000000000000000000000000000..d995749ff31de555b155c0a174508b7ba752d082 GIT binary patch literal 711 zcmV;&0yzCgNk%w1VXOcr0HOc@0RI300095s0RPSa|6>3E0000000000A^8LW00000 zEC2ui0IUEf000C27`oj4Fv>}*y*O*2yZ>M)id-O^XsV*h>ZYw5zwb=1_6?gl&i6Z@ zN>LI9je;EOXH@o_I_OPGqt*gNWReMlT4mgB_&JW2r{^m6>(hGESM65L9>T%&^}UUJ z=l^bdc7T0)ghGCShlqklg?U+ze3OHCmXef?m6=O%mv)g&V~Lz6q@tdsbDx^6onWCm z60EPPr>>@Dx3!zSxT`*~OS87R#;Lx%zq`4}%f`ZFw9V7N$<)Qp%G=o2);rN=)y&`A z<=xNP=;q`^b-!xr=kx8yiuc9gX!zds^5pyYJu5MwpuvL(4Jt^;@Zds*4--;o7!hGb zhXE*NY^eTmBS(oB6?(L&=c7iGAWuS^pfcskmM9yb6uAHa?-Cn&CRstAIcraeMd=cxdx>)gHwv9o$#TZy}VZx8sYOb4@>EFzp zBX1Tt`R-mKmkobj-Iujv*N{QmZJTu~>eRA3kJcSJx9Hxmck3-3^E8&!#DAM^&D<>G z+Jd38y?xoY)8N4KUVr}gdh+d-absWpy18fW+`nTLjNJPA^6<|)H>=+Eaq-&U#~#m{ zypDX&^&v)GVeXkHT!DjB<}AXfr|5Jo7W2MNMedC60l;3FM=53h$yBwV~aH6$l{GU`lX|dHNtpbbwLXGV~It|m}HJX?zrTS tJmMH-i+)LX;f7dd$zX*LUa94mU}E6lm}Hh|=9y@wspgt&wpnHZ06R(VYxDpB literal 0 HcmV?d00001 diff --git a/src/actions/save-logo.ts b/src/actions/save-logo.ts index 83017393..76863102 100644 --- a/src/actions/save-logo.ts +++ b/src/actions/save-logo.ts @@ -1,12 +1,12 @@ "use server"; import { revalidatePath } from "next/cache"; -import { writeFile } from "fs/promises"; +import { mkdir, writeFile } from "fs/promises"; import path from "path"; import { prisma } from "@/lib/prisma"; import { siteSettings } from "@/lib/services/site-settings"; -const MEDIA_DIR = "public/assets/images/media"; +const MEDIA_DIR = "public/assets/images/media/logo"; export async function saveLogo(formData: FormData): Promise<{ success: boolean; url?: string; error?: string }> { try { @@ -20,9 +20,10 @@ export async function saveLogo(formData: FormData): Promise<{ success: boolean; const filePath = path.join(dir, filename); const buffer = Buffer.from(await file.arrayBuffer()); + await mkdir(dir, { recursive: true }); await writeFile(filePath, buffer); - const url = `/api/media/${filename}`; + const url = `/api/media/logo/${filename}`; await prisma.websiteSetting.upsert({ where: { key: "cms_logo" }, @@ -53,9 +54,10 @@ export async function saveLogoFromUrl(gifUrl: string): Promise<{ success: boolea const dir = path.join(process.cwd(), MEDIA_DIR); const filePath = path.join(dir, filename); + await mkdir(dir, { recursive: true }); await writeFile(filePath, buffer); - const url = `/api/media/${filename}`; + const url = `/api/media/logo/${filename}`; await prisma.websiteSetting.upsert({ where: { key: "cms_logo" }, diff --git a/src/app/api/media/[name]/route.ts b/src/app/api/media/[...path]/route.ts similarity index 86% rename from src/app/api/media/[name]/route.ts rename to src/app/api/media/[...path]/route.ts index 29a592c9..4fba7460 100644 --- a/src/app/api/media/[name]/route.ts +++ b/src/app/api/media/[...path]/route.ts @@ -10,11 +10,12 @@ const ALLOWED_EXT = [".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".bmp"]; export async function GET( _request: Request, - { params }: { params: Promise<{ name: string }> }, + { params }: { params: Promise<{ path: string[] }> }, ) { - const { name } = await params; + const { path: segments } = await params; + const name = segments.join("/"); // Prevent path traversal - if (name.includes("..") || name.includes("/") || name.includes("\\")) { + if (name.includes("..") || name.includes("\\")) { return new NextResponse("Forbidden", { status: 403 }); } const ext = path.extname(name).toLowerCase(); diff --git a/src/components/top-header.tsx b/src/components/top-header.tsx index 52746cb5..1f16abdd 100644 --- a/src/components/top-header.tsx +++ b/src/components/top-header.tsx @@ -76,10 +76,13 @@ export async function TopHeader() { Commandocentrum - - Logs - - + + Logs + + + Logo generator + + ) : null}