From d207e5653e4b0748ee38f63f3f86d811e64fb1f6 Mon Sep 17 00:00:00 2001 From: Do Siki Date: Sat, 12 Sep 2026 00:41:42 +0200 Subject: [PATCH] fix(cms): make Partners.logo optional; fix Media read access (public site was broken) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User request: don't force a logo upload to save a Partner — allow saving name+url first, logo later. Removed `required: true` from Partners.ts logo field. The frontend (getPartners(), payload-content.ts) already filters out logo-less partners before rendering, so this is safe: a partner without a logo just doesn't show on the public site yet, nothing breaks. While verifying this live (create a partner without a logo, check the public homepage doesn't break), found a real, previously-undetected bug that predates this change: partner logos never actually loaded on the public site at all. Payload's default collection read access is "authenticated users only" (Boolean(user)), and Media.ts never overrode it — so GET /api/media/file/ always 403'd for anyone not logged into the admin. Next.js's image optimizer (/_next/image) fetches that URL server-side without forwarding the browser's admin session cookie, so it always got a 403 back, which it reports as "The requested resource isn't a valid image" (400) — the silently rendered as a broken image icon on the homepage the whole time. Fixed by adding `access: { read: () => true }` to Media.ts — write operations (create/update/delete) stay admin-only via Payload's default. Verified live in the browser: created a Partner with only name+url via the admin (saved successfully, no required-field error), confirmed it correctly does NOT appear on the public homepage (no logo yet), then deleted that test record. Separately, in a fresh unauthenticated tab, confirmed the existing Partner's logo now actually renders on /hu (previously a broken image icon) — curl-verified both /api/media/file/ and /_next/image?url=... return 200 without any auth. Zero console errors. Gate: tsc, lint, unit tests (51 passed), production build all green. Co-Authored-By: Claude Sonnet 5 --- proto/src/collections/Media.ts | 13 +++++++++++++ proto/src/collections/Partners.ts | 10 ++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/proto/src/collections/Media.ts b/proto/src/collections/Media.ts index 55f1d68..580de11 100644 --- a/proto/src/collections/Media.ts +++ b/proto/src/collections/Media.ts @@ -17,6 +17,19 @@ export const Media: CollectionConfig = { admin: { group: 'Média', }, + // WHY explicit public read access: Payload alapértelmezés szerint minden + // collection read-je csak bejelentkezett usernek engedélyezett + // (defaultAccess = Boolean(user)) — enélkül a /api/media/file/* + // REST route 403-at adott VOLNA vissza kijelentkezve, tehát a publikus + // oldalon a partner logók (Home) sosem töltődtek volna be (a Next.js + // image-optimizer szerver-oldali proxyja sem küld auth cookie-t). + // Valódi böngészős teszttel derült ki (MITHOME-89 óta jelen lévő hiba, + // csak eddig senki nem nézte meg közelről a renderelt -et). Write + // műveletek (create/update/delete) változatlanul csak bejelentkezett + // usernek engedélyezettek (Payload alapértelmezés). + access: { + read: () => true, + }, upload: { mimeTypes: ['image/*'], }, diff --git a/proto/src/collections/Partners.ts b/proto/src/collections/Partners.ts index 89fe7fc..24e4046 100644 --- a/proto/src/collections/Partners.ts +++ b/proto/src/collections/Partners.ts @@ -22,7 +22,13 @@ export const Partners: CollectionConfig = { name: 'logo', type: 'upload', relationTo: 'media', - required: true, + // WHY opcionális (felhasználói döntés): így elmenthető egy partner + // név+URL-lel, logó nélkül is — pl. amíg a logó előkészítése + // (remove.bg stb.) még folyamatban van. A frontend (getPartners, + // src/lib/payload-content.ts) eleve kiszűri a logó nélküli + // partnereket, tehát ilyenkor egyszerűen nem jelenik meg a publikus + // oldalon, amíg nincs logó feltöltve — nem törik el semmi. + // // WHY nincs beépített vágó/áttetszővé tevő szerkesztő: a régi CMS-ben // ez kliens-oldali canvas-logika volt (scripts/cms-logo-client.js), // amit tudatosan nem ültettünk át Payload admin komponensként — @@ -31,7 +37,7 @@ export const Partners: CollectionConfig = { // PNG-t kell feltölteni, azt egy külső eszközzel (pl. remove.bg) // előkészítve. admin: { - description: 'Már kész, átlátszó hátterű PNG-t tölts fel (pl. remove.bg-vel előkészítve) — az admin felület nem vág/forgat/tesz átlátszóvá.', + description: 'Már kész, átlátszó hátterű PNG-t tölts fel (pl. remove.bg-vel előkészítve) — az admin felület nem vág/forgat/tesz átlátszóvá. Logó nélkül is elmenthető a partner, de a publikus oldalon csak logóval jelenik meg.', }, }, ],