fix: querying by polymorphic join field relationTo with overrideAccess: false (#11999)
Previously, querying by polymorphic joins `relationTo` with `overrideAccess: false` caused an error: ``` QueryError: The following paths cannot be queried: relationTo ``` As this field actually doesn't exist in the schema. Now, under condition that the query comes from a polymorphic join we skip checking `relationTo` field access.
This commit is contained in:
@@ -13,6 +13,7 @@ type Args = {
|
|||||||
errors?: { path: string }[]
|
errors?: { path: string }[]
|
||||||
overrideAccess: boolean
|
overrideAccess: boolean
|
||||||
policies?: EntityPolicies
|
policies?: EntityPolicies
|
||||||
|
polymorphicJoin?: boolean
|
||||||
req: PayloadRequest
|
req: PayloadRequest
|
||||||
versionFields?: FlattenedField[]
|
versionFields?: FlattenedField[]
|
||||||
where: Where
|
where: Where
|
||||||
@@ -52,6 +53,7 @@ export async function validateQueryPaths({
|
|||||||
collections: {},
|
collections: {},
|
||||||
globals: {},
|
globals: {},
|
||||||
},
|
},
|
||||||
|
polymorphicJoin,
|
||||||
req,
|
req,
|
||||||
versionFields,
|
versionFields,
|
||||||
where,
|
where,
|
||||||
@@ -77,6 +79,7 @@ export async function validateQueryPaths({
|
|||||||
overrideAccess,
|
overrideAccess,
|
||||||
path,
|
path,
|
||||||
policies,
|
policies,
|
||||||
|
polymorphicJoin,
|
||||||
req,
|
req,
|
||||||
val,
|
val,
|
||||||
versionFields,
|
versionFields,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ type Args = {
|
|||||||
parentIsLocalized?: boolean
|
parentIsLocalized?: boolean
|
||||||
path: string
|
path: string
|
||||||
policies: EntityPolicies
|
policies: EntityPolicies
|
||||||
|
polymorphicJoin?: boolean
|
||||||
req: PayloadRequest
|
req: PayloadRequest
|
||||||
val: unknown
|
val: unknown
|
||||||
versionFields?: FlattenedField[]
|
versionFields?: FlattenedField[]
|
||||||
@@ -39,6 +40,7 @@ export async function validateSearchParam({
|
|||||||
parentIsLocalized,
|
parentIsLocalized,
|
||||||
path: incomingPath,
|
path: incomingPath,
|
||||||
policies,
|
policies,
|
||||||
|
polymorphicJoin,
|
||||||
req,
|
req,
|
||||||
val,
|
val,
|
||||||
versionFields,
|
versionFields,
|
||||||
@@ -102,6 +104,10 @@ export async function validateSearchParam({
|
|||||||
errors.push({ path })
|
errors.push({ path })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (polymorphicJoin && path === 'relationTo') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!overrideAccess && fieldAffectsData(field)) {
|
if (!overrideAccess && fieldAffectsData(field)) {
|
||||||
if (collectionSlug) {
|
if (collectionSlug) {
|
||||||
if (!policies.collections[collectionSlug]) {
|
if (!policies.collections[collectionSlug]) {
|
||||||
@@ -140,8 +146,10 @@ export async function validateSearchParam({
|
|||||||
const segments = fieldPath.split('.')
|
const segments = fieldPath.split('.')
|
||||||
|
|
||||||
let fieldAccess
|
let fieldAccess
|
||||||
|
|
||||||
if (versionFields) {
|
if (versionFields) {
|
||||||
fieldAccess = policies[entityType][entitySlug]
|
fieldAccess = policies[entityType][entitySlug]
|
||||||
|
|
||||||
if (segments[0] === 'parent' || segments[0] === 'version') {
|
if (segments[0] === 'parent' || segments[0] === 'version') {
|
||||||
segments.shift()
|
segments.shift()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// @ts-strict-ignore
|
// @ts-strict-ignore
|
||||||
import type { SanitizedCollectionConfig, SanitizedJoin } from '../collections/config/types.js'
|
import type { SanitizedCollectionConfig, SanitizedJoin } from '../collections/config/types.js'
|
||||||
|
import type { FlattenedField } from '../fields/config/types.js'
|
||||||
import type { JoinQuery, PayloadRequest } from '../types/index.js'
|
import type { JoinQuery, PayloadRequest } from '../types/index.js'
|
||||||
|
|
||||||
import executeAccess from '../auth/executeAccess.js'
|
import executeAccess from '../auth/executeAccess.js'
|
||||||
@@ -67,6 +68,7 @@ const sanitizeJoinFieldQuery = async ({
|
|||||||
collectionConfig: joinCollectionConfig,
|
collectionConfig: joinCollectionConfig,
|
||||||
errors,
|
errors,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
|
polymorphicJoin: Array.isArray(join.field.collection),
|
||||||
req,
|
req,
|
||||||
// incoming where input, but we shouldn't validate generated from the access control.
|
// incoming where input, but we shouldn't validate generated from the access control.
|
||||||
where: joinQuery.where,
|
where: joinQuery.where,
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ export default buildConfigWithDefaults({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: 'multiple-collections-parents',
|
slug: 'multiple-collections-parents',
|
||||||
|
access: { read: () => true },
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
type: 'join',
|
type: 'join',
|
||||||
@@ -236,6 +237,7 @@ export default buildConfigWithDefaults({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: 'multiple-collections-1',
|
slug: 'multiple-collections-1',
|
||||||
|
access: { read: () => true },
|
||||||
admin: { useAsTitle: 'title' },
|
admin: { useAsTitle: 'title' },
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@@ -255,6 +257,7 @@ export default buildConfigWithDefaults({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: 'multiple-collections-2',
|
slug: 'multiple-collections-2',
|
||||||
|
access: { read: () => true },
|
||||||
admin: { useAsTitle: 'title' },
|
admin: { useAsTitle: 'title' },
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1389,7 +1389,7 @@ describe('Joins Field', () => {
|
|||||||
expect(parent.children?.docs).toHaveLength(1)
|
expect(parent.children?.docs).toHaveLength(1)
|
||||||
expect(parent.children.docs[0]?.value.title).toBe('doc-1')
|
expect(parent.children.docs[0]?.value.title).toBe('doc-1')
|
||||||
|
|
||||||
// WHERE by _relationTo (join for specific collectionSlug)
|
// WHERE by relationTo (join for specific collectionSlug)
|
||||||
parent = await payload.findByID({
|
parent = await payload.findByID({
|
||||||
collection: 'multiple-collections-parents',
|
collection: 'multiple-collections-parents',
|
||||||
id: parent.id,
|
id: parent.id,
|
||||||
@@ -1405,6 +1405,23 @@ describe('Joins Field', () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// WHERE by relationTo with overrideAccess:false
|
||||||
|
parent = await payload.findByID({
|
||||||
|
collection: 'multiple-collections-parents',
|
||||||
|
id: parent.id,
|
||||||
|
overrideAccess: false,
|
||||||
|
depth: 1,
|
||||||
|
joins: {
|
||||||
|
children: {
|
||||||
|
where: {
|
||||||
|
relationTo: {
|
||||||
|
equals: 'multiple-collections-2',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
expect(parent.children?.docs).toHaveLength(1)
|
expect(parent.children?.docs).toHaveLength(1)
|
||||||
expect(parent.children.docs[0]?.value.title).toBe('doc-2')
|
expect(parent.children.docs[0]?.value.title).toBe('doc-2')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user