#Access to collection only through relationship

8 messages · Page 1 of 1 (latest)

solemn sparrow
#

Hello!

I have two collections in Payload: Author and Publications. Publications has a relationship field to the Author collection. Publications has public read access, the Author collection doesn't.

I can't seem to find a way to keep the public access for the Author collection private while still allowing the Publication collection to access the Author data as part of the relationship.

Is there an (easy) way to configure this? I tried my best using several hooks but I can't seem to get it to work.

split iris
#

Hey @solemn sparrow I really enjoy access control questions!

#

there are a couple of ways you could handle this

#

rather than blocking read access to the entire Author collection, allow the collection to be read publicly but restrict sensitive fields within it:

// Author collection
fields: [
  { name: 'name', type: 'text' }, // public
  { name: 'bio', type: 'text' },  // public
  {
    name: 'email',
    type: 'email',
    access: {
      read: ({ req }) => Boolean(req.user), // private fields
    },
  },
]
#

with the above approach, Publications can populate the Author relationship at any depth, public users see only safe fields, and sensitive fields are hidden unless authenticated

#

if the entire Author document must stay private but should still populate through Publications, you should be able to use an afterRead hook on Publications

#
// Publications collection
hooks: {
  afterRead: [
    async ({ doc, req }) => {
      if (doc.author && typeof doc.author !== 'object') {
        doc.author = await req.payload.findByID({
          collection: 'authors',
          id: doc.author,
          overrideAccess: true,
          depth: 0,
        })
      }
      return doc
    },
  ],
}