teqo-backup/src/globals/Metadata.ts
Cursor Agent 6705db80eb security: lock public globals update to payloadAdminOnly (Pass 4 P0)
The four public globals (site-settings, home, metadata, privacy-policy)
spelled update access as "any authenticated user" — and campaign JWTs
authenticate against /api/*, so any campaign session (leader included)
could PATCH the public site. payloadAdminOnly matches the collection
lockdown precedent; editors lose config-global writes deliberately
(content editing stays on canManagePublishedContent collections).

Pins: identity + deny (coordinator/editor) + allow (admin fn) + anonymous
read in collectionAccessLockdown.int.spec.ts. Recurrence guard:
globalAccessConventions.unit.spec.ts bans the Boolean(user) shape in
src/globals.

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-07-31 20:57:18 -03:00

101 lines
2 KiB
TypeScript

import { payloadAdminOnly } from '@/utilities/campaignAccess'
import { revalidateGlobal } from '@/utilities/globals'
import { GlobalConfig } from 'payload'
const slug = 'metadata'
const revalidate = async () => revalidateGlobal(slug)
export const Metadata: GlobalConfig = {
slug,
label: 'Metadados',
admin: {
group: 'Configurações',
},
access: {
read: () => true,
// Admin-only like the other site globals (Pass 4) — campaign JWTs reach /api/*.
update: payloadAdminOnly,
},
hooks: {
afterChange: [revalidate],
},
fields: [
{
name: 'URL',
label: 'URL',
type: 'text',
required: true,
},
{
name: 'title',
label: 'Título',
type: 'text',
required: true,
},
{
name: 'description',
label: 'Descrição',
type: 'textarea',
required: true,
},
{
name: 'keywords',
label: 'Palavras-chave',
type: 'array',
required: true,
fields: [
{
name: 'keyword',
label: 'Palavra-chave',
type: 'text',
required: true,
},
],
},
{
name: 'openGraph',
label: 'Open Graph',
type: 'group',
fields: [
{
name: 'siteName',
label: 'Nome do Site',
type: 'text',
required: true,
},
{
name: 'description',
label: 'Descrição',
type: 'textarea',
required: true,
},
],
},
{
name: 'twitter',
label: 'Twitter',
type: 'group',
fields: [
{
name: 'creator',
label: 'Criador',
type: 'text',
required: true,
},
{
name: 'description',
label: 'Descrição',
type: 'textarea',
required: true,
},
],
},
{
name: 'image',
label: 'Imagem',
type: 'upload',
relationTo: 'media',
},
],
}