From 5503afdf292bda2eb2ca6e052d134985fbec769d Mon Sep 17 00:00:00 2001 From: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com> Date: Mon, 18 Nov 2024 10:47:57 -0500 Subject: [PATCH] fix: sanitize sub block field permissions correctly (#9296) Fixes https://github.com/payloadcms/payload/issues/9288 ### What? When a block had a subfield named `blocks`, sanitization would throw an error. ### Why? An incorrect check for the key of `"fields"` would then attempt to pass `data.blocks[key].fields` aka `data.blocks.fields.fields` to the next call of `areAllPermissionsTrue` which would be undefined. Instead if the key is `fields` it should pass `data.blocks[key]`. ### How? Remove the second `.fields` property accessor. --- packages/payload/src/auth/types.ts | 9 ++ .../src/utilities/sanitizePermissions.spec.ts | 94 +++++++++++++++++++ .../src/utilities/sanitizePermissions.ts | 2 +- 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/packages/payload/src/auth/types.ts b/packages/payload/src/auth/types.ts index 570dad10d6..d994f46a94 100644 --- a/packages/payload/src/auth/types.ts +++ b/packages/payload/src/auth/types.ts @@ -14,9 +14,18 @@ export type Permission = { export type FieldPermissions = { blocks?: { [blockSlug: string]: { + create: { + permission: boolean + } fields: { [fieldName: string]: FieldPermissions } + read: { + permission: boolean + } + update: { + permission: boolean + } } } create: { diff --git a/packages/payload/src/utilities/sanitizePermissions.spec.ts b/packages/payload/src/utilities/sanitizePermissions.spec.ts index cdadd8add5..a2875f90bf 100644 --- a/packages/payload/src/utilities/sanitizePermissions.spec.ts +++ b/packages/payload/src/utilities/sanitizePermissions.spec.ts @@ -157,6 +157,15 @@ describe('recursivelySanitizePermissions', () => { }, }, }, + create: { + permission: true, + }, + read: { + permission: true, + }, + update: { + permission: true, + }, }, }, read: { @@ -236,6 +245,15 @@ describe('recursivelySanitizePermissions', () => { }, }, }, + create: { + permission: true, + }, + read: { + permission: true, + }, + update: { + permission: true, + }, }, }, read: { @@ -267,6 +285,9 @@ describe('recursivelySanitizePermissions', () => { read: true, }, }, + create: true, + update: true, + read: true, }, }, read: true, @@ -349,6 +370,79 @@ describe('recursivelySanitizePermissions', () => { }) }) + it('should sanitize blocks with subfield named blocks', () => { + const permissions: CollectionPermission = { + fields: { + content: { + create: { permission: true }, + blocks: { + test: { + fields: { + blocks: { + create: { permission: true }, + fields: { + arrayText: { + create: { permission: true }, + read: { permission: true }, + update: { permission: true }, + }, + id: { + create: { permission: true }, + read: { permission: true }, + update: { permission: true }, + }, + }, + read: { permission: true }, + update: { permission: true }, + }, + id: { + create: { permission: true }, + read: { permission: true }, + update: { permission: true }, + }, + blockName: { + create: { permission: true }, + read: { permission: true }, + update: { permission: true }, + }, + }, + create: { permission: true }, + read: { permission: true }, + update: { permission: true }, + }, + }, + read: { permission: true }, + update: { permission: true }, + }, + }, + create: { + permission: true, + }, + read: { + permission: true, + }, + update: { + permission: true, + }, + delete: { + permission: false, + }, + readVersions: { + permission: true, + }, + } + + recursivelySanitizePermissions(permissions) + + expect(permissions).toStrictEqual({ + fields: true, + create: true, + read: true, + update: true, + readVersions: true, + }) + }) + it('should sanitize a collection with nested fields in richText', () => { const permissions: Partial = { fields: { diff --git a/packages/payload/src/utilities/sanitizePermissions.ts b/packages/payload/src/utilities/sanitizePermissions.ts index 474cad438c..68fb268eb5 100644 --- a/packages/payload/src/utilities/sanitizePermissions.ts +++ b/packages/payload/src/utilities/sanitizePermissions.ts @@ -12,7 +12,7 @@ function areAllPermissionsTrue(data: PermissionObject): boolean { for (const key in data.blocks) { if (typeof data.blocks[key] === 'object') { // If any recursive call returns false, the whole function returns false - if (key === 'fields' && !areAllPermissionsTrue(data.blocks[key].fields)) { + if (key === 'fields' && !areAllPermissionsTrue(data.blocks[key])) { return false } if (data.blocks[key].fields && !areAllPermissionsTrue(data.blocks[key].fields)) {