diff --git a/packages/plugin-multi-tenant/src/filters/filterDocumentsByTenants.ts b/packages/plugin-multi-tenant/src/filters/filterDocumentsByTenants.ts index bbf4c75e7..533320e18 100644 --- a/packages/plugin-multi-tenant/src/filters/filterDocumentsByTenants.ts +++ b/packages/plugin-multi-tenant/src/filters/filterDocumentsByTenants.ts @@ -1,24 +1,30 @@ -import type { PayloadRequest, Where } from 'payload' +import type { PayloadRequest, TypedUser, Where } from 'payload' + +import type { MultiTenantPluginConfig } from '../types.js' import { defaults } from '../defaults.js' import { getCollectionIDType } from '../utilities/getCollectionIDType.js' import { getTenantFromCookie } from '../utilities/getTenantFromCookie.js' import { getUserTenantIDs } from '../utilities/getUserTenantIDs.js' -type Args = { +type Args = { filterFieldName: string req: PayloadRequest tenantsArrayFieldName?: string tenantsArrayTenantFieldName?: string tenantsCollectionSlug: string + userHasAccessToAllTenants: Required< + MultiTenantPluginConfig + >['userHasAccessToAllTenants'] } -export const filterDocumentsByTenants = ({ +export const filterDocumentsByTenants = ({ filterFieldName, req, tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName, tenantsCollectionSlug, -}: Args): null | Where => { + userHasAccessToAllTenants, +}: Args): null | Where => { const idType = getCollectionIDType({ collectionSlug: tenantsCollectionSlug, payload: req.payload, @@ -34,6 +40,15 @@ export const filterDocumentsByTenants = ({ } } + if ( + req.user && + userHasAccessToAllTenants( + req?.user as ConfigType extends { user: unknown } ? ConfigType['user'] : TypedUser, + ) + ) { + return null + } + // scope to user assigned tenants const userAssignedTenants = getUserTenantIDs(req.user, { tenantsArrayFieldName, diff --git a/packages/plugin-multi-tenant/src/index.ts b/packages/plugin-multi-tenant/src/index.ts index 0328a9fd3..48c3e95ea 100644 --- a/packages/plugin-multi-tenant/src/index.ts +++ b/packages/plugin-multi-tenant/src/index.ts @@ -116,12 +116,13 @@ export const multiTenantPlugin = adminUsersCollection.admin.baseFilter = combineFilters({ baseFilter, customFilter: (args) => - filterDocumentsByTenants({ + filterDocumentsByTenants({ filterFieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`, req: args.req, tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }), }) } @@ -176,6 +177,7 @@ export const multiTenantPlugin = tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }) if (pluginConfig.collections[foldersSlug]?.customTenantField !== true) { @@ -207,12 +209,13 @@ export const multiTenantPlugin = collection.admin.baseFilter = combineFilters({ baseFilter: collection.admin?.baseFilter ?? collection.admin?.baseListFilter, customFilter: (args) => - filterDocumentsByTenants({ + filterDocumentsByTenants({ filterFieldName: tenantFieldName, req: args.req, tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }), }) } @@ -279,6 +282,7 @@ export const multiTenantPlugin = tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }), }) } @@ -317,7 +321,7 @@ export const multiTenantPlugin = collection.endpoints = [ ...(collection.endpoints || []), - getTenantOptionsEndpoint({ + getTenantOptionsEndpoint({ tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, @@ -346,6 +350,7 @@ export const multiTenantPlugin = tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }) if (pluginConfig.collections[collection.slug]?.customTenantField !== true) { @@ -383,6 +388,7 @@ export const multiTenantPlugin = tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }), }) } diff --git a/packages/plugin-multi-tenant/src/utilities/addFilterOptionsToFields.ts b/packages/plugin-multi-tenant/src/utilities/addFilterOptionsToFields.ts index cbf9b9896..384d5f2b9 100644 --- a/packages/plugin-multi-tenant/src/utilities/addFilterOptionsToFields.ts +++ b/packages/plugin-multi-tenant/src/utilities/addFilterOptionsToFields.ts @@ -1,9 +1,11 @@ -import type { Block, Config, Field, RelationshipField, SanitizedConfig } from 'payload' +import type { Block, Config, Field, RelationshipField, SanitizedConfig, TypedUser } from 'payload' + +import type { MultiTenantPluginConfig } from '../types.js' import { defaults } from '../defaults.js' import { filterDocumentsByTenants } from '../filters/filterDocumentsByTenants.js' -type AddFilterOptionsToFieldsArgs = { +type AddFilterOptionsToFieldsArgs = { blockReferencesWithFilters: string[] config: Config | SanitizedConfig fields: Field[] @@ -13,9 +15,12 @@ type AddFilterOptionsToFieldsArgs = { tenantsArrayFieldName: string tenantsArrayTenantFieldName: string tenantsCollectionSlug: string + userHasAccessToAllTenants: Required< + MultiTenantPluginConfig + >['userHasAccessToAllTenants'] } -export function addFilterOptionsToFields({ +export function addFilterOptionsToFields({ blockReferencesWithFilters, config, fields, @@ -25,7 +30,8 @@ export function addFilterOptionsToFields({ tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName, tenantsCollectionSlug, -}: AddFilterOptionsToFieldsArgs) { + userHasAccessToAllTenants, +}: AddFilterOptionsToFieldsArgs) { fields.forEach((field) => { if (field.type === 'relationship') { /** @@ -46,6 +52,7 @@ export function addFilterOptionsToFields({ tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }) } } else { @@ -63,6 +70,7 @@ export function addFilterOptionsToFields({ tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }) } }) @@ -85,6 +93,7 @@ export function addFilterOptionsToFields({ tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }) } @@ -113,6 +122,7 @@ export function addFilterOptionsToFields({ tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }) } }) @@ -130,28 +140,33 @@ export function addFilterOptionsToFields({ tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }) }) } }) } -type AddFilterArgs = { +type AddFilterArgs = { field: RelationshipField tenantEnabledCollectionSlugs: string[] tenantFieldName: string tenantsArrayFieldName: string tenantsArrayTenantFieldName: string tenantsCollectionSlug: string + userHasAccessToAllTenants: Required< + MultiTenantPluginConfig + >['userHasAccessToAllTenants'] } -function addFilter({ +function addFilter({ field, tenantEnabledCollectionSlugs, tenantFieldName, tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName, tenantsCollectionSlug, -}: AddFilterArgs) { + userHasAccessToAllTenants, +}: AddFilterArgs) { // User specified filter const originalFilter = field.filterOptions field.filterOptions = async (args) => { @@ -175,6 +190,7 @@ function addFilter({ tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, + userHasAccessToAllTenants, }) // If the tenant filter returns null, meaning no tenant filter, just use the original filter