@payloadcms/plugin-multi-tenant 3.60.0-canary.1 → 3.60.0-canary.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/tenantField/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqC,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAEzF,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAA;AAwBpE,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,8BAA8B,CAAA;IAC1C,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AACD,eAAO,MAAM,WAAW,+HAQrB,IAAI,KAAG,uBAmFT,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fields/tenantField/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA+B,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAEnF,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAA;AA8BpE,KAAK,IAAI,GAAG;IACV,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,8BAA8B,CAAA;IAC1C,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AACD,eAAO,MAAM,WAAW,+HAQrB,IAAI,KAAG,uBA2FT,CAAA"}
@@ -9,13 +9,19 @@ const fieldValidation = (validateFunction)=>(value, options)=>{
9
9
  return result;
10
10
  }
11
11
  }
12
- if (!value) {
13
- return options.req.t('validation:required');
12
+ if (options.hasMany) {
13
+ if (!value || Array.isArray(value) && value.length === 0) {
14
+ return options.req.t('validation:required');
15
+ }
16
+ } else {
17
+ if (!value) {
18
+ return options.req.t('validation:required');
19
+ }
14
20
  }
15
21
  return true;
16
22
  };
17
23
  export const tenantField = ({ name = defaults.tenantFieldName, debug, overrides: _overrides = {}, tenantsArrayFieldName = defaults.tenantsArrayFieldName, tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName, tenantsCollectionSlug = defaults.tenantCollectionSlug, unique })=>{
18
- const { validate, ...overrides } = _overrides || {};
24
+ const { hasMany = false, validate, ...overrides } = _overrides || {};
19
25
  return {
20
26
  ...overrides || {},
21
27
  name,
@@ -57,7 +63,9 @@ export const tenantField = ({ name = defaults.tenantFieldName, debug, overrides:
57
63
  user: req.user,
58
64
  where: {
59
65
  id: {
60
- equals: tenantFromCookie
66
+ in: [
67
+ tenantFromCookie
68
+ ]
61
69
  }
62
70
  }
63
71
  });
@@ -79,12 +87,18 @@ export const tenantField = ({ name = defaults.tenantFieldName, debug, overrides:
79
87
  }
80
88
  return true;
81
89
  }),
82
- hasMany: false,
83
90
  index: true,
84
91
  relationTo: tenantsCollectionSlug,
85
92
  unique,
86
- // TODO: V4 - replace validation with required: true
87
- validate: fieldValidation(validate),
93
+ ...hasMany ? {
94
+ hasMany: true,
95
+ // TODO: V4 - replace validation with required: true
96
+ validate: fieldValidation(validate)
97
+ } : {
98
+ hasMany: false,
99
+ // TODO: V4 - replace validation with required: true
100
+ validate: fieldValidation(validate)
101
+ },
88
102
  // @ts-expect-error translations are not typed for this plugin
89
103
  label: overrides.label || (({ t })=>t('plugin-multi-tenant:field-assignedTenant-label'))
90
104
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/fields/tenantField/index.ts"],"sourcesContent":["import type { RelationshipFieldSingleValidation, SingleRelationshipField } from 'payload'\n\nimport type { RootTenantFieldConfigOverrides } from '../../types.js'\n\nimport { defaults } from '../../defaults.js'\nimport { getCollectionIDType } from '../../utilities/getCollectionIDType.js'\nimport { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js'\nimport { getUserTenantIDs } from '../../utilities/getUserTenantIDs.js'\n\nconst fieldValidation =\n (validateFunction?: RelationshipFieldSingleValidation): RelationshipFieldSingleValidation =>\n (value, options) => {\n if (validateFunction) {\n const result = validateFunction(value, options)\n if (result !== true) {\n return result\n }\n }\n\n if (!value) {\n return options.req.t('validation:required')\n }\n\n return true\n }\n\ntype Args = {\n debug?: boolean\n name: string\n overrides?: RootTenantFieldConfigOverrides\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n unique: boolean\n}\nexport const tenantField = ({\n name = defaults.tenantFieldName,\n debug,\n overrides: _overrides = {},\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n tenantsCollectionSlug = defaults.tenantCollectionSlug,\n unique,\n}: Args): SingleRelationshipField => {\n const { validate, ...overrides } = _overrides || {}\n return {\n ...(overrides || {}),\n name,\n type: 'relationship',\n access: overrides.access || {},\n admin: {\n allowCreate: false,\n allowEdit: false,\n disableGroupBy: true,\n disableListColumn: true,\n disableListFilter: true,\n position: 'sidebar',\n ...(overrides.admin || {}),\n components: {\n ...(overrides.admin?.components || {}),\n Field: {\n path: '@payloadcms/plugin-multi-tenant/client#TenantField',\n ...(typeof overrides.admin?.components?.Field !== 'string'\n ? overrides.admin?.components?.Field || {}\n : {}),\n clientProps: {\n ...(typeof overrides.admin?.components?.Field !== 'string'\n ? (overrides.admin?.components?.Field || {})?.clientProps\n : {}),\n debug,\n unique,\n },\n },\n },\n },\n defaultValue:\n overrides.defaultValue ||\n (async ({ req }) => {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload: req.payload,\n })\n const tenantFromCookie = getTenantFromCookie(req.headers, idType)\n if (tenantFromCookie) {\n const isValidTenant = await req.payload.count({\n collection: tenantsCollectionSlug,\n depth: 0,\n overrideAccess: false,\n req,\n user: req.user,\n where: {\n id: {\n equals: tenantFromCookie,\n },\n },\n })\n return isValidTenant ? tenantFromCookie : null\n }\n return null\n }),\n filterOptions:\n overrides.filterOptions ||\n (({ req }) => {\n const userAssignedTenants = getUserTenantIDs(req.user, {\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n })\n if (userAssignedTenants.length > 0) {\n return {\n id: {\n in: userAssignedTenants,\n },\n }\n }\n\n return true\n }),\n hasMany: false,\n index: true,\n relationTo: tenantsCollectionSlug,\n unique,\n // TODO: V4 - replace validation with required: true\n validate: fieldValidation(validate as RelationshipFieldSingleValidation),\n // @ts-expect-error translations are not typed for this plugin\n label: overrides.label || (({ t }) => t('plugin-multi-tenant:field-assignedTenant-label')),\n }\n}\n"],"names":["defaults","getCollectionIDType","getTenantFromCookie","getUserTenantIDs","fieldValidation","validateFunction","value","options","result","req","t","tenantField","name","tenantFieldName","debug","overrides","_overrides","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","tenantCollectionSlug","unique","validate","type","access","admin","allowCreate","allowEdit","disableGroupBy","disableListColumn","disableListFilter","position","components","Field","path","clientProps","defaultValue","idType","collectionSlug","payload","tenantFromCookie","headers","isValidTenant","count","collection","depth","overrideAccess","user","where","id","equals","filterOptions","userAssignedTenants","length","in","hasMany","index","relationTo","label"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/fields/tenantField/index.ts"],"sourcesContent":["import type { RelationshipFieldValidation, SingleRelationshipField } from 'payload'\n\nimport type { RootTenantFieldConfigOverrides } from '../../types.js'\n\nimport { defaults } from '../../defaults.js'\nimport { getCollectionIDType } from '../../utilities/getCollectionIDType.js'\nimport { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js'\nimport { getUserTenantIDs } from '../../utilities/getUserTenantIDs.js'\n\nconst fieldValidation =\n (validateFunction?: RelationshipFieldValidation): RelationshipFieldValidation =>\n (value, options) => {\n if (validateFunction) {\n const result = validateFunction(value, options)\n if (result !== true) {\n return result\n }\n }\n\n if (options.hasMany) {\n if (!value || (Array.isArray(value) && value.length === 0)) {\n return options.req.t('validation:required')\n }\n } else {\n if (!value) {\n return options.req.t('validation:required')\n }\n }\n\n return true\n }\n\ntype Args = {\n debug?: boolean\n name: string\n overrides?: RootTenantFieldConfigOverrides\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n unique: boolean\n}\nexport const tenantField = ({\n name = defaults.tenantFieldName,\n debug,\n overrides: _overrides = {},\n tenantsArrayFieldName = defaults.tenantsArrayFieldName,\n tenantsArrayTenantFieldName = defaults.tenantsArrayTenantFieldName,\n tenantsCollectionSlug = defaults.tenantCollectionSlug,\n unique,\n}: Args): SingleRelationshipField => {\n const { hasMany = false, validate, ...overrides } = _overrides || {}\n return {\n ...(overrides || {}),\n name,\n type: 'relationship',\n access: overrides.access || {},\n admin: {\n allowCreate: false,\n allowEdit: false,\n disableGroupBy: true,\n disableListColumn: true,\n disableListFilter: true,\n position: 'sidebar',\n ...(overrides.admin || {}),\n components: {\n ...(overrides.admin?.components || {}),\n Field: {\n path: '@payloadcms/plugin-multi-tenant/client#TenantField',\n ...(typeof overrides.admin?.components?.Field !== 'string'\n ? overrides.admin?.components?.Field || {}\n : {}),\n clientProps: {\n ...(typeof overrides.admin?.components?.Field !== 'string'\n ? (overrides.admin?.components?.Field || {})?.clientProps\n : {}),\n debug,\n unique,\n },\n },\n },\n },\n defaultValue:\n overrides.defaultValue ||\n (async ({ req }) => {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload: req.payload,\n })\n const tenantFromCookie = getTenantFromCookie(req.headers, idType)\n if (tenantFromCookie) {\n const isValidTenant = await req.payload.count({\n collection: tenantsCollectionSlug,\n depth: 0,\n overrideAccess: false,\n req,\n user: req.user,\n where: {\n id: {\n in: [tenantFromCookie],\n },\n },\n })\n return isValidTenant ? tenantFromCookie : null\n }\n return null\n }),\n filterOptions:\n overrides.filterOptions ||\n (({ req }) => {\n const userAssignedTenants = getUserTenantIDs(req.user, {\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n })\n if (userAssignedTenants.length > 0) {\n return {\n id: {\n in: userAssignedTenants,\n },\n }\n }\n\n return true\n }),\n index: true,\n relationTo: tenantsCollectionSlug,\n unique,\n ...(hasMany\n ? {\n hasMany: true,\n // TODO: V4 - replace validation with required: true\n validate: fieldValidation(validate as RelationshipFieldValidation),\n }\n : {\n hasMany: false,\n // TODO: V4 - replace validation with required: true\n validate: fieldValidation(validate as RelationshipFieldValidation),\n }),\n // @ts-expect-error translations are not typed for this plugin\n label: overrides.label || (({ t }) => t('plugin-multi-tenant:field-assignedTenant-label')),\n }\n}\n"],"names":["defaults","getCollectionIDType","getTenantFromCookie","getUserTenantIDs","fieldValidation","validateFunction","value","options","result","hasMany","Array","isArray","length","req","t","tenantField","name","tenantFieldName","debug","overrides","_overrides","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","tenantCollectionSlug","unique","validate","type","access","admin","allowCreate","allowEdit","disableGroupBy","disableListColumn","disableListFilter","position","components","Field","path","clientProps","defaultValue","idType","collectionSlug","payload","tenantFromCookie","headers","isValidTenant","count","collection","depth","overrideAccess","user","where","id","in","filterOptions","userAssignedTenants","index","relationTo","label"],"mappings":"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"}
@@ -45,7 +45,9 @@ export const afterTenantDelete = ({ enabledSlugs, tenantFieldName, tenantsCollec
45
45
  collection: slug,
46
46
  where: {
47
47
  [tenantFieldName]: {
48
- equals: id
48
+ in: [
49
+ id
50
+ ]
49
51
  }
50
52
  }
51
53
  }));
@@ -57,7 +59,9 @@ export const afterTenantDelete = ({ enabledSlugs, tenantFieldName, tenantsCollec
57
59
  limit: 0,
58
60
  where: {
59
61
  [`${usersTenantsArrayFieldName}.${usersTenantsArrayTenantFieldName}`]: {
60
- equals: id
62
+ in: [
63
+ id
64
+ ]
61
65
  }
62
66
  }
63
67
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/afterTenantDelete.ts"],"sourcesContent":["import type {\n CollectionAfterDeleteHook,\n CollectionConfig,\n JsonObject,\n PaginatedDocs,\n} from 'payload'\n\nimport { generateCookie, mergeHeaders } from 'payload'\n\nimport type { UserWithTenantsField } from '../types.js'\n\nimport { getCollectionIDType } from '../utilities/getCollectionIDType.js'\nimport { getTenantFromCookie } from '../utilities/getTenantFromCookie.js'\n\ntype Args = {\n collection: CollectionConfig\n enabledSlugs: string[]\n tenantFieldName: string\n tenantsCollectionSlug: string\n usersSlug: string\n usersTenantsArrayFieldName: string\n usersTenantsArrayTenantFieldName: string\n}\n/**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\nexport const addTenantCleanup = ({\n collection,\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n}: Args) => {\n if (!collection.hooks) {\n collection.hooks = {}\n }\n if (!collection.hooks?.afterDelete) {\n collection.hooks.afterDelete = []\n }\n collection.hooks.afterDelete.push(\n afterTenantDelete({\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n }),\n )\n}\n\nexport const afterTenantDelete =\n ({\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n }: Omit<Args, 'collection'>): CollectionAfterDeleteHook =>\n async ({ id, req }) => {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload: req.payload,\n })\n const currentTenantCookieID = getTenantFromCookie(req.headers, idType)\n if (currentTenantCookieID === id) {\n const newHeaders = new Headers({\n 'Set-Cookie': generateCookie<string>({\n name: 'payload-tenant',\n expires: new Date(Date.now() - 1000),\n path: '/',\n returnCookieAsObject: false,\n value: '',\n }),\n })\n\n req.responseHeaders = req.responseHeaders\n ? mergeHeaders(req.responseHeaders, newHeaders)\n : newHeaders\n }\n const cleanupPromises: Promise<JsonObject>[] = []\n enabledSlugs.forEach((slug) => {\n cleanupPromises.push(\n req.payload.delete({\n collection: slug,\n where: {\n [tenantFieldName]: {\n equals: id,\n },\n },\n }),\n )\n })\n\n try {\n const usersWithTenant = (await req.payload.find({\n collection: usersSlug,\n depth: 0,\n limit: 0,\n where: {\n [`${usersTenantsArrayFieldName}.${usersTenantsArrayTenantFieldName}`]: {\n equals: id,\n },\n },\n })) as PaginatedDocs<UserWithTenantsField>\n\n usersWithTenant?.docs?.forEach((user) => {\n cleanupPromises.push(\n req.payload.update({\n id: user.id,\n collection: usersSlug,\n data: {\n [usersTenantsArrayFieldName]: (user[usersTenantsArrayFieldName] || []).filter(\n (row: Record<string, string>) => {\n if (row[usersTenantsArrayTenantFieldName]) {\n return row[usersTenantsArrayTenantFieldName] !== id\n }\n },\n ),\n },\n }),\n )\n })\n } catch (e) {\n console.error('Error deleting tenants from users:', e)\n }\n\n await Promise.all(cleanupPromises)\n }\n"],"names":["generateCookie","mergeHeaders","getCollectionIDType","getTenantFromCookie","addTenantCleanup","collection","enabledSlugs","tenantFieldName","tenantsCollectionSlug","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","hooks","afterDelete","push","afterTenantDelete","id","req","idType","collectionSlug","payload","currentTenantCookieID","headers","newHeaders","Headers","name","expires","Date","now","path","returnCookieAsObject","value","responseHeaders","cleanupPromises","forEach","slug","delete","where","equals","usersWithTenant","find","depth","limit","docs","user","update","data","filter","row","e","console","error","Promise","all"],"mappings":"AAOA,SAASA,cAAc,EAAEC,YAAY,QAAQ,UAAS;AAItD,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,mBAAmB,QAAQ,sCAAqC;AAWzE;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAAC,EAC/BC,UAAU,EACVC,YAAY,EACZC,eAAe,EACfC,qBAAqB,EACrBC,SAAS,EACTC,0BAA0B,EAC1BC,gCAAgC,EAC3B;IACL,IAAI,CAACN,WAAWO,KAAK,EAAE;QACrBP,WAAWO,KAAK,GAAG,CAAC;IACtB;IACA,IAAI,CAACP,WAAWO,KAAK,EAAEC,aAAa;QAClCR,WAAWO,KAAK,CAACC,WAAW,GAAG,EAAE;IACnC;IACAR,WAAWO,KAAK,CAACC,WAAW,CAACC,IAAI,CAC/BC,kBAAkB;QAChBT;QACAC;QACAC;QACAC;QACAC;QACAC;IACF;AAEJ,EAAC;AAED,OAAO,MAAMI,oBACX,CAAC,EACCT,YAAY,EACZC,eAAe,EACfC,qBAAqB,EACrBC,SAAS,EACTC,0BAA0B,EAC1BC,gCAAgC,EACP,GAC3B,OAAO,EAAEK,EAAE,EAAEC,GAAG,EAAE;QAChB,MAAMC,SAAShB,oBAAoB;YACjCiB,gBAAgBX;YAChBY,SAASH,IAAIG,OAAO;QACtB;QACA,MAAMC,wBAAwBlB,oBAAoBc,IAAIK,OAAO,EAAEJ;QAC/D,IAAIG,0BAA0BL,IAAI;YAChC,MAAMO,aAAa,IAAIC,QAAQ;gBAC7B,cAAcxB,eAAuB;oBACnCyB,MAAM;oBACNC,SAAS,IAAIC,KAAKA,KAAKC,GAAG,KAAK;oBAC/BC,MAAM;oBACNC,sBAAsB;oBACtBC,OAAO;gBACT;YACF;YAEAd,IAAIe,eAAe,GAAGf,IAAIe,eAAe,GACrC/B,aAAagB,IAAIe,eAAe,EAAET,cAClCA;QACN;QACA,MAAMU,kBAAyC,EAAE;QACjD3B,aAAa4B,OAAO,CAAC,CAACC;YACpBF,gBAAgBnB,IAAI,CAClBG,IAAIG,OAAO,CAACgB,MAAM,CAAC;gBACjB/B,YAAY8B;gBACZE,OAAO;oBACL,CAAC9B,gBAAgB,EAAE;wBACjB+B,QAAQtB;oBACV;gBACF;YACF;QAEJ;QAEA,IAAI;YACF,MAAMuB,kBAAmB,MAAMtB,IAAIG,OAAO,CAACoB,IAAI,CAAC;gBAC9CnC,YAAYI;gBACZgC,OAAO;gBACPC,OAAO;gBACPL,OAAO;oBACL,CAAC,GAAG3B,2BAA2B,CAAC,EAAEC,kCAAkC,CAAC,EAAE;wBACrE2B,QAAQtB;oBACV;gBACF;YACF;YAEAuB,iBAAiBI,MAAMT,QAAQ,CAACU;gBAC9BX,gBAAgBnB,IAAI,CAClBG,IAAIG,OAAO,CAACyB,MAAM,CAAC;oBACjB7B,IAAI4B,KAAK5B,EAAE;oBACXX,YAAYI;oBACZqC,MAAM;wBACJ,CAACpC,2BAA2B,EAAE,AAACkC,CAAAA,IAAI,CAAClC,2BAA2B,IAAI,EAAE,AAAD,EAAGqC,MAAM,CAC3E,CAACC;4BACC,IAAIA,GAAG,CAACrC,iCAAiC,EAAE;gCACzC,OAAOqC,GAAG,CAACrC,iCAAiC,KAAKK;4BACnD;wBACF;oBAEJ;gBACF;YAEJ;QACF,EAAE,OAAOiC,GAAG;YACVC,QAAQC,KAAK,CAAC,sCAAsCF;QACtD;QAEA,MAAMG,QAAQC,GAAG,CAACpB;IACpB,EAAC"}
1
+ {"version":3,"sources":["../../src/hooks/afterTenantDelete.ts"],"sourcesContent":["import type {\n CollectionAfterDeleteHook,\n CollectionConfig,\n JsonObject,\n PaginatedDocs,\n} from 'payload'\n\nimport { generateCookie, mergeHeaders } from 'payload'\n\nimport type { UserWithTenantsField } from '../types.js'\n\nimport { getCollectionIDType } from '../utilities/getCollectionIDType.js'\nimport { getTenantFromCookie } from '../utilities/getTenantFromCookie.js'\n\ntype Args = {\n collection: CollectionConfig\n enabledSlugs: string[]\n tenantFieldName: string\n tenantsCollectionSlug: string\n usersSlug: string\n usersTenantsArrayFieldName: string\n usersTenantsArrayTenantFieldName: string\n}\n/**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\nexport const addTenantCleanup = ({\n collection,\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n}: Args) => {\n if (!collection.hooks) {\n collection.hooks = {}\n }\n if (!collection.hooks?.afterDelete) {\n collection.hooks.afterDelete = []\n }\n collection.hooks.afterDelete.push(\n afterTenantDelete({\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n }),\n )\n}\n\nexport const afterTenantDelete =\n ({\n enabledSlugs,\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug,\n usersTenantsArrayFieldName,\n usersTenantsArrayTenantFieldName,\n }: Omit<Args, 'collection'>): CollectionAfterDeleteHook =>\n async ({ id, req }) => {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload: req.payload,\n })\n const currentTenantCookieID = getTenantFromCookie(req.headers, idType)\n if (currentTenantCookieID === id) {\n const newHeaders = new Headers({\n 'Set-Cookie': generateCookie<string>({\n name: 'payload-tenant',\n expires: new Date(Date.now() - 1000),\n path: '/',\n returnCookieAsObject: false,\n value: '',\n }),\n })\n\n req.responseHeaders = req.responseHeaders\n ? mergeHeaders(req.responseHeaders, newHeaders)\n : newHeaders\n }\n const cleanupPromises: Promise<JsonObject>[] = []\n enabledSlugs.forEach((slug) => {\n cleanupPromises.push(\n req.payload.delete({\n collection: slug,\n where: {\n [tenantFieldName]: {\n in: [id],\n },\n },\n }),\n )\n })\n\n try {\n const usersWithTenant = (await req.payload.find({\n collection: usersSlug,\n depth: 0,\n limit: 0,\n where: {\n [`${usersTenantsArrayFieldName}.${usersTenantsArrayTenantFieldName}`]: {\n in: [id],\n },\n },\n })) as PaginatedDocs<UserWithTenantsField>\n\n usersWithTenant?.docs?.forEach((user) => {\n cleanupPromises.push(\n req.payload.update({\n id: user.id,\n collection: usersSlug,\n data: {\n [usersTenantsArrayFieldName]: (user[usersTenantsArrayFieldName] || []).filter(\n (row: Record<string, string>) => {\n if (row[usersTenantsArrayTenantFieldName]) {\n return row[usersTenantsArrayTenantFieldName] !== id\n }\n },\n ),\n },\n }),\n )\n })\n } catch (e) {\n console.error('Error deleting tenants from users:', e)\n }\n\n await Promise.all(cleanupPromises)\n }\n"],"names":["generateCookie","mergeHeaders","getCollectionIDType","getTenantFromCookie","addTenantCleanup","collection","enabledSlugs","tenantFieldName","tenantsCollectionSlug","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","hooks","afterDelete","push","afterTenantDelete","id","req","idType","collectionSlug","payload","currentTenantCookieID","headers","newHeaders","Headers","name","expires","Date","now","path","returnCookieAsObject","value","responseHeaders","cleanupPromises","forEach","slug","delete","where","in","usersWithTenant","find","depth","limit","docs","user","update","data","filter","row","e","console","error","Promise","all"],"mappings":"AAOA,SAASA,cAAc,EAAEC,YAAY,QAAQ,UAAS;AAItD,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,mBAAmB,QAAQ,sCAAqC;AAWzE;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAAC,EAC/BC,UAAU,EACVC,YAAY,EACZC,eAAe,EACfC,qBAAqB,EACrBC,SAAS,EACTC,0BAA0B,EAC1BC,gCAAgC,EAC3B;IACL,IAAI,CAACN,WAAWO,KAAK,EAAE;QACrBP,WAAWO,KAAK,GAAG,CAAC;IACtB;IACA,IAAI,CAACP,WAAWO,KAAK,EAAEC,aAAa;QAClCR,WAAWO,KAAK,CAACC,WAAW,GAAG,EAAE;IACnC;IACAR,WAAWO,KAAK,CAACC,WAAW,CAACC,IAAI,CAC/BC,kBAAkB;QAChBT;QACAC;QACAC;QACAC;QACAC;QACAC;IACF;AAEJ,EAAC;AAED,OAAO,MAAMI,oBACX,CAAC,EACCT,YAAY,EACZC,eAAe,EACfC,qBAAqB,EACrBC,SAAS,EACTC,0BAA0B,EAC1BC,gCAAgC,EACP,GAC3B,OAAO,EAAEK,EAAE,EAAEC,GAAG,EAAE;QAChB,MAAMC,SAAShB,oBAAoB;YACjCiB,gBAAgBX;YAChBY,SAASH,IAAIG,OAAO;QACtB;QACA,MAAMC,wBAAwBlB,oBAAoBc,IAAIK,OAAO,EAAEJ;QAC/D,IAAIG,0BAA0BL,IAAI;YAChC,MAAMO,aAAa,IAAIC,QAAQ;gBAC7B,cAAcxB,eAAuB;oBACnCyB,MAAM;oBACNC,SAAS,IAAIC,KAAKA,KAAKC,GAAG,KAAK;oBAC/BC,MAAM;oBACNC,sBAAsB;oBACtBC,OAAO;gBACT;YACF;YAEAd,IAAIe,eAAe,GAAGf,IAAIe,eAAe,GACrC/B,aAAagB,IAAIe,eAAe,EAAET,cAClCA;QACN;QACA,MAAMU,kBAAyC,EAAE;QACjD3B,aAAa4B,OAAO,CAAC,CAACC;YACpBF,gBAAgBnB,IAAI,CAClBG,IAAIG,OAAO,CAACgB,MAAM,CAAC;gBACjB/B,YAAY8B;gBACZE,OAAO;oBACL,CAAC9B,gBAAgB,EAAE;wBACjB+B,IAAI;4BAACtB;yBAAG;oBACV;gBACF;YACF;QAEJ;QAEA,IAAI;YACF,MAAMuB,kBAAmB,MAAMtB,IAAIG,OAAO,CAACoB,IAAI,CAAC;gBAC9CnC,YAAYI;gBACZgC,OAAO;gBACPC,OAAO;gBACPL,OAAO;oBACL,CAAC,GAAG3B,2BAA2B,CAAC,EAAEC,kCAAkC,CAAC,EAAE;wBACrE2B,IAAI;4BAACtB;yBAAG;oBACV;gBACF;YACF;YAEAuB,iBAAiBI,MAAMT,QAAQ,CAACU;gBAC9BX,gBAAgBnB,IAAI,CAClBG,IAAIG,OAAO,CAACyB,MAAM,CAAC;oBACjB7B,IAAI4B,KAAK5B,EAAE;oBACXX,YAAYI;oBACZqC,MAAM;wBACJ,CAACpC,2BAA2B,EAAE,AAACkC,CAAAA,IAAI,CAAClC,2BAA2B,IAAI,EAAE,AAAD,EAAGqC,MAAM,CAC3E,CAACC;4BACC,IAAIA,GAAG,CAACrC,iCAAiC,EAAE;gCACzC,OAAOqC,GAAG,CAACrC,iCAAiC,KAAKK;4BACnD;wBACF;oBAEJ;gBACF;YAEJ;QACF,EAAE,OAAOiC,GAAG;YACVC,QAAQC,KAAK,CAAC,sCAAsCF;QACtD;QAEA,MAAMG,QAAQC,GAAG,CAACpB;IACpB,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAKvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAczD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,MAofzB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,MAAM,EAAE,MAAM,SAAS,CAAA;AAKvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAczD,eAAO,MAAM,iBAAiB,GAC3B,UAAU,gBAAgB,uBAAuB,CAAC,UAAU,CAAC,sBAC7C,MAAM,KAAG,MAqfzB,CAAA"}
package/dist/index.js CHANGED
@@ -68,6 +68,7 @@ export const multiTenantPlugin = (pluginConfig)=>(incomingConfig)=>{
68
68
  }));
69
69
  }
70
70
  addCollectionAccess({
71
+ accessResultCallback: pluginConfig.usersAccessResultOverride,
71
72
  adminUsersSlug: adminUsersCollection.slug,
72
73
  collection: adminUsersCollection,
73
74
  fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport type { CollectionConfig, Config } from 'payload'\n\nimport chalk from 'chalk'\n\nimport type { PluginDefaultTranslationsObject } from './translations/types.js'\nimport type { MultiTenantPluginConfig } from './types.js'\n\nimport { defaults } from './defaults.js'\nimport { getTenantOptionsEndpoint } from './endpoints/getTenantOptionsEndpoint.js'\nimport { tenantField } from './fields/tenantField/index.js'\nimport { tenantsArrayField } from './fields/tenantsArrayField/index.js'\nimport { filterDocumentsByTenants } from './filters/filterDocumentsByTenants.js'\nimport { addTenantCleanup } from './hooks/afterTenantDelete.js'\nimport { translations } from './translations/index.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { combineFilters } from './utilities/combineFilters.js'\nimport { miniChalk } from './utilities/miniChalk.js'\n\nexport const multiTenantPlugin =\n <ConfigType>(pluginConfig: MultiTenantPluginConfig<ConfigType>) =>\n (incomingConfig: Config): Config => {\n if (pluginConfig.enabled === false) {\n return incomingConfig\n }\n\n /**\n * Set defaults\n */\n const userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants'] =\n typeof pluginConfig.userHasAccessToAllTenants === 'function'\n ? pluginConfig.userHasAccessToAllTenants\n : () => false\n const tenantsCollectionSlug = (pluginConfig.tenantsSlug =\n pluginConfig.tenantsSlug || defaults.tenantCollectionSlug)\n const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName\n const tenantsArrayFieldName =\n pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n const basePath = pluginConfig.basePath || defaults.basePath\n\n /**\n * Add defaults for admin properties\n */\n if (!incomingConfig.admin) {\n incomingConfig.admin = {}\n }\n if (!incomingConfig.admin?.components) {\n incomingConfig.admin.components = {\n actions: [],\n beforeNavLinks: [],\n providers: [],\n }\n }\n if (!incomingConfig.admin.components?.providers) {\n incomingConfig.admin.components.providers = []\n }\n if (!incomingConfig.admin.components?.actions) {\n incomingConfig.admin.components.actions = []\n }\n if (!incomingConfig.admin.components?.beforeNavLinks) {\n incomingConfig.admin.components.beforeNavLinks = []\n }\n if (!incomingConfig.collections) {\n incomingConfig.collections = []\n }\n\n /**\n * Add tenants array field to users collection\n */\n const adminUsersCollection = incomingConfig.collections.find(({ slug, auth }) => {\n if (incomingConfig.admin?.user) {\n return slug === incomingConfig.admin.user\n } else if (auth) {\n return true\n }\n })\n\n if (!adminUsersCollection) {\n throw Error('An auth enabled collection was not found')\n }\n\n /**\n * Add tenants array field to users collection\n */\n if (pluginConfig?.tenantsArrayField?.includeDefaultField !== false) {\n adminUsersCollection.fields.push(\n tenantsArrayField({\n ...(pluginConfig?.tenantsArrayField || {}),\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n )\n }\n\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.useUsersTenantFilter !== false) {\n if (!adminUsersCollection.admin) {\n adminUsersCollection.admin = {}\n }\n\n const baseFilter =\n adminUsersCollection.admin?.baseFilter ?? adminUsersCollection.admin?.baseListFilter\n adminUsersCollection.admin.baseFilter = combineFilters({\n baseFilter,\n customFilter: (args) =>\n filterDocumentsByTenants<ConfigType>({\n filterFieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n }),\n })\n }\n\n let tenantCollection: CollectionConfig | undefined\n\n const [collectionSlugs, globalCollectionSlugs] = Object.keys(pluginConfig.collections).reduce<\n [string[], string[]]\n >(\n (acc, slug) => {\n if (pluginConfig?.collections?.[slug]?.isGlobal) {\n acc[1].push(slug)\n } else {\n acc[0].push(slug)\n }\n\n return acc\n },\n [[], []],\n )\n\n // used to track and not duplicate filterOptions on referenced blocks\n const blockReferencesWithFilters: string[] = []\n\n // used to validate enabled collection slugs\n const multiTenantCollectionsFound: string[] = []\n\n /**\n * The folders collection is added AFTER the plugin is initialized\n * so if they added the folder slug to the plugin collections,\n * we can assume that they have folders enabled\n */\n const foldersSlug = incomingConfig.folders\n ? incomingConfig.folders.slug || 'payload-folders'\n : 'payload-folders'\n\n if (collectionSlugs.includes(foldersSlug)) {\n multiTenantCollectionsFound.push(foldersSlug)\n incomingConfig.folders = incomingConfig.folders || {}\n incomingConfig.folders.collectionOverrides = incomingConfig.folders.collectionOverrides || []\n incomingConfig.folders.collectionOverrides.push(({ collection }) => {\n /**\n * Add filter options to all relationship fields\n */\n addFilterOptionsToFields({\n blockReferencesWithFilters,\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.collections[foldersSlug]?.customTenantField !== true) {\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.unshift(\n tenantField({\n name: tenantFieldName,\n debug: pluginConfig.debug,\n overrides: pluginConfig.collections[collection.slug]?.tenantFieldOverrides\n ? pluginConfig.collections[collection.slug]?.tenantFieldOverrides\n : pluginConfig.tenantField || {},\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n unique: false,\n }),\n )\n }\n\n const { useBaseFilter, useBaseListFilter } = pluginConfig.collections[collection.slug] || {}\n if (useBaseFilter ?? useBaseListFilter ?? true) {\n /**\n * Add list filter to enabled collections\n * - filters results by selected tenant\n */\n collection.admin = collection.admin || {}\n collection.admin.baseFilter = combineFilters({\n baseFilter: collection.admin?.baseFilter ?? collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterDocumentsByTenants<ConfigType>({\n filterFieldName: tenantFieldName,\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n }),\n })\n }\n\n if (pluginConfig.collections[foldersSlug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled folders collection\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n return collection\n })\n }\n\n /**\n * Modify collections\n */\n incomingConfig.collections.forEach((collection) => {\n /**\n * Modify tenants collection\n */\n if (collection.slug === tenantsCollectionSlug) {\n tenantCollection = collection\n\n if (pluginConfig.useTenantsCollectionAccess !== false) {\n /**\n * Add access control constraint to tenants collection\n * - constrains access a users assigned tenants\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: 'id',\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.useTenantsListFilter !== false) {\n /**\n * Add list filter to tenants collection\n * - filter by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n const baseFilter = collection.admin?.baseFilter ?? collection.admin?.baseListFilter\n collection.admin.baseFilter = combineFilters({\n baseFilter,\n customFilter: (args) =>\n filterDocumentsByTenants({\n filterFieldName: 'id',\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n }),\n })\n }\n\n if (pluginConfig.cleanupAfterTenantDelete !== false) {\n /**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\n addTenantCleanup({\n collection,\n enabledSlugs: [...collectionSlugs, ...globalCollectionSlugs],\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug: adminUsersCollection.slug,\n usersTenantsArrayFieldName: tenantsArrayFieldName,\n usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName,\n })\n }\n\n /**\n * Add custom tenant field that watches and dispatches updates to the selector\n */\n collection.fields.push({\n name: '_watchTenant',\n type: 'ui',\n admin: {\n components: {\n Field: {\n path: '@payloadcms/plugin-multi-tenant/client#WatchTenantCollection',\n },\n },\n disableBulkEdit: true,\n disableListColumn: true,\n },\n })\n\n collection.endpoints = [\n ...(collection.endpoints || []),\n getTenantOptionsEndpoint({\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n userHasAccessToAllTenants,\n }),\n ]\n } else if (pluginConfig.collections?.[collection.slug]) {\n multiTenantCollectionsFound.push(collection.slug)\n const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal)\n\n if (isGlobal) {\n collection.disableDuplicate = true\n }\n\n if (!pluginConfig.debug && !isGlobal) {\n collection.admin ??= {}\n collection.admin.components ??= {}\n collection.admin.components.edit ??= {}\n collection.admin.components.edit.editMenuItems ??= []\n collection.admin.components.edit.editMenuItems.push({\n path: '@payloadcms/plugin-multi-tenant/client#AssignTenantFieldTrigger',\n })\n }\n\n /**\n * Add filter options to all relationship fields\n */\n addFilterOptionsToFields({\n blockReferencesWithFilters,\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.collections[collection.slug]?.customTenantField !== true) {\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.unshift(\n tenantField({\n name: tenantFieldName,\n debug: pluginConfig.debug,\n overrides: pluginConfig.collections[collection.slug]?.tenantFieldOverrides\n ? pluginConfig.collections[collection.slug]?.tenantFieldOverrides\n : pluginConfig.tenantField || {},\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n unique: isGlobal,\n }),\n )\n }\n\n const { useBaseFilter, useBaseListFilter } = pluginConfig.collections[collection.slug] || {}\n if (useBaseFilter ?? useBaseListFilter ?? true) {\n /**\n * Add list filter to enabled collections\n * - filters results by selected tenant\n */\n collection.admin = collection.admin || {}\n collection.admin.baseFilter = combineFilters({\n baseFilter: collection.admin?.baseFilter ?? collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterDocumentsByTenants({\n filterFieldName: tenantFieldName,\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n }),\n })\n }\n\n if (pluginConfig.collections[collection.slug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled collection\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n }\n })\n\n if (!tenantCollection) {\n throw new Error(`Tenants collection not found with slug: ${tenantsCollectionSlug}`)\n }\n\n if (\n multiTenantCollectionsFound.length !==\n collectionSlugs.length + globalCollectionSlugs.length\n ) {\n const missingSlugs = [...collectionSlugs, ...globalCollectionSlugs].filter(\n (slug) => !multiTenantCollectionsFound.includes(slug),\n )\n // eslint-disable-next-line no-console\n console.error(\n miniChalk.yellowBold('WARNING (plugin-multi-tenant)'),\n 'missing collections',\n missingSlugs,\n 'try placing the multi-tenant plugin after other plugins.',\n )\n }\n\n /**\n * Add TenantSelectionProvider to admin providers\n */\n incomingConfig.admin.components.providers.push({\n clientProps: {\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug: tenantCollection.slug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n userHasAccessToAllTenants,\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelectionProvider',\n })\n\n /**\n * Add global redirect action\n */\n if (globalCollectionSlugs.length) {\n incomingConfig.admin.components.actions.push({\n path: '@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect',\n serverProps: {\n basePath,\n globalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n userHasAccessToAllTenants,\n },\n })\n }\n\n /**\n * Add tenant selector to admin UI\n */\n incomingConfig.admin.components.beforeNavLinks.push({\n clientProps: {\n enabledSlugs: [\n ...collectionSlugs,\n ...globalCollectionSlugs,\n adminUsersCollection.slug,\n tenantCollection.slug,\n ],\n label: pluginConfig.tenantSelectorLabel || undefined,\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelector',\n })\n\n /**\n * Merge plugin translations\n */\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n Object.entries(translations).forEach(([locale, pluginI18nObject]) => {\n const typedLocale = locale as AcceptedLanguages\n if (!incomingConfig.i18n!.translations) {\n incomingConfig.i18n!.translations = {}\n }\n if (!(typedLocale in incomingConfig.i18n!.translations)) {\n incomingConfig.i18n!.translations[typedLocale] = {}\n }\n if (!('plugin-multi-tenant' in incomingConfig.i18n!.translations[typedLocale]!)) {\n ;(incomingConfig.i18n!.translations[typedLocale] as PluginDefaultTranslationsObject)[\n 'plugin-multi-tenant'\n ] = {} as PluginDefaultTranslationsObject['plugin-multi-tenant']\n }\n\n ;(incomingConfig.i18n!.translations[typedLocale] as PluginDefaultTranslationsObject)[\n 'plugin-multi-tenant'\n ] = {\n ...pluginI18nObject.translations['plugin-multi-tenant'],\n ...(pluginConfig.i18n?.translations?.[typedLocale] || {}),\n }\n })\n\n return incomingConfig\n }\n"],"names":["defaults","getTenantOptionsEndpoint","tenantField","tenantsArrayField","filterDocumentsByTenants","addTenantCleanup","translations","addCollectionAccess","addFilterOptionsToFields","combineFilters","miniChalk","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","basePath","admin","components","actions","beforeNavLinks","providers","collections","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","adminUsersSlug","collection","fieldName","useUsersTenantFilter","baseFilter","baseListFilter","customFilter","args","filterFieldName","req","tenantCollection","collectionSlugs","globalCollectionSlugs","Object","keys","reduce","acc","isGlobal","blockReferencesWithFilters","multiTenantCollectionsFound","foldersSlug","folders","includes","collectionOverrides","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","customTenantField","unshift","debug","overrides","tenantFieldOverrides","unique","useBaseFilter","useBaseListFilter","useTenantAccess","forEach","useTenantsCollectionAccess","useTenantsListFilter","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","type","Field","path","disableBulkEdit","disableListColumn","endpoints","useAsTitle","Boolean","disableDuplicate","edit","editMenuItems","length","missingSlugs","filter","console","error","yellowBold","clientProps","serverProps","globalSlugs","label","tenantSelectorLabel","undefined","i18n","entries","locale","pluginI18nObject","typedLocale"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport type { CollectionConfig, Config } from 'payload'\n\nimport chalk from 'chalk'\n\nimport type { PluginDefaultTranslationsObject } from './translations/types.js'\nimport type { MultiTenantPluginConfig } from './types.js'\n\nimport { defaults } from './defaults.js'\nimport { getTenantOptionsEndpoint } from './endpoints/getTenantOptionsEndpoint.js'\nimport { tenantField } from './fields/tenantField/index.js'\nimport { tenantsArrayField } from './fields/tenantsArrayField/index.js'\nimport { filterDocumentsByTenants } from './filters/filterDocumentsByTenants.js'\nimport { addTenantCleanup } from './hooks/afterTenantDelete.js'\nimport { translations } from './translations/index.js'\nimport { addCollectionAccess } from './utilities/addCollectionAccess.js'\nimport { addFilterOptionsToFields } from './utilities/addFilterOptionsToFields.js'\nimport { combineFilters } from './utilities/combineFilters.js'\nimport { miniChalk } from './utilities/miniChalk.js'\n\nexport const multiTenantPlugin =\n <ConfigType>(pluginConfig: MultiTenantPluginConfig<ConfigType>) =>\n (incomingConfig: Config): Config => {\n if (pluginConfig.enabled === false) {\n return incomingConfig\n }\n\n /**\n * Set defaults\n */\n const userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants'] =\n typeof pluginConfig.userHasAccessToAllTenants === 'function'\n ? pluginConfig.userHasAccessToAllTenants\n : () => false\n const tenantsCollectionSlug = (pluginConfig.tenantsSlug =\n pluginConfig.tenantsSlug || defaults.tenantCollectionSlug)\n const tenantFieldName = pluginConfig?.tenantField?.name || defaults.tenantFieldName\n const tenantsArrayFieldName =\n pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n const basePath = pluginConfig.basePath || defaults.basePath\n\n /**\n * Add defaults for admin properties\n */\n if (!incomingConfig.admin) {\n incomingConfig.admin = {}\n }\n if (!incomingConfig.admin?.components) {\n incomingConfig.admin.components = {\n actions: [],\n beforeNavLinks: [],\n providers: [],\n }\n }\n if (!incomingConfig.admin.components?.providers) {\n incomingConfig.admin.components.providers = []\n }\n if (!incomingConfig.admin.components?.actions) {\n incomingConfig.admin.components.actions = []\n }\n if (!incomingConfig.admin.components?.beforeNavLinks) {\n incomingConfig.admin.components.beforeNavLinks = []\n }\n if (!incomingConfig.collections) {\n incomingConfig.collections = []\n }\n\n /**\n * Add tenants array field to users collection\n */\n const adminUsersCollection = incomingConfig.collections.find(({ slug, auth }) => {\n if (incomingConfig.admin?.user) {\n return slug === incomingConfig.admin.user\n } else if (auth) {\n return true\n }\n })\n\n if (!adminUsersCollection) {\n throw Error('An auth enabled collection was not found')\n }\n\n /**\n * Add tenants array field to users collection\n */\n if (pluginConfig?.tenantsArrayField?.includeDefaultField !== false) {\n adminUsersCollection.fields.push(\n tenantsArrayField({\n ...(pluginConfig?.tenantsArrayField || {}),\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n }),\n )\n }\n\n addCollectionAccess({\n accessResultCallback: pluginConfig.usersAccessResultOverride,\n adminUsersSlug: adminUsersCollection.slug,\n collection: adminUsersCollection,\n fieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.useUsersTenantFilter !== false) {\n if (!adminUsersCollection.admin) {\n adminUsersCollection.admin = {}\n }\n\n const baseFilter =\n adminUsersCollection.admin?.baseFilter ?? adminUsersCollection.admin?.baseListFilter\n adminUsersCollection.admin.baseFilter = combineFilters({\n baseFilter,\n customFilter: (args) =>\n filterDocumentsByTenants<ConfigType>({\n filterFieldName: `${tenantsArrayFieldName}.${tenantsArrayTenantFieldName}`,\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n }),\n })\n }\n\n let tenantCollection: CollectionConfig | undefined\n\n const [collectionSlugs, globalCollectionSlugs] = Object.keys(pluginConfig.collections).reduce<\n [string[], string[]]\n >(\n (acc, slug) => {\n if (pluginConfig?.collections?.[slug]?.isGlobal) {\n acc[1].push(slug)\n } else {\n acc[0].push(slug)\n }\n\n return acc\n },\n [[], []],\n )\n\n // used to track and not duplicate filterOptions on referenced blocks\n const blockReferencesWithFilters: string[] = []\n\n // used to validate enabled collection slugs\n const multiTenantCollectionsFound: string[] = []\n\n /**\n * The folders collection is added AFTER the plugin is initialized\n * so if they added the folder slug to the plugin collections,\n * we can assume that they have folders enabled\n */\n const foldersSlug = incomingConfig.folders\n ? incomingConfig.folders.slug || 'payload-folders'\n : 'payload-folders'\n\n if (collectionSlugs.includes(foldersSlug)) {\n multiTenantCollectionsFound.push(foldersSlug)\n incomingConfig.folders = incomingConfig.folders || {}\n incomingConfig.folders.collectionOverrides = incomingConfig.folders.collectionOverrides || []\n incomingConfig.folders.collectionOverrides.push(({ collection }) => {\n /**\n * Add filter options to all relationship fields\n */\n addFilterOptionsToFields({\n blockReferencesWithFilters,\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.collections[foldersSlug]?.customTenantField !== true) {\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.unshift(\n tenantField({\n name: tenantFieldName,\n debug: pluginConfig.debug,\n overrides: pluginConfig.collections[collection.slug]?.tenantFieldOverrides\n ? pluginConfig.collections[collection.slug]?.tenantFieldOverrides\n : pluginConfig.tenantField || {},\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n unique: false,\n }),\n )\n }\n\n const { useBaseFilter, useBaseListFilter } = pluginConfig.collections[collection.slug] || {}\n if (useBaseFilter ?? useBaseListFilter ?? true) {\n /**\n * Add list filter to enabled collections\n * - filters results by selected tenant\n */\n collection.admin = collection.admin || {}\n collection.admin.baseFilter = combineFilters({\n baseFilter: collection.admin?.baseFilter ?? collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterDocumentsByTenants<ConfigType>({\n filterFieldName: tenantFieldName,\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n }),\n })\n }\n\n if (pluginConfig.collections[foldersSlug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled folders collection\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n return collection\n })\n }\n\n /**\n * Modify collections\n */\n incomingConfig.collections.forEach((collection) => {\n /**\n * Modify tenants collection\n */\n if (collection.slug === tenantsCollectionSlug) {\n tenantCollection = collection\n\n if (pluginConfig.useTenantsCollectionAccess !== false) {\n /**\n * Add access control constraint to tenants collection\n * - constrains access a users assigned tenants\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: 'id',\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n\n if (pluginConfig.useTenantsListFilter !== false) {\n /**\n * Add list filter to tenants collection\n * - filter by selected tenant\n */\n if (!collection.admin) {\n collection.admin = {}\n }\n\n const baseFilter = collection.admin?.baseFilter ?? collection.admin?.baseListFilter\n collection.admin.baseFilter = combineFilters({\n baseFilter,\n customFilter: (args) =>\n filterDocumentsByTenants({\n filterFieldName: 'id',\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n }),\n })\n }\n\n if (pluginConfig.cleanupAfterTenantDelete !== false) {\n /**\n * Add cleanup logic when tenant is deleted\n * - delete documents related to tenant\n * - remove tenant from users\n */\n addTenantCleanup({\n collection,\n enabledSlugs: [...collectionSlugs, ...globalCollectionSlugs],\n tenantFieldName,\n tenantsCollectionSlug,\n usersSlug: adminUsersCollection.slug,\n usersTenantsArrayFieldName: tenantsArrayFieldName,\n usersTenantsArrayTenantFieldName: tenantsArrayTenantFieldName,\n })\n }\n\n /**\n * Add custom tenant field that watches and dispatches updates to the selector\n */\n collection.fields.push({\n name: '_watchTenant',\n type: 'ui',\n admin: {\n components: {\n Field: {\n path: '@payloadcms/plugin-multi-tenant/client#WatchTenantCollection',\n },\n },\n disableBulkEdit: true,\n disableListColumn: true,\n },\n })\n\n collection.endpoints = [\n ...(collection.endpoints || []),\n getTenantOptionsEndpoint({\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n userHasAccessToAllTenants,\n }),\n ]\n } else if (pluginConfig.collections?.[collection.slug]) {\n multiTenantCollectionsFound.push(collection.slug)\n const isGlobal = Boolean(pluginConfig.collections[collection.slug]?.isGlobal)\n\n if (isGlobal) {\n collection.disableDuplicate = true\n }\n\n if (!pluginConfig.debug && !isGlobal) {\n collection.admin ??= {}\n collection.admin.components ??= {}\n collection.admin.components.edit ??= {}\n collection.admin.components.edit.editMenuItems ??= []\n collection.admin.components.edit.editMenuItems.push({\n path: '@payloadcms/plugin-multi-tenant/client#AssignTenantFieldTrigger',\n })\n }\n\n /**\n * Add filter options to all relationship fields\n */\n addFilterOptionsToFields({\n blockReferencesWithFilters,\n config: incomingConfig,\n fields: collection.fields,\n tenantEnabledCollectionSlugs: collectionSlugs,\n tenantEnabledGlobalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n })\n\n if (pluginConfig.collections[collection.slug]?.customTenantField !== true) {\n /**\n * Add tenant field to enabled collections\n */\n collection.fields.unshift(\n tenantField({\n name: tenantFieldName,\n debug: pluginConfig.debug,\n overrides: pluginConfig.collections[collection.slug]?.tenantFieldOverrides\n ? pluginConfig.collections[collection.slug]?.tenantFieldOverrides\n : pluginConfig.tenantField || {},\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n unique: isGlobal,\n }),\n )\n }\n\n const { useBaseFilter, useBaseListFilter } = pluginConfig.collections[collection.slug] || {}\n if (useBaseFilter ?? useBaseListFilter ?? true) {\n /**\n * Add list filter to enabled collections\n * - filters results by selected tenant\n */\n collection.admin = collection.admin || {}\n collection.admin.baseFilter = combineFilters({\n baseFilter: collection.admin?.baseFilter ?? collection.admin?.baseListFilter,\n customFilter: (args) =>\n filterDocumentsByTenants({\n filterFieldName: tenantFieldName,\n req: args.req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n userHasAccessToAllTenants,\n }),\n })\n }\n\n if (pluginConfig.collections[collection.slug]?.useTenantAccess !== false) {\n /**\n * Add access control constraint to tenant enabled collection\n */\n addCollectionAccess({\n adminUsersSlug: adminUsersCollection.slug,\n collection,\n fieldName: tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n }\n }\n })\n\n if (!tenantCollection) {\n throw new Error(`Tenants collection not found with slug: ${tenantsCollectionSlug}`)\n }\n\n if (\n multiTenantCollectionsFound.length !==\n collectionSlugs.length + globalCollectionSlugs.length\n ) {\n const missingSlugs = [...collectionSlugs, ...globalCollectionSlugs].filter(\n (slug) => !multiTenantCollectionsFound.includes(slug),\n )\n // eslint-disable-next-line no-console\n console.error(\n miniChalk.yellowBold('WARNING (plugin-multi-tenant)'),\n 'missing collections',\n missingSlugs,\n 'try placing the multi-tenant plugin after other plugins.',\n )\n }\n\n /**\n * Add TenantSelectionProvider to admin providers\n */\n incomingConfig.admin.components.providers.push({\n clientProps: {\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug: tenantCollection.slug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n userHasAccessToAllTenants,\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelectionProvider',\n })\n\n /**\n * Add global redirect action\n */\n if (globalCollectionSlugs.length) {\n incomingConfig.admin.components.actions.push({\n path: '@payloadcms/plugin-multi-tenant/rsc#GlobalViewRedirect',\n serverProps: {\n basePath,\n globalSlugs: globalCollectionSlugs,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle: tenantCollection.admin?.useAsTitle || 'id',\n userHasAccessToAllTenants,\n },\n })\n }\n\n /**\n * Add tenant selector to admin UI\n */\n incomingConfig.admin.components.beforeNavLinks.push({\n clientProps: {\n enabledSlugs: [\n ...collectionSlugs,\n ...globalCollectionSlugs,\n adminUsersCollection.slug,\n tenantCollection.slug,\n ],\n label: pluginConfig.tenantSelectorLabel || undefined,\n },\n path: '@payloadcms/plugin-multi-tenant/rsc#TenantSelector',\n })\n\n /**\n * Merge plugin translations\n */\n if (!incomingConfig.i18n) {\n incomingConfig.i18n = {}\n }\n Object.entries(translations).forEach(([locale, pluginI18nObject]) => {\n const typedLocale = locale as AcceptedLanguages\n if (!incomingConfig.i18n!.translations) {\n incomingConfig.i18n!.translations = {}\n }\n if (!(typedLocale in incomingConfig.i18n!.translations)) {\n incomingConfig.i18n!.translations[typedLocale] = {}\n }\n if (!('plugin-multi-tenant' in incomingConfig.i18n!.translations[typedLocale]!)) {\n ;(incomingConfig.i18n!.translations[typedLocale] as PluginDefaultTranslationsObject)[\n 'plugin-multi-tenant'\n ] = {} as PluginDefaultTranslationsObject['plugin-multi-tenant']\n }\n\n ;(incomingConfig.i18n!.translations[typedLocale] as PluginDefaultTranslationsObject)[\n 'plugin-multi-tenant'\n ] = {\n ...pluginI18nObject.translations['plugin-multi-tenant'],\n ...(pluginConfig.i18n?.translations?.[typedLocale] || {}),\n }\n })\n\n return incomingConfig\n }\n"],"names":["defaults","getTenantOptionsEndpoint","tenantField","tenantsArrayField","filterDocumentsByTenants","addTenantCleanup","translations","addCollectionAccess","addFilterOptionsToFields","combineFilters","miniChalk","multiTenantPlugin","pluginConfig","incomingConfig","enabled","userHasAccessToAllTenants","tenantsCollectionSlug","tenantsSlug","tenantCollectionSlug","tenantFieldName","name","tenantsArrayFieldName","arrayFieldName","tenantsArrayTenantFieldName","arrayTenantFieldName","basePath","admin","components","actions","beforeNavLinks","providers","collections","adminUsersCollection","find","slug","auth","user","Error","includeDefaultField","fields","push","accessResultCallback","usersAccessResultOverride","adminUsersSlug","collection","fieldName","useUsersTenantFilter","baseFilter","baseListFilter","customFilter","args","filterFieldName","req","tenantCollection","collectionSlugs","globalCollectionSlugs","Object","keys","reduce","acc","isGlobal","blockReferencesWithFilters","multiTenantCollectionsFound","foldersSlug","folders","includes","collectionOverrides","config","tenantEnabledCollectionSlugs","tenantEnabledGlobalSlugs","customTenantField","unshift","debug","overrides","tenantFieldOverrides","unique","useBaseFilter","useBaseListFilter","useTenantAccess","forEach","useTenantsCollectionAccess","useTenantsListFilter","cleanupAfterTenantDelete","enabledSlugs","usersSlug","usersTenantsArrayFieldName","usersTenantsArrayTenantFieldName","type","Field","path","disableBulkEdit","disableListColumn","endpoints","useAsTitle","Boolean","disableDuplicate","edit","editMenuItems","length","missingSlugs","filter","console","error","yellowBold","clientProps","serverProps","globalSlugs","label","tenantSelectorLabel","undefined","i18n","entries","locale","pluginI18nObject","typedLocale"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { AcceptedLanguages } from '@payloadcms/translations';
2
- import type { ArrayField, CollectionSlug, Field, RelationshipField, SingleRelationshipField, TypedUser } from 'payload';
2
+ import type { AccessResult, ArrayField, CollectionConfig, CollectionSlug, Field, RelationshipField, SingleRelationshipField, TypedUser } from 'payload';
3
3
  export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
4
4
  /**
5
5
  * Base path for your application
@@ -184,6 +184,13 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
184
184
  userHasAccessToAllTenants?: (user: ConfigTypes extends {
185
185
  user: unknown;
186
186
  } ? ConfigTypes['user'] : TypedUser) => boolean;
187
+ /**
188
+ * Override the result of the admin `users` collection access control functions
189
+ */
190
+ usersAccessResultOverride?: ({ accessKey, result, }: {
191
+ accessKey: AllAccessKeys[number];
192
+ result: AccessResult;
193
+ }) => AccessResult;
187
194
  /**
188
195
  * Opt out of adding access constraints to the tenants collection
189
196
  */
@@ -197,7 +204,7 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
197
204
  */
198
205
  useUsersTenantFilter?: boolean;
199
206
  };
200
- export type RootTenantFieldConfigOverrides = Partial<Omit<SingleRelationshipField, '_sanitized' | 'hasMany' | 'hidden' | 'index' | 'localized' | 'max' | 'maxRows' | 'min' | 'minRows' | 'relationTo' | 'required' | 'type' | 'unique' | 'virtual'>>;
207
+ export type RootTenantFieldConfigOverrides = Partial<Omit<SingleRelationshipField, '_sanitized' | 'hidden' | 'index' | 'localized' | 'max' | 'maxRows' | 'min' | 'minRows' | 'relationTo' | 'required' | 'type' | 'unique' | 'virtual'>>;
201
208
  export type CollectionTenantFieldConfigOverrides = Partial<Omit<RootTenantFieldConfigOverrides, 'name'>>;
202
209
  export type Tenant<IDType = number | string> = {
203
210
  id: IDType;
@@ -208,4 +215,14 @@ export type UserWithTenantsField = {
208
215
  tenant: number | string | Tenant;
209
216
  }[] | null;
210
217
  } & TypedUser;
218
+ type AllAccessKeysT<T extends readonly string[]> = T[number] extends keyof Omit<Required<CollectionConfig>['access'], 'admin'> ? keyof Omit<Required<CollectionConfig>['access'], 'admin'> extends T[number] ? T : never : never;
219
+ export type AllAccessKeys = AllAccessKeysT<[
220
+ 'create',
221
+ 'read',
222
+ 'update',
223
+ 'delete',
224
+ 'readVersions',
225
+ 'unlock'
226
+ ]>;
227
+ export {};
211
228
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport type {\n ArrayField,\n CollectionSlug,\n Field,\n RelationshipField,\n SingleRelationshipField,\n TypedUser,\n} from 'payload'\n\nexport type MultiTenantPluginConfig<ConfigTypes = unknown> = {\n /**\n * Base path for your application\n *\n * https://nextjs.org/docs/app/api-reference/config/next-config-js/basePath\n *\n * @default undefined\n */\n basePath?: string\n /**\n * After a tenant is deleted, the plugin will attempt to clean up related documents\n * - removing documents with the tenant ID\n * - removing the tenant from users\n *\n * @default true\n */\n cleanupAfterTenantDelete?: boolean\n /**\n * Automatically\n */\n collections: {\n [key in CollectionSlug]?: {\n /**\n * Opt out of adding the tenant field and place\n * it manually using the `tenantField` export from the plugin\n */\n customTenantField?: boolean\n /**\n * Set to `true` if you want the collection to behave as a global\n *\n * @default false\n */\n isGlobal?: boolean\n /**\n * Overrides for the tenant field, will override the entire tenantField configuration\n */\n tenantFieldOverrides?: CollectionTenantFieldConfigOverrides\n /**\n * Set to `false` if you want to manually apply the baseListFilter\n * Set to `false` if you want to manually apply the baseFilter\n *\n * @default true\n */\n useBaseFilter?: boolean\n /**\n * @deprecated Use `useBaseFilter` instead. If both are defined,\n * `useBaseFilter` will take precedence. This property remains only\n * for backward compatibility and may be removed in a future version.\n *\n * Originally, `baseListFilter` was intended to filter only the List View\n * in the admin panel. However, base filtering is often required in other areas\n * such as internal link relationships in the Lexical editor.\n *\n * @default true\n */\n useBaseListFilter?: boolean\n /**\n * Set to `false` if you want to handle collection access manually without the multi-tenant constraints applied\n *\n * @default true\n */\n useTenantAccess?: boolean\n }\n }\n /**\n * Enables debug mode\n * - Makes the tenant field visible in the admin UI within applicable collections\n *\n * @default false\n */\n debug?: boolean\n /**\n * Enables the multi-tenant plugin\n *\n * @default true\n */\n enabled?: boolean\n /**\n * Localization for the plugin\n */\n i18n?: {\n translations: {\n [key in AcceptedLanguages]?: {\n /**\n * Shown inside 3 dot menu on edit document view\n *\n * @default 'Assign Tenant'\n */\n 'assign-tenant-button-label'?: string\n /**\n * Shown as the title of the assign tenant modal\n *\n * @default 'Assign \"{{title}}\"'\n */\n 'assign-tenant-modal-title'?: string\n /**\n * Shown as the label for the assigned tenant field in the assign tenant modal\n *\n * @default 'Assigned Tenant'\n */\n 'field-assignedTenant-label'?: string\n /**\n * Shown as the label for the global tenant selector in the admin UI\n *\n * @default 'Filter by Tenant'\n */\n 'nav-tenantSelector-label'?: string\n }\n }\n }\n /**\n * Field configuration for the field added to all tenant enabled collections\n */\n tenantField?: RootTenantFieldConfigOverrides\n /**\n * Field configuration for the field added to the users collection\n *\n * If `includeDefaultField` is `false`, you must include the field on your users collection manually\n * This is useful if you want to customize the field or place the field in a specific location\n */\n tenantsArrayField?:\n | {\n /**\n * Access configuration for the array field\n */\n arrayFieldAccess?: ArrayField['access']\n /**\n * Name of the array field\n *\n * @default 'tenants'\n */\n arrayFieldName?: string\n /**\n * Name of the tenant field\n *\n * @default 'tenant'\n */\n arrayTenantFieldName?: string\n /**\n * When `includeDefaultField` is `true`, the field will be added to the users collection automatically\n */\n includeDefaultField?: true\n /**\n * Additional fields to include on the tenants array field\n */\n rowFields?: Field[]\n /**\n * Access configuration for the tenant field\n */\n tenantFieldAccess?: RelationshipField['access']\n }\n | {\n arrayFieldAccess?: never\n arrayFieldName?: string\n arrayTenantFieldName?: string\n /**\n * When `includeDefaultField` is `false`, you must include the field on your users collection manually\n */\n includeDefaultField?: false\n rowFields?: never\n tenantFieldAccess?: never\n }\n /**\n * Customize tenant selector label\n *\n * Either a string or an object where the keys are i18n codes and the values are the string labels\n *\n * @deprecated Use `i18n.translations` instead.\n */\n tenantSelectorLabel?:\n | Partial<{\n [key in AcceptedLanguages]?: string\n }>\n | string\n /**\n * The slug for the tenant collection\n *\n * @default 'tenants'\n */\n tenantsSlug?: string\n /**\n * Function that determines if a user has access to _all_ tenants\n *\n * Useful for super-admin type users\n */\n userHasAccessToAllTenants?: (\n user: ConfigTypes extends { user: unknown } ? ConfigTypes['user'] : TypedUser,\n ) => boolean\n /**\n * Opt out of adding access constraints to the tenants collection\n */\n useTenantsCollectionAccess?: boolean\n /**\n * Opt out including the baseListFilter to filter tenants by selected tenant\n */\n useTenantsListFilter?: boolean\n /**\n * Opt out including the baseListFilter to filter users by selected tenant\n */\n useUsersTenantFilter?: boolean\n}\n\nexport type RootTenantFieldConfigOverrides = Partial<\n Omit<\n SingleRelationshipField,\n | '_sanitized'\n | 'hasMany'\n | 'hidden'\n | 'index'\n | 'localized'\n | 'max'\n | 'maxRows'\n | 'min'\n | 'minRows'\n | 'relationTo'\n | 'required'\n | 'type'\n | 'unique'\n | 'virtual'\n >\n>\n\nexport type CollectionTenantFieldConfigOverrides = Partial<\n Omit<RootTenantFieldConfigOverrides, 'name'>\n>\n\nexport type Tenant<IDType = number | string> = {\n id: IDType\n name: string\n}\n\nexport type UserWithTenantsField = {\n tenants?:\n | {\n tenant: number | string | Tenant\n }[]\n | null\n} & TypedUser\n"],"names":[],"mappings":"AAiPA,WAMa"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\nimport type {\n AccessResult,\n ArrayField,\n CollectionConfig,\n CollectionSlug,\n Field,\n RelationshipField,\n SingleRelationshipField,\n TypedUser,\n} from 'payload'\n\nexport type MultiTenantPluginConfig<ConfigTypes = unknown> = {\n /**\n * Base path for your application\n *\n * https://nextjs.org/docs/app/api-reference/config/next-config-js/basePath\n *\n * @default undefined\n */\n basePath?: string\n /**\n * After a tenant is deleted, the plugin will attempt to clean up related documents\n * - removing documents with the tenant ID\n * - removing the tenant from users\n *\n * @default true\n */\n cleanupAfterTenantDelete?: boolean\n /**\n * Automatically\n */\n collections: {\n [key in CollectionSlug]?: {\n /**\n * Opt out of adding the tenant field and place\n * it manually using the `tenantField` export from the plugin\n */\n customTenantField?: boolean\n /**\n * Set to `true` if you want the collection to behave as a global\n *\n * @default false\n */\n isGlobal?: boolean\n /**\n * Overrides for the tenant field, will override the entire tenantField configuration\n */\n tenantFieldOverrides?: CollectionTenantFieldConfigOverrides\n /**\n * Set to `false` if you want to manually apply the baseListFilter\n * Set to `false` if you want to manually apply the baseFilter\n *\n * @default true\n */\n useBaseFilter?: boolean\n /**\n * @deprecated Use `useBaseFilter` instead. If both are defined,\n * `useBaseFilter` will take precedence. This property remains only\n * for backward compatibility and may be removed in a future version.\n *\n * Originally, `baseListFilter` was intended to filter only the List View\n * in the admin panel. However, base filtering is often required in other areas\n * such as internal link relationships in the Lexical editor.\n *\n * @default true\n */\n useBaseListFilter?: boolean\n /**\n * Set to `false` if you want to handle collection access manually without the multi-tenant constraints applied\n *\n * @default true\n */\n useTenantAccess?: boolean\n }\n }\n /**\n * Enables debug mode\n * - Makes the tenant field visible in the admin UI within applicable collections\n *\n * @default false\n */\n debug?: boolean\n /**\n * Enables the multi-tenant plugin\n *\n * @default true\n */\n enabled?: boolean\n /**\n * Localization for the plugin\n */\n i18n?: {\n translations: {\n [key in AcceptedLanguages]?: {\n /**\n * Shown inside 3 dot menu on edit document view\n *\n * @default 'Assign Tenant'\n */\n 'assign-tenant-button-label'?: string\n /**\n * Shown as the title of the assign tenant modal\n *\n * @default 'Assign \"{{title}}\"'\n */\n 'assign-tenant-modal-title'?: string\n /**\n * Shown as the label for the assigned tenant field in the assign tenant modal\n *\n * @default 'Assigned Tenant'\n */\n 'field-assignedTenant-label'?: string\n /**\n * Shown as the label for the global tenant selector in the admin UI\n *\n * @default 'Filter by Tenant'\n */\n 'nav-tenantSelector-label'?: string\n }\n }\n }\n /**\n * Field configuration for the field added to all tenant enabled collections\n */\n tenantField?: RootTenantFieldConfigOverrides\n /**\n * Field configuration for the field added to the users collection\n *\n * If `includeDefaultField` is `false`, you must include the field on your users collection manually\n * This is useful if you want to customize the field or place the field in a specific location\n */\n tenantsArrayField?:\n | {\n /**\n * Access configuration for the array field\n */\n arrayFieldAccess?: ArrayField['access']\n /**\n * Name of the array field\n *\n * @default 'tenants'\n */\n arrayFieldName?: string\n /**\n * Name of the tenant field\n *\n * @default 'tenant'\n */\n arrayTenantFieldName?: string\n /**\n * When `includeDefaultField` is `true`, the field will be added to the users collection automatically\n */\n includeDefaultField?: true\n /**\n * Additional fields to include on the tenants array field\n */\n rowFields?: Field[]\n /**\n * Access configuration for the tenant field\n */\n tenantFieldAccess?: RelationshipField['access']\n }\n | {\n arrayFieldAccess?: never\n arrayFieldName?: string\n arrayTenantFieldName?: string\n /**\n * When `includeDefaultField` is `false`, you must include the field on your users collection manually\n */\n includeDefaultField?: false\n rowFields?: never\n tenantFieldAccess?: never\n }\n /**\n * Customize tenant selector label\n *\n * Either a string or an object where the keys are i18n codes and the values are the string labels\n *\n * @deprecated Use `i18n.translations` instead.\n */\n tenantSelectorLabel?:\n | Partial<{\n [key in AcceptedLanguages]?: string\n }>\n | string\n /**\n * The slug for the tenant collection\n *\n * @default 'tenants'\n */\n tenantsSlug?: string\n /**\n * Function that determines if a user has access to _all_ tenants\n *\n * Useful for super-admin type users\n */\n userHasAccessToAllTenants?: (\n user: ConfigTypes extends { user: unknown } ? ConfigTypes['user'] : TypedUser,\n ) => boolean\n /**\n * Override the result of the admin `users` collection access control functions\n */\n usersAccessResultOverride?: ({\n accessKey,\n result,\n }: {\n accessKey: AllAccessKeys[number]\n result: AccessResult\n }) => AccessResult\n /**\n * Opt out of adding access constraints to the tenants collection\n */\n useTenantsCollectionAccess?: boolean\n /**\n * Opt out including the baseListFilter to filter tenants by selected tenant\n */\n useTenantsListFilter?: boolean\n\n /**\n * Opt out including the baseListFilter to filter users by selected tenant\n */\n useUsersTenantFilter?: boolean\n}\n\nexport type RootTenantFieldConfigOverrides = Partial<\n Omit<\n SingleRelationshipField,\n | '_sanitized'\n | 'hidden'\n | 'index'\n | 'localized'\n | 'max'\n | 'maxRows'\n | 'min'\n | 'minRows'\n | 'relationTo'\n | 'required'\n | 'type'\n | 'unique'\n | 'virtual'\n >\n>\n\nexport type CollectionTenantFieldConfigOverrides = Partial<\n Omit<RootTenantFieldConfigOverrides, 'name'>\n>\n\nexport type Tenant<IDType = number | string> = {\n id: IDType\n name: string\n}\n\nexport type UserWithTenantsField = {\n tenants?:\n | {\n tenant: number | string | Tenant\n }[]\n | null\n} & TypedUser\n\ntype AllAccessKeysT<T extends readonly string[]> = T[number] extends keyof Omit<\n Required<CollectionConfig>['access'],\n 'admin'\n>\n ? keyof Omit<Required<CollectionConfig>['access'], 'admin'> extends T[number]\n ? T\n : never\n : never\n\nexport type AllAccessKeys = AllAccessKeysT<\n ['create', 'read', 'update', 'delete', 'readVersions', 'unlock']\n>\n"],"names":[],"mappings":"AA8QA,WAEC"}
@@ -1,6 +1,8 @@
1
1
  import type { CollectionConfig } from 'payload';
