#Access Rule Bypassed for Unpublished Video Content

5 messages · Page 1 of 1 (latest)

gentle doveBOT
#

Hey, I have a custom API route that queries some content like this:

payload.find({
          collection: 'video-content',
          where: { and: [{ topics: { in: [topicId] } }, ...preferenceFilter] },
          sort: '-publishedAt',
          limit: videoContentCount,
          page,
          select: videoContentDefaultPopulateOrSelect,
          req,
        }),

While manually testing, I noticed it returns a document marked UNPUBLISHED. I have an access rule for that video-content collection that filters non-published content:

if (user.collection === 'app-users') {
    return { _status: { equals: 'published' } }
  }

if the content has never been published before, it works as expected. But then, if I publish the document and then unpublish it, I get results.

I also tried using draft: true and I get the same data.

Does anyone know if this is a known issue or am I missing anything?

wanton cypressBOT
#

Original message from @gentle gate - Moved from #general message

#
wraith reef
#

Most likely you’re not hitting the bug you think you are - you’re seeing a mismatch between the “live” row Payload queries on find and what the admin labels as unpublished.

Two concrete checks:

  1. Local API find skips access.read unless you pass overrideAccess: false. If that’s off, your { _status: { equals: 'published' } } rule never runs. (If “never published” was filtered only by your own where, that would look like “access works” even when it doesn’t.)

  2. With drafts enabled, draft: true on read does not mean “only published.” It reads the latest row in the versions collection (see drafts docs). draft: false / omitted reads the main collection document.

The pattern “never published → hidden; published once → after unpublish still shows up” matches the documented write behavior: updates with draft: true and _status draft (or omitted) do not update the main collection after the doc exists - only the versions table. The main row can keep _status: 'published' while the admin/version UI shows a newer draft. A normal find (no draft: true) still queries that main row, so _status: { equals: 'published' } still matches.

gentle gate
#

Hey, thanks so much @wraith reef . To be honest, I didn't understand what you explained in the last paragraph...

But what you mentioned in makes total sense and that's actually the cuplit. Even though I was passing req to my query, overrideAccess was true (default value), so it wasn't going through the access rules. Once I set overrideAccess: false, then it goes through the access rules and filters only published content, indeed.

What you mentioned on 2. also makes sense to me now: I can get still a published document even with drat: true if the latest row in the versions collection is the published one.

Thanks so much!