mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-14 17:43:04 +00:00
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>
95 lines
2.4 KiB
TypeScript
95 lines
2.4 KiB
TypeScript
import { payloadAdminOnly } from '@/utilities/campaignAccess'
|
|
import { revalidateGlobal } from '@/utilities/globals'
|
|
import type { GlobalConfig } from 'payload'
|
|
|
|
const slug = 'site-settings'
|
|
|
|
const revalidate = async () => revalidateGlobal(slug)
|
|
|
|
export const SiteSettings: GlobalConfig = {
|
|
slug,
|
|
label: 'Configurações do site',
|
|
admin: {
|
|
group: 'Configurações',
|
|
},
|
|
access: {
|
|
read: () => true,
|
|
// Site-wide config: campaign JWTs authenticate against /api/*, so "any
|
|
// authenticated user" here was a write path into the public site (Pass 4).
|
|
update: payloadAdminOnly,
|
|
},
|
|
hooks: {
|
|
afterChange: [revalidate],
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'headerTitle',
|
|
type: 'text',
|
|
label: 'Título do cabeçalho',
|
|
},
|
|
{
|
|
name: 'socialLinks',
|
|
type: 'array',
|
|
label: 'Redes sociais',
|
|
labels: {
|
|
singular: 'Rede social',
|
|
plural: 'Redes sociais',
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'platform',
|
|
type: 'select',
|
|
label: 'Plataforma',
|
|
required: true,
|
|
options: [
|
|
{ label: 'Instagram', value: 'instagram' },
|
|
{ label: 'Facebook', value: 'facebook' },
|
|
{ label: 'YouTube', value: 'youtube' },
|
|
{ label: 'WhatsApp', value: 'whatsapp' },
|
|
],
|
|
},
|
|
{
|
|
name: 'url',
|
|
type: 'text',
|
|
label: 'URL',
|
|
required: true,
|
|
validate: (value: string | null | undefined) => {
|
|
if (!value) return 'A URL é obrigatória'
|
|
try {
|
|
const parsed = new URL(value)
|
|
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
return 'A URL deve começar com http:// ou https://'
|
|
}
|
|
return true
|
|
} catch {
|
|
return 'Informe uma URL válida'
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: 'label',
|
|
type: 'text',
|
|
label: 'Rótulo de acessibilidade',
|
|
admin: {
|
|
description:
|
|
'Rótulo opcional para acessibilidade. Se estiver vazio, usamos um rótulo padrão da plataforma.',
|
|
},
|
|
},
|
|
{
|
|
name: 'enabled',
|
|
type: 'checkbox',
|
|
label: 'Ativo',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
versions: {
|
|
drafts: {
|
|
autosave: {
|
|
interval: 1000,
|
|
},
|
|
schedulePublish: true,
|
|
},
|
|
max: 10,
|
|
},
|
|
}
|