2
- import type { MultiTenantPluginConfig } from '../types.js';
2
+ import type { AllAccessKeys, MultiTenantPluginConfig } from '../types.js';
3
+ export declare const collectionAccessKeys: AllAccessKeys;
3
4
  type Args<ConfigType> = {
5
+ accessResultCallback?: MultiTenantPluginConfig<ConfigType>['usersAccessResultOverride'];
4
6
  adminUsersSlug: string;
5
7
  collection: CollectionConfig;
6
8
  fieldName: string;
@@ -12,6 +14,6 @@ type Args<ConfigType> = {
12
14
  * Adds tenant access constraint to collection
13
15
  * - constrains access a users assigned tenants
14
16
  */
15
- export declare const addCollectionAccess: <ConfigType>({ adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => void;
17
+ export declare const addCollectionAccess: <ConfigType>({ accessResultCallback, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => void;
16
18
  export {};
17
19
  //# sourceMappingURL=addCollectionAccess.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"addCollectionAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/addCollectionAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAiB1D,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,6HAO3C,IAAI,CAAC,UAAU,CAAC,KAAG,IAerB,CAAA"}
1
+ {"version":3,"file":"addCollectionAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/addCollectionAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAIzE,eAAO,MAAM,oBAAoB,EAAE,aAOzB,CAAA;AAEV,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,oBAAoB,CAAC,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAC,2BAA2B,CAAC,CAAA;IACvF,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,mJAQ3C,IAAI,CAAC,UAAU,CAAC,KAAG,IAiBrB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { withTenantAccess } from './withTenantAccess.js';
2
- const collectionAccessKeys = [
2
+ export const collectionAccessKeys = [
3
3
  'create',
4
4
  'read',
5
5
  'update',
@@ -10,13 +10,15 @@ const collectionAccessKeys = [
10
10
  /**
11
11
  * Adds tenant access constraint to collection
12
12
  * - constrains access a users assigned tenants
13
- */ export const addCollectionAccess = ({ adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>{
13
+ */ export const addCollectionAccess = ({ accessResultCallback, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>{
14
14
  collectionAccessKeys.forEach((key)=>{
15
15
  if (!collection.access) {
16
16
  collection.access = {};
17
17
  }
18
18
  collection.access[key] = withTenantAccess({
19
19
  accessFunction: collection.access?.[key],
20
+ accessKey: key,
21
+ accessResultCallback,
20
22
  adminUsersSlug,
21
23
  collection,
22
24
  fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { withTenantAccess } from './withTenantAccess.js'\n\ntype AllAccessKeys<T extends readonly string[]> = T[number] extends keyof Omit<\n Required<CollectionConfig>['access'],\n 'admin'\n>\n ? keyof Omit<Required<CollectionConfig>['access'], 'admin'> extends T[number]\n ? T\n : never\n : never\n\nconst collectionAccessKeys: AllAccessKeys<\n ['create', 'read', 'update', 'delete', 'readVersions', 'unlock']\n> = ['create', 'read', 'update', 'delete', 'readVersions', 'unlock'] as const\n\ntype Args<ConfigType> = {\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\n\n/**\n * Adds tenant access constraint to collection\n * - constrains access a users assigned tenants\n */\nexport const addCollectionAccess = <ConfigType>({\n adminUsersSlug,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n}: Args<ConfigType>): void => {\n collectionAccessKeys.forEach((key) => {\n if (!collection.access) {\n collection.access = {}\n }\n collection.access[key] = withTenantAccess<ConfigType>({\n accessFunction: collection.access?.[key],\n adminUsersSlug,\n collection,\n fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n })\n}\n"],"names":["withTenantAccess","collectionAccessKeys","addCollectionAccess","adminUsersSlug","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","forEach","key","access","accessFunction"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,wBAAuB;AAWxD,MAAMC,uBAEF;IAAC;IAAU;IAAQ;IAAU;IAAU;IAAgB;CAAS;AAapE;;;CAGC,GACD,OAAO,MAAMC,sBAAsB,CAAa,EAC9CC,cAAc,EACdC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACR;IACjBP,qBAAqBQ,OAAO,CAAC,CAACC;QAC5B,IAAI,CAACN,WAAWO,MAAM,EAAE;YACtBP,WAAWO,MAAM,GAAG,CAAC;QACvB;QACAP,WAAWO,MAAM,CAACD,IAAI,GAAGV,iBAA6B;YACpDY,gBAAgBR,WAAWO,MAAM,EAAE,CAACD,IAAI;YACxCP;YACAC;YACAC,WAAWK,QAAQ,iBAAiB,CAAC,QAAQ,EAAEL,WAAW,GAAGA;YAC7DC;YACAC;YACAC;QACF;IACF;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { AllAccessKeys, MultiTenantPluginConfig } from '../types.js'\n\nimport { withTenantAccess } from './withTenantAccess.js'\n\nexport const collectionAccessKeys: AllAccessKeys = [\n 'create',\n 'read',\n 'update',\n 'delete',\n 'readVersions',\n 'unlock',\n] as const\n\ntype Args<ConfigType> = {\n accessResultCallback?: MultiTenantPluginConfig<ConfigType>['usersAccessResultOverride']\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\n\n/**\n * Adds tenant access constraint to collection\n * - constrains access a users assigned tenants\n */\nexport const addCollectionAccess = <ConfigType>({\n accessResultCallback,\n adminUsersSlug,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n}: Args<ConfigType>): void => {\n collectionAccessKeys.forEach((key) => {\n if (!collection.access) {\n collection.access = {}\n }\n collection.access[key] = withTenantAccess<ConfigType>({\n accessFunction: collection.access?.[key],\n accessKey: key,\n accessResultCallback,\n adminUsersSlug,\n collection,\n fieldName: key === 'readVersions' ? `version.${fieldName}` : fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n })\n })\n}\n"],"names":["withTenantAccess","collectionAccessKeys","addCollectionAccess","accessResultCallback","adminUsersSlug","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","forEach","key","access","accessFunction","accessKey"],"mappings":"AAIA,SAASA,gBAAgB,QAAQ,wBAAuB;AAExD,OAAO,MAAMC,uBAAsC;IACjD;IACA;IACA;IACA;IACA;IACA;CACD,CAAS;AAcV;;;CAGC,GACD,OAAO,MAAMC,sBAAsB,CAAa,EAC9CC,oBAAoB,EACpBC,cAAc,EACdC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACR;IACjBR,qBAAqBS,OAAO,CAAC,CAACC;QAC5B,IAAI,CAACN,WAAWO,MAAM,EAAE;YACtBP,WAAWO,MAAM,GAAG,CAAC;QACvB;QACAP,WAAWO,MAAM,CAACD,IAAI,GAAGX,iBAA6B;YACpDa,gBAAgBR,WAAWO,MAAM,EAAE,CAACD,IAAI;YACxCG,WAAWH;YACXR;YACAC;YACAC;YACAC,WAAWK,QAAQ,iBAAiB,CAAC,QAAQ,EAAEL,WAAW,GAAGA;YAC7DC;YACAC;YACAC;QACF;IACF;AACF,EAAC"}
@@ -37,7 +37,9 @@ export async function getGlobalViewRedirect({ slug: collectionSlug, basePath, do
37
37
  },
38
38
  where: {
39
39
  [tenantFieldName]: {
40
- equals: tenant
40
+ in: [
41
+ tenant
42
+ ]
41
43
  }
42
44
  }
43
45
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, TypedUser, ViewTypes } from 'payload'\n\nimport { unauthorized } from 'next/navigation.js'\nimport { formatAdminURL } from 'payload/shared'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\nimport { getTenantOptions } from './getTenantOptions.js'\n\ntype Args = {\n basePath?: string\n docID?: number | string\n headers: Headers\n payload: Payload\n slug: string\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: TypedUser\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig<any>>['userHasAccessToAllTenants']\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug: collectionSlug,\n basePath,\n docID,\n headers,\n payload,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n userHasAccessToAllTenants,\n view,\n}: Args): Promise<string | void> {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload,\n })\n let tenant = getTenantFromCookie(headers, idType)\n let redirectRoute: `/${string}` | void = undefined\n\n if (!user) {\n return unauthorized()\n }\n\n if (!tenant) {\n const tenantOptions = await getTenantOptions({\n payload,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n userHasAccessToAllTenants,\n })\n\n tenant = tenantOptions[0]?.value || null\n }\n\n if (tenant) {\n try {\n const globalTenantDocQuery = await payload.find({\n collection: collectionSlug,\n depth: 0,\n limit: 1,\n pagination: false,\n select: {\n id: true,\n },\n where: {\n [tenantFieldName]: {\n equals: tenant,\n },\n },\n })\n\n const globalTenantDocID = globalTenantDocQuery?.docs?.[0]?.id\n\n if (view === 'document') {\n // global tenant document edit view\n if (globalTenantDocID && docID !== globalTenantDocID) {\n // tenant document already exists but does not match current route docID\n // redirect to matching tenant docID from query\n redirectRoute = `/collections/${collectionSlug}/${globalTenantDocID}`\n } else if (docID && !globalTenantDocID) {\n // a docID was found in the route but no global document with this tenant exists\n // so we need to generate a redirect to the create route\n redirectRoute = await generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID: tenant,\n })\n }\n } else if (view === 'list') {\n // global tenant document list view\n if (globalTenantDocID) {\n // tenant document exists, redirect from list view to the document edit view\n redirectRoute = `/collections/${collectionSlug}/${globalTenantDocID}`\n } else {\n // no matching document was found for the current tenant\n // so we need to generate a redirect to the create route\n redirectRoute = await generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID: tenant,\n })\n }\n }\n } catch (e: unknown) {\n const prefix = `${e && typeof e === 'object' && 'message' in e && typeof e.message === 'string' ? `${e.message} - ` : ''}`\n payload.logger.error(e, `${prefix}Multi Tenant Redirect Error`)\n }\n } else {\n // no tenants were found, redirect to the admin view\n return formatAdminURL({\n adminRoute: payload.config.routes.admin,\n basePath,\n path: '',\n serverURL: payload.config.serverURL,\n })\n }\n\n if (redirectRoute) {\n return formatAdminURL({\n adminRoute: payload.config.routes.admin,\n basePath,\n path: redirectRoute,\n serverURL: payload.config.serverURL,\n })\n }\n\n // no redirect is needed\n // the current route is valid\n return undefined\n}\n\ntype GenerateCreateArgs = {\n collectionSlug: string\n payload: Payload\n tenantID: number | string\n}\n/**\n * Generate a redirect URL for creating a new document in a multi-tenant collection.\n *\n * If autosave is enabled on the collection, we need to create the document and then redirect to it.\n * Otherwise we can redirect to the default create route.\n */\nasync function generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID,\n}: GenerateCreateArgs): Promise<`/${string}` | undefined> {\n const collection = payload.collections[collectionSlug]\n if (\n collection?.config.versions?.drafts &&\n typeof collection.config.versions.drafts === 'object' &&\n collection.config.versions.drafts.autosave\n ) {\n // Autosave is enabled, create a document first\n try {\n const doc = await payload.create({\n collection: collectionSlug,\n data: {\n tenant: tenantID,\n },\n depth: 0,\n draft: true,\n select: {\n id: true,\n },\n })\n return `/collections/${collectionSlug}/${doc.id}`\n } catch (error) {\n payload.logger.error(\n error,\n `Error creating autosave global multi tenant document for ${collectionSlug}`,\n )\n }\n\n return '/'\n }\n\n // Autosave is not enabled, redirect to default create route\n return `/collections/${collectionSlug}/create`\n}\n"],"names":["unauthorized","formatAdminURL","getCollectionIDType","getTenantFromCookie","getTenantOptions","getGlobalViewRedirect","slug","collectionSlug","basePath","docID","headers","payload","tenantFieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","useAsTitle","user","userHasAccessToAllTenants","view","idType","tenant","redirectRoute","undefined","tenantOptions","value","globalTenantDocQuery","find","collection","depth","limit","pagination","select","id","where","equals","globalTenantDocID","docs","generateCreateRedirect","tenantID","e","prefix","message","logger","error","adminRoute","config","routes","admin","path","serverURL","collections","versions","drafts","autosave","doc","create","data","draft"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, TypedUser, ViewTypes } from 'payload'\n\nimport { unauthorized } from 'next/navigation.js'\nimport { formatAdminURL } from 'payload/shared'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { getCollectionIDType } from './getCollectionIDType.js'\nimport { getTenantFromCookie } from './getTenantFromCookie.js'\nimport { getTenantOptions } from './getTenantOptions.js'\n\ntype Args = {\n basePath?: string\n docID?: number | string\n headers: Headers\n payload: Payload\n slug: string\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: TypedUser\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig<any>>['userHasAccessToAllTenants']\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug: collectionSlug,\n basePath,\n docID,\n headers,\n payload,\n tenantFieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n userHasAccessToAllTenants,\n view,\n}: Args): Promise<string | void> {\n const idType = getCollectionIDType({\n collectionSlug: tenantsCollectionSlug,\n payload,\n })\n let tenant = getTenantFromCookie(headers, idType)\n let redirectRoute: `/${string}` | void = undefined\n\n if (!user) {\n return unauthorized()\n }\n\n if (!tenant) {\n const tenantOptions = await getTenantOptions({\n payload,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n tenantsCollectionSlug,\n useAsTitle,\n user,\n userHasAccessToAllTenants,\n })\n\n tenant = tenantOptions[0]?.value || null\n }\n\n if (tenant) {\n try {\n const globalTenantDocQuery = await payload.find({\n collection: collectionSlug,\n depth: 0,\n limit: 1,\n pagination: false,\n select: {\n id: true,\n },\n where: {\n [tenantFieldName]: {\n in: [tenant],\n },\n },\n })\n\n const globalTenantDocID = globalTenantDocQuery?.docs?.[0]?.id\n\n if (view === 'document') {\n // global tenant document edit view\n if (globalTenantDocID && docID !== globalTenantDocID) {\n // tenant document already exists but does not match current route docID\n // redirect to matching tenant docID from query\n redirectRoute = `/collections/${collectionSlug}/${globalTenantDocID}`\n } else if (docID && !globalTenantDocID) {\n // a docID was found in the route but no global document with this tenant exists\n // so we need to generate a redirect to the create route\n redirectRoute = await generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID: tenant,\n })\n }\n } else if (view === 'list') {\n // global tenant document list view\n if (globalTenantDocID) {\n // tenant document exists, redirect from list view to the document edit view\n redirectRoute = `/collections/${collectionSlug}/${globalTenantDocID}`\n } else {\n // no matching document was found for the current tenant\n // so we need to generate a redirect to the create route\n redirectRoute = await generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID: tenant,\n })\n }\n }\n } catch (e: unknown) {\n const prefix = `${e && typeof e === 'object' && 'message' in e && typeof e.message === 'string' ? `${e.message} - ` : ''}`\n payload.logger.error(e, `${prefix}Multi Tenant Redirect Error`)\n }\n } else {\n // no tenants were found, redirect to the admin view\n return formatAdminURL({\n adminRoute: payload.config.routes.admin,\n basePath,\n path: '',\n serverURL: payload.config.serverURL,\n })\n }\n\n if (redirectRoute) {\n return formatAdminURL({\n adminRoute: payload.config.routes.admin,\n basePath,\n path: redirectRoute,\n serverURL: payload.config.serverURL,\n })\n }\n\n // no redirect is needed\n // the current route is valid\n return undefined\n}\n\ntype GenerateCreateArgs = {\n collectionSlug: string\n payload: Payload\n tenantID: number | string\n}\n/**\n * Generate a redirect URL for creating a new document in a multi-tenant collection.\n *\n * If autosave is enabled on the collection, we need to create the document and then redirect to it.\n * Otherwise we can redirect to the default create route.\n */\nasync function generateCreateRedirect({\n collectionSlug,\n payload,\n tenantID,\n}: GenerateCreateArgs): Promise<`/${string}` | undefined> {\n const collection = payload.collections[collectionSlug]\n if (\n collection?.config.versions?.drafts &&\n typeof collection.config.versions.drafts === 'object' &&\n collection.config.versions.drafts.autosave\n ) {\n // Autosave is enabled, create a document first\n try {\n const doc = await payload.create({\n collection: collectionSlug,\n data: {\n tenant: tenantID,\n },\n depth: 0,\n draft: true,\n select: {\n id: true,\n },\n })\n return `/collections/${collectionSlug}/${doc.id}`\n } catch (error) {\n payload.logger.error(\n error,\n `Error creating autosave global multi tenant document for ${collectionSlug}`,\n )\n }\n\n return '/'\n }\n\n // Autosave is not enabled, redirect to default create route\n return `/collections/${collectionSlug}/create`\n}\n"],"names":["unauthorized","formatAdminURL","getCollectionIDType","getTenantFromCookie","getTenantOptions","getGlobalViewRedirect","slug","collectionSlug","basePath","docID","headers","payload","tenantFieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","useAsTitle","user","userHasAccessToAllTenants","view","idType","tenant","redirectRoute","undefined","tenantOptions","value","globalTenantDocQuery","find","collection","depth","limit","pagination","select","id","where","in","globalTenantDocID","docs","generateCreateRedirect","tenantID","e","prefix","message","logger","error","adminRoute","config","routes","admin","path","serverURL","collections","versions","drafts","autosave","doc","create","data","draft"],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import type { Access, AccessArgs, AccessResult, CollectionConfig } from 'payload';
2
- import type { MultiTenantPluginConfig } from '../types.js';
2
+ import type { AllAccessKeys, MultiTenantPluginConfig } from '../types.js';
3
3
  type Args<ConfigType> = {
4
4
  accessFunction?: Access;
5
+ accessKey: AllAccessKeys[number];
6
+ accessResultCallback?: MultiTenantPluginConfig<ConfigType>['usersAccessResultOverride'];
5
7
  adminUsersSlug: string;
6
8
  collection: CollectionConfig;
7
9
  fieldName: string;
@@ -9,6 +11,6 @@ type Args<ConfigType> = {
9
11
  tenantsArrayTenantFieldName?: string;
10
12
  userHasAccessToAllTenants: Required<MultiTenantPluginConfig<ConfigType>>['userHasAccessToAllTenants'];
11
13
  };
12
- export declare const withTenantAccess: <ConfigType>({ accessFunction, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => (args: AccessArgs) => Promise<AccessResult>;
14
+ export declare const withTenantAccess: <ConfigType>({ accessFunction, accessKey, accessResultCallback, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args<ConfigType>) => (args: AccessArgs) => Promise<AccessResult>;
13
15
  export {};
14
16
  //# sourceMappingURL=withTenantAccess.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"withTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/withTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAoB,MAAM,SAAS,CAAA;AAEnG,OAAO,KAAK,EAAE,uBAAuB,EAAwB,MAAM,aAAa,CAAA;AAKhF,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AACD,eAAO,MAAM,gBAAgB,GAC1B,UAAU,6IAQR,IAAI,CAAC,UAAU,CAAC,YACN,UAAU,KAAG,OAAO,CAAC,YAAY,CA6C7C,CAAA"}
1
+ {"version":3,"file":"withTenantAccess.d.ts","sourceRoot":"","sources":["../../src/utilities/withTenantAccess.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAoB,MAAM,SAAS,CAAA;AAEnG,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAwB,MAAM,aAAa,CAAA;AAK/F,KAAK,IAAI,CAAC,UAAU,IAAI;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAChC,oBAAoB,CAAC,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAC,2BAA2B,CAAC,CAAA;IACvF,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,yBAAyB,EAAE,QAAQ,CACjC,uBAAuB,CAAC,UAAU,CAAC,CACpC,CAAC,2BAA2B,CAAC,CAAA;CAC/B,CAAA;AACD,eAAO,MAAM,gBAAgB,GAC1B,UAAU,8KAUR,IAAI,CAAC,UAAU,CAAC,YACN,UAAU,KAAG,OAAO,CAAC,YAAY,CAgE7C,CAAA"}
@@ -1,10 +1,16 @@
1
1
  import { combineWhereConstraints } from './combineWhereConstraints.js';
2
2
  import { getTenantAccess } from './getTenantAccess.js';
3
- export const withTenantAccess = ({ accessFunction, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>async (args)=>{
3
+ export const withTenantAccess = ({ accessFunction, accessKey, accessResultCallback, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>async (args)=>{
4
4
  const constraints = [];
5
5
  const accessFn = typeof accessFunction === 'function' ? accessFunction : ({ req })=>Boolean(req.user);
6
6
  const accessResult = await accessFn(args);
7
7
  if (accessResult === false) {
8
+ if (accessResultCallback) {
9
+ return accessResultCallback({
10
+ accessKey,
11
+ result: false
12
+ });
13
+ }
8
14
  return false;
9
15
  } else if (accessResult && typeof accessResult === 'object') {
10
16
  constraints.push(accessResult);
@@ -30,8 +36,20 @@ export const withTenantAccess = ({ accessFunction, adminUsersSlug, collection, f
30
36
  } else {
31
37
  constraints.push(tenantConstraint);
32
38
  }
39
+ if (accessResultCallback) {
40
+ return accessResultCallback({
41
+ accessKey,
42
+ result: combineWhereConstraints(constraints)
43
+ });
44
+ }
33
45
  return combineWhereConstraints(constraints);
34
46
  }
47
+ if (accessResultCallback) {
48
+ return accessResultCallback({
49
+ accessKey,
50
+ result: accessResult
51
+ });
52
+ }
35
53
  return accessResult;
36
54
  };
37
55
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/withTenantAccess.ts"],"sourcesContent":["import type { Access, AccessArgs, AccessResult, CollectionConfig, TypedUser, Where } from 'payload'\n\nimport type { MultiTenantPluginConfig, UserWithTenantsField } from '../types.js'\n\nimport { combineWhereConstraints } from './combineWhereConstraints.js'\nimport { getTenantAccess } from './getTenantAccess.js'\n\ntype Args<ConfigType> = {\n accessFunction?: Access\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\nexport const withTenantAccess =\n <ConfigType>({\n accessFunction,\n adminUsersSlug,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n }: Args<ConfigType>) =>\n async (args: AccessArgs): Promise<AccessResult> => {\n const constraints: Where[] = []\n const accessFn =\n typeof accessFunction === 'function'\n ? accessFunction\n : ({ req }: AccessArgs): AccessResult => Boolean(req.user)\n const accessResult: AccessResult = await accessFn(args)\n\n if (accessResult === false) {\n return false\n } else if (accessResult && typeof accessResult === 'object') {\n constraints.push(accessResult)\n }\n\n if (\n args.req.user &&\n args.req.user.collection === adminUsersSlug &&\n !userHasAccessToAllTenants(\n args.req.user as ConfigType extends { user: unknown } ? ConfigType['user'] : TypedUser,\n )\n ) {\n const tenantConstraint = getTenantAccess({\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n user: args.req.user as UserWithTenantsField,\n })\n if (collection.slug === args.req.user.collection) {\n constraints.push({\n or: [\n {\n id: {\n equals: args.req.user.id,\n },\n },\n tenantConstraint,\n ],\n })\n } else {\n constraints.push(tenantConstraint)\n }\n return combineWhereConstraints(constraints)\n }\n\n return accessResult\n }\n"],"names":["combineWhereConstraints","getTenantAccess","withTenantAccess","accessFunction","adminUsersSlug","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","args","constraints","accessFn","req","Boolean","user","accessResult","push","tenantConstraint","slug","or","id","equals"],"mappings":"AAIA,SAASA,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,eAAe,QAAQ,uBAAsB;AAatD,OAAO,MAAMC,mBACX,CAAa,EACXC,cAAc,EACdC,cAAc,EACdC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACR,GACnB,OAAOC;QACL,MAAMC,cAAuB,EAAE;QAC/B,MAAMC,WACJ,OAAOT,mBAAmB,aACtBA,iBACA,CAAC,EAAEU,GAAG,EAAc,GAAmBC,QAAQD,IAAIE,IAAI;QAC7D,MAAMC,eAA6B,MAAMJ,SAASF;QAElD,IAAIM,iBAAiB,OAAO;YAC1B,OAAO;QACT,OAAO,IAAIA,gBAAgB,OAAOA,iBAAiB,UAAU;YAC3DL,YAAYM,IAAI,CAACD;QACnB;QAEA,IACEN,KAAKG,GAAG,CAACE,IAAI,IACbL,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,KAAKD,kBAC7B,CAACK,0BACCC,KAAKG,GAAG,CAACE,IAAI,GAEf;YACA,MAAMG,mBAAmBjB,gBAAgB;gBACvCK;gBACAC;gBACAC;gBACAO,MAAML,KAAKG,GAAG,CAACE,IAAI;YACrB;YACA,IAAIV,WAAWc,IAAI,KAAKT,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,EAAE;gBAChDM,YAAYM,IAAI,CAAC;oBACfG,IAAI;wBACF;4BACEC,IAAI;gCACFC,QAAQZ,KAAKG,GAAG,CAACE,IAAI,CAACM,EAAE;4BAC1B;wBACF;wBACAH;qBACD;gBACH;YACF,OAAO;gBACLP,YAAYM,IAAI,CAACC;YACnB;YACA,OAAOlB,wBAAwBW;QACjC;QAEA,OAAOK;IACT,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/withTenantAccess.ts"],"sourcesContent":["import type { Access, AccessArgs, AccessResult, CollectionConfig, TypedUser, Where } from 'payload'\n\nimport type { AllAccessKeys, MultiTenantPluginConfig, UserWithTenantsField } from '../types.js'\n\nimport { combineWhereConstraints } from './combineWhereConstraints.js'\nimport { getTenantAccess } from './getTenantAccess.js'\n\ntype Args<ConfigType> = {\n accessFunction?: Access\n accessKey: AllAccessKeys[number]\n accessResultCallback?: MultiTenantPluginConfig<ConfigType>['usersAccessResultOverride']\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<\n MultiTenantPluginConfig<ConfigType>\n >['userHasAccessToAllTenants']\n}\nexport const withTenantAccess =\n <ConfigType>({\n accessFunction,\n accessKey,\n accessResultCallback,\n adminUsersSlug,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n }: Args<ConfigType>) =>\n async (args: AccessArgs): Promise<AccessResult> => {\n const constraints: Where[] = []\n const accessFn =\n typeof accessFunction === 'function'\n ? accessFunction\n : ({ req }: AccessArgs): AccessResult => Boolean(req.user)\n const accessResult: AccessResult = await accessFn(args)\n\n if (accessResult === false) {\n if (accessResultCallback) {\n return accessResultCallback({\n accessKey,\n result: false,\n })\n }\n return false\n } else if (accessResult && typeof accessResult === 'object') {\n constraints.push(accessResult)\n }\n\n if (\n args.req.user &&\n args.req.user.collection === adminUsersSlug &&\n !userHasAccessToAllTenants(\n args.req.user as ConfigType extends { user: unknown } ? ConfigType['user'] : TypedUser,\n )\n ) {\n const tenantConstraint = getTenantAccess({\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n user: args.req.user as UserWithTenantsField,\n })\n if (collection.slug === args.req.user.collection) {\n constraints.push({\n or: [\n {\n id: {\n equals: args.req.user.id,\n },\n },\n tenantConstraint,\n ],\n })\n } else {\n constraints.push(tenantConstraint)\n }\n\n if (accessResultCallback) {\n return accessResultCallback({\n accessKey,\n result: combineWhereConstraints(constraints),\n })\n }\n return combineWhereConstraints(constraints)\n }\n\n if (accessResultCallback) {\n return accessResultCallback({\n accessKey,\n result: accessResult,\n })\n }\n return accessResult\n }\n"],"names":["combineWhereConstraints","getTenantAccess","withTenantAccess","accessFunction","accessKey","accessResultCallback","adminUsersSlug","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","args","constraints","accessFn","req","Boolean","user","accessResult","result","push","tenantConstraint","slug","or","id","equals"],"mappings":"AAIA,SAASA,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,eAAe,QAAQ,uBAAsB;AAetD,OAAO,MAAMC,mBACX,CAAa,EACXC,cAAc,EACdC,SAAS,EACTC,oBAAoB,EACpBC,cAAc,EACdC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACR,GACnB,OAAOC;QACL,MAAMC,cAAuB,EAAE;QAC/B,MAAMC,WACJ,OAAOX,mBAAmB,aACtBA,iBACA,CAAC,EAAEY,GAAG,EAAc,GAAmBC,QAAQD,IAAIE,IAAI;QAC7D,MAAMC,eAA6B,MAAMJ,SAASF;QAElD,IAAIM,iBAAiB,OAAO;YAC1B,IAAIb,sBAAsB;gBACxB,OAAOA,qBAAqB;oBAC1BD;oBACAe,QAAQ;gBACV;YACF;YACA,OAAO;QACT,OAAO,IAAID,gBAAgB,OAAOA,iBAAiB,UAAU;YAC3DL,YAAYO,IAAI,CAACF;QACnB;QAEA,IACEN,KAAKG,GAAG,CAACE,IAAI,IACbL,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,KAAKD,kBAC7B,CAACK,0BACCC,KAAKG,GAAG,CAACE,IAAI,GAEf;YACA,MAAMI,mBAAmBpB,gBAAgB;gBACvCO;gBACAC;gBACAC;gBACAO,MAAML,KAAKG,GAAG,CAACE,IAAI;YACrB;YACA,IAAIV,WAAWe,IAAI,KAAKV,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,EAAE;gBAChDM,YAAYO,IAAI,CAAC;oBACfG,IAAI;wBACF;4BACEC,IAAI;gCACFC,QAAQb,KAAKG,GAAG,CAACE,IAAI,CAACO,EAAE;4BAC1B;wBACF;wBACAH;qBACD;gBACH;YACF,OAAO;gBACLR,YAAYO,IAAI,CAACC;YACnB;YAEA,IAAIhB,sBAAsB;gBACxB,OAAOA,qBAAqB;oBAC1BD;oBACAe,QAAQnB,wBAAwBa;gBAClC;YACF;YACA,OAAOb,wBAAwBa;QACjC;QAEA,IAAIR,sBAAsB;YACxB,OAAOA,qBAAqB;gBAC1BD;gBACAe,QAAQD;YACV;QACF;QACA,OAAOA;IACT,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-multi-tenant",
3
- "version": "3.60.0-canary.1",
3
+ "version": "3.60.0-canary.3",
4
4
  "description": "Multi Tenant plugin for Payload",
5
5
  "keywords": [
6
6
  "payload",
@@ -81,14 +81,14 @@
81
81
  ],
82
82
  "devDependencies": {
83
83
  "@payloadcms/eslint-config": "3.28.0",
84
- "@payloadcms/ui": "3.60.0-canary.1",
85
- "@payloadcms/translations": "3.60.0-canary.1",
86
- "payload": "3.60.0-canary.1"
84
+ "@payloadcms/translations": "3.60.0-canary.3",
85
+ "@payloadcms/ui": "3.60.0-canary.3",
86
+ "payload": "3.60.0-canary.3"
87
87
  },
88
88
  "peerDependencies": {
89
89
  "next": "^15.2.3",
90
- "@payloadcms/ui": "3.60.0-canary.1",
91
- "payload": "3.60.0-canary.1"
90
+ "@payloadcms/ui": "3.60.0-canary.3",
91
+ "payload": "3.60.0-canary.3"
92
92
  },
93
93
  "homepage:": "https://payloadcms.com",
94
94
  "scripts": {