teqo/src/collections/Users.ts
Francisco Ignácio Fontoura Solla 473c82d09d Lock down CMS/PII collection access and leader routes
- users/signature/subscription/consent: all operations Payload-admin-only
  (Payload's default allowed ANY authenticated user, incl. campaign JWTs
  via /api — privilege escalation + PII exposure)
- post/tag/media/petition: public read kept, writes admin-only,
  readVersions admin-only on drafted collections
- leader lockdown: staff gates on /campanha/demandas* and /campanha/planos*;
  removed the dead leader branch of the demand detail page
- fix createLeaderSupporter: scope now asserted via the leader's engaged
  leadership municipalities (canReadMunicipality always denied leaders)
- candidate alignment: supporter area, invite creation, and escalated
  demand decisions now treat candidate as unrestricted staff consistently
- tests: collectionAccessLockdown.int.spec pins the lockdown; leased-consent
  helpers generalized (supporter keys); fixtures purge deletes residue
  invites before leaderships; stale leader-phone tests updated to the
  lockdown model; 'sem Praça' copy renamed to 'sem município'
2026-07-23 22:25:18 -03:00

30 lines
848 B
TypeScript

import { isPayloadAdmin, payloadAdminOnly } from '@/utilities/campaignAccess'
import type { CollectionConfig } from 'payload'
export const Users: CollectionConfig = {
slug: 'users',
labels: {
singular: 'Usuário',
plural: 'Usuários',
},
admin: {
group: 'Coleções',
useAsTitle: 'email',
},
auth: true,
// Admin accounts are managed only by admin accounts. Without this, Payload's
// "any authenticated user" default would let a campaignUser JWT manage admins
// through /api/users — a privilege-escalation path.
access: {
admin: ({ req }) => isPayloadAdmin(req.user),
create: payloadAdminOnly,
read: payloadAdminOnly,
update: payloadAdminOnly,
delete: payloadAdminOnly,
unlock: payloadAdminOnly,
},
fields: [
// Email added by default
// Add more fields as needed
],
}