fix: error accessing sanitizedPermissions during docAccess operation: "Cannot read properties of undefined" (#13800)

Fixes #12924

### What?

If an access check request resulted in no access to a doc, then the
sanitizer will remove even the `collections` field from the sanitized
permissions. This throws a server error when the `collections` field is
attempted to be accessed with some collection slug. The error is "Cannot
read properties of undefined".

### Why?

An example of how this might come about:
I am using multi-tenancy. I have some conditions about which users can
see other user's information (do they share any tenants). One workflow
is such that a "super admin" (user A) of a tenant removes an "admin"
(user B) inside their tenant. This is done by removing the tenant from
the user's list. After user A's update succeeds, payload defaults to
trying to reload user B's page. However, the two no longer share a
tenant. The access controls correctly evaluate that user A should no
longer be able to see/update/etc user B, but there is a bug in how the
objects are handled (see below).

The sanitizer removes the .collections field from the
sanitizedPermissions, so we get a server error about the key missing
"Cannot read properties of undefined (reading 'users')" in my case.

### How?

Instead of immediately keying into the sanitizedPermissions, we see if
the collections exist. If not, we make sure to return a well-defined
object with no permissions.

Before:

```ts
return sanitizedPermissions.collections![config.slug]!
```

After:

```ts
const collectionPermissions = sanitizedPermissions?.collections?.[config.slug]
return collectionPermissions ?? { fields: {} }
```

---------

Co-authored-by: Alessio Gravili <alessio@gravili.de>
This commit is contained in:
BrannanKovachev
2025-09-15 00:06:20 -07:00
committed by GitHub
parent fce94d6802
commit c7795fa4a1
2 changed files with 4 additions and 2 deletions

View File

@@ -51,7 +51,8 @@ export async function docAccessOperation(args: Arguments): Promise<SanitizedColl
},
})
return sanitizedPermissions.collections![config.slug]!
const collectionPermissions = sanitizedPermissions?.collections?.[config.slug]
return collectionPermissions ?? { fields: {} }
} catch (e: unknown) {
await killTransaction(req)
throw e

View File

@@ -40,7 +40,8 @@ export const docAccessOperation = async (args: Arguments): Promise<SanitizedGlob
},
})
return sanitizedPermissions.globals![globalConfig.slug]!
const globalPermissions = sanitizedPermissions?.globals?.[globalConfig.slug]
return globalPermissions ?? { fields: {} }
} catch (e: unknown) {
await killTransaction(req)
throw e