fix: make SEO global read public to prevent 403 during admin SSR

The SEO Settings global had `read: ({ req: { user } }) => Boolean(user)`
which requires authentication. During admin panel server-side rendering
(after saves), the user context is not propagated to global reads,
causing a Forbidden error that crashes the entire page render.

SEO data is not sensitive, so public read access is appropriate.
Also removes temporary debug logging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-02-25 13:32:00 +00:00
parent 36823b2d9f
commit a77c2b747d
2 changed files with 4 additions and 42 deletions

View file

@ -17,18 +17,11 @@ export const SEOSettings: GlobalConfig = {
description: 'Globale SEO-Konfiguration und Schema.org Daten', description: 'Globale SEO-Konfiguration und Schema.org Daten',
}, },
access: { access: {
// Alle angemeldeten Benutzer können lesen // Öffentlich lesbar - SEO-Daten sind nicht sensitiv und werden
read: ({ req: { user } }) => { // beim Admin-Panel SSR benötigt (wo der User-Kontext fehlen kann)
const result = Boolean(user) read: () => true,
if (!result) console.log('[DEBUG:SEO] read ACCESS DENIED - no user')
return result
},
// Nur Super Admins können bearbeiten // Nur Super Admins können bearbeiten
update: ({ req: { user } }) => { update: ({ req: { user } }) => Boolean(user?.isSuperAdmin),
const result = Boolean(user?.isSuperAdmin)
console.log('[DEBUG:SEO] update access:', { email: user?.email, isSuperAdmin: user?.isSuperAdmin, result })
return result
},
}, },
fields: [ fields: [
// === META DEFAULTS === // === META DEFAULTS ===

View file

@ -131,37 +131,6 @@ const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename) const dirname = path.dirname(filename)
export default buildConfig({ export default buildConfig({
// DEBUG: Log all API requests that result in 403
onInit: async (payload) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const origFindGlobal = payload.findGlobal.bind(payload) as any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(payload as any).findGlobal = async (args: any) => {
try { return await origFindGlobal(args) } catch (err: any) {
if (err?.status === 403) console.log('[DEBUG:403] Global read FORBIDDEN:', { slug: args.slug, user: args.req?.user?.email || 'no user' })
throw err
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const origUpdate = payload.update.bind(payload) as any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(payload as any).update = async (args: any) => {
try { return await origUpdate(args) } catch (err: any) {
if (err?.status === 403) console.log('[DEBUG:403] Collection update FORBIDDEN:', { collection: args.collection, id: args.id, user: args.req?.user?.email || 'no user' })
throw err
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const origUpdateGlobal = payload.updateGlobal.bind(payload) as any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(payload as any).updateGlobal = async (args: any) => {
try { return await origUpdateGlobal(args) } catch (err: any) {
if (err?.status === 403) console.log('[DEBUG:403] Global update FORBIDDEN:', { slug: args.slug, user: args.req?.user?.email || 'no user' })
throw err
}
}
console.log('[DEBUG] 403 interceptors installed')
},
serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL || 'https://pl.porwoll.tech', serverURL: process.env.PAYLOAD_PUBLIC_SERVER_URL || 'https://pl.porwoll.tech',
admin: { admin: {
user: Users.slug, user: Users.slug,