Files
ipal-kit/src/globals/SiteIntegrations/index.ts
T

57 lines
1.9 KiB
TypeScript

import type { Field, GlobalConfig } from 'payload'
import { isAdmin } from '../../modules/access/index.js'
import { analyticsFields } from './fields/analytics.js'
import { smtpFields } from './fields/smtp.js'
import { turnstileFields } from './fields/turnstile.js'
type BuildSiteIntegrationsArgs = {
/** Extra fields injected by the client project */
additionalFields?: Field[]
}
/**
* Builds the SiteIntegrations global.
*
* Holds third-party service credentials. Access is enforced at the global
* level — the whole global requires an authenticated user — so secrets stay
* out of anonymous API responses while remaining editable in the admin panel
* and readable via the server-side Local API. (Field-level read:false was
* avoided because it also hides fields from the admin UI, making them
* impossible to enter.)
*
* Unnamed tabs keep data flat (siteIntegrations.ga4MeasurementId).
*
* Note: R2 storage credentials are NOT here — storage is infrastructure and
* binds at boot, so its config lives in .env (R2_BUCKET, R2_ENDPOINT, ...),
* consumed by buildR2Storage. See docs/storage.md.
*/
export function buildSiteIntegrations({
additionalFields,
}: BuildSiteIntegrationsArgs = {}): GlobalConfig {
return {
slug: 'site-integrations',
access: {
// Admin-only — secrets live here. Anonymous and non-admin users get
// nothing through the API; admins read/edit in the panel and via Local API.
read: ({ req: { user } }) => isAdmin(user),
update: ({ req: { user } }) => isAdmin(user),
},
admin: {
group: 'Settings',
},
fields: [
{
type: 'tabs',
tabs: [
{ fields: analyticsFields, label: 'Analytics' },
{ fields: turnstileFields, label: 'Turnstile' },
{ fields: smtpFields, label: 'SMTP' },
...(additionalFields?.length ? [{ fields: additionalFields, label: 'Custom' }] : []),
],
},
],
label: 'Site Integrations',
}
}