@payloadcms/plugin-multi-tenant 4.0.0-internal.c7d5de4 → 4.0.0-internal.cb69780
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.
- package/dist/components/AssignTenantFieldModal/index.client.d.ts +2 -2
- package/dist/components/AssignTenantFieldModal/index.client.d.ts.map +1 -1
- package/dist/components/AssignTenantFieldModal/index.client.js.map +1 -1
- package/dist/components/TenantField/index.client.d.ts.map +1 -1
- package/dist/components/TenantField/index.client.js +84 -74
- package/dist/components/TenantField/index.client.js.map +1 -1
- package/dist/fields/tenantField/index.d.ts +4 -2
- package/dist/fields/tenantField/index.d.ts.map +1 -1
- package/dist/fields/tenantField/index.js +36 -9
- package/dist/fields/tenantField/index.js.map +1 -1
- package/dist/hooks/afterTenantDelete.d.ts.map +1 -1
- package/dist/hooks/afterTenantDelete.js +3 -0
- package/dist/hooks/afterTenantDelete.js.map +1 -1
- package/dist/hooks/enforceTenantMembership.d.ts +15 -0
- package/dist/hooks/enforceTenantMembership.d.ts.map +1 -0
- package/dist/hooks/enforceTenantMembership.js +39 -0
- package/dist/hooks/enforceTenantMembership.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -4
- package/dist/index.js.map +1 -1
- package/dist/providers/TenantSelectionProvider/index.client.d.ts.map +1 -1
- package/dist/providers/TenantSelectionProvider/index.client.js +22 -24
- package/dist/providers/TenantSelectionProvider/index.client.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/addCollectionAccess.d.ts +6 -8
- package/dist/utilities/addCollectionAccess.d.ts.map +1 -1
- package/dist/utilities/addCollectionAccess.js +91 -20
- package/dist/utilities/addCollectionAccess.js.map +1 -1
- package/dist/utilities/getGlobalViewRedirect.d.ts.map +1 -1
- package/dist/utilities/getGlobalViewRedirect.js +2 -0
- package/dist/utilities/getGlobalViewRedirect.js.map +1 -1
- package/dist/utilities/getTenantIDsFromValue.d.ts +2 -0
- package/dist/utilities/getTenantIDsFromValue.d.ts.map +1 -0
- package/dist/utilities/getTenantIDsFromValue.js +14 -0
- package/dist/utilities/getTenantIDsFromValue.js.map +1 -0
- package/dist/utilities/getUserTenantIDs.d.ts.map +1 -1
- package/dist/utilities/getUserTenantIDs.js +3 -2
- package/dist/utilities/getUserTenantIDs.js.map +1 -1
- package/dist/utilities/isValidTenantAssignment.d.ts +13 -0
- package/dist/utilities/isValidTenantAssignment.d.ts.map +1 -0
- package/dist/utilities/isValidTenantAssignment.js +28 -0
- package/dist/utilities/isValidTenantAssignment.js.map +1 -0
- package/dist/utilities/shouldRefreshTenantSelection.d.ts +5 -0
- package/dist/utilities/shouldRefreshTenantSelection.d.ts.map +1 -0
- package/dist/utilities/shouldRefreshTenantSelection.js +3 -0
- package/dist/utilities/shouldRefreshTenantSelection.js.map +1 -0
- package/package.json +7 -8
- package/dist/utilities/combineWhereConstraints.d.ts +0 -3
- package/dist/utilities/combineWhereConstraints.d.ts.map +0 -1
- package/dist/utilities/combineWhereConstraints.js +0 -19
- package/dist/utilities/combineWhereConstraints.js.map +0 -1
- package/dist/utilities/withTenantAccess.d.ts +0 -16
- package/dist/utilities/withTenantAccess.d.ts.map +0 -1
- package/dist/utilities/withTenantAccess.js +0 -76
- package/dist/utilities/withTenantAccess.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getTenantAccess } from './getTenantAccess.js';
|
|
2
2
|
export const collectionAccessKeys = [
|
|
3
3
|
'create',
|
|
4
4
|
'read',
|
|
@@ -7,26 +7,97 @@ export const collectionAccessKeys = [
|
|
|
7
7
|
'readVersions',
|
|
8
8
|
'unlock'
|
|
9
9
|
];
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
10
|
+
const getTenantAccessResult = ({ accessKey, accessResult, accessResultCallback, adminUsersSlug, args, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>{
|
|
11
|
+
const finish = (result)=>accessResultCallback ? accessResultCallback({
|
|
12
|
+
accessKey,
|
|
13
|
+
accessResult: result,
|
|
14
|
+
...args
|
|
15
|
+
}) : result;
|
|
16
|
+
if (!accessResult) {
|
|
17
|
+
return finish(false);
|
|
18
|
+
}
|
|
19
|
+
const user = args.req.user;
|
|
20
|
+
if (!user || user.collection !== adminUsersSlug || userHasAccessToAllTenants(user)) {
|
|
21
|
+
return finish(accessResult);
|
|
22
|
+
}
|
|
23
|
+
const tenantConstraint = getTenantAccess({
|
|
24
|
+
fieldName,
|
|
25
|
+
tenantsArrayFieldName,
|
|
26
|
+
tenantsArrayTenantFieldName,
|
|
27
|
+
user
|
|
28
|
+
});
|
|
29
|
+
if (tenantConstraint[fieldName]?.in.length === 0) {
|
|
30
|
+
return finish(collection.slug === user.collection ? {
|
|
31
|
+
id: {
|
|
32
|
+
equals: user.id
|
|
33
|
+
}
|
|
34
|
+
} : false);
|
|
35
|
+
}
|
|
36
|
+
const tenantResult = collection.slug === user.collection ? {
|
|
37
|
+
or: [
|
|
38
|
+
{
|
|
39
|
+
id: {
|
|
40
|
+
equals: user.id
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
tenantConstraint
|
|
44
|
+
]
|
|
45
|
+
} : tenantConstraint;
|
|
46
|
+
return finish(accessResult === true ? tenantResult : {
|
|
47
|
+
and: [
|
|
48
|
+
accessResult,
|
|
49
|
+
tenantResult
|
|
50
|
+
]
|
|
29
51
|
});
|
|
30
52
|
};
|
|
53
|
+
const wrapCollectionAccess = (scope)=>{
|
|
54
|
+
scope.collection.access ??= {};
|
|
55
|
+
for (const accessKey of collectionAccessKeys){
|
|
56
|
+
const accessFunction = scope.collection.access[accessKey] ?? (({ req })=>Boolean(req.user));
|
|
57
|
+
scope.collection.access[accessKey] = async (args)=>getTenantAccessResult({
|
|
58
|
+
...scope,
|
|
59
|
+
accessKey,
|
|
60
|
+
accessResult: await accessFunction(args),
|
|
61
|
+
args,
|
|
62
|
+
fieldName: accessKey === 'readVersions' ? `version.${scope.fieldName}` : scope.fieldName
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
export const addCollectionAccess = ({ config, scopes })=>{
|
|
67
|
+
const baseAccessScopes = new Map();
|
|
68
|
+
for (const scope of scopes){
|
|
69
|
+
if (scope.accessResultCallback) {
|
|
70
|
+
wrapCollectionAccess(scope);
|
|
71
|
+
} else {
|
|
72
|
+
baseAccessScopes.set(scope.collection.slug, scope);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!baseAccessScopes.size) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
config.baseAccess ??= {};
|
|
79
|
+
config.baseAccess.collections ??= {};
|
|
80
|
+
for (const accessKey of collectionAccessKeys){
|
|
81
|
+
const baseAccessFunction = config.baseAccess.collections[accessKey];
|
|
82
|
+
config.baseAccess.collections[accessKey] = async (args)=>{
|
|
83
|
+
const baseResult = baseAccessFunction ? await baseAccessFunction(args) : true;
|
|
84
|
+
const scope = baseAccessScopes.get(args.slug);
|
|
85
|
+
if (!baseResult || !scope) {
|
|
86
|
+
return baseResult;
|
|
87
|
+
}
|
|
88
|
+
if (accessKey === 'create' && typeof baseResult === 'object') {
|
|
89
|
+
return baseResult;
|
|
90
|
+
}
|
|
91
|
+
const tenantResult = await getTenantAccessResult({
|
|
92
|
+
...scope,
|
|
93
|
+
accessKey,
|
|
94
|
+
accessResult: baseResult,
|
|
95
|
+
args,
|
|
96
|
+
fieldName: accessKey === 'readVersions' ? `version.${scope.fieldName}` : scope.fieldName
|
|
97
|
+
});
|
|
98
|
+
return accessKey === 'create' ? Boolean(tenantResult) : tenantResult;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
};
|
|
31
102
|
|
|
32
103
|
//# sourceMappingURL=addCollectionAccess.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { AllAccessKeys, MultiTenantPluginConfig } from '../types.js'\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/addCollectionAccess.ts"],"sourcesContent":["import type { AccessArgs, AccessResult, CollectionConfig, Config, User, Where } from 'payload'\n\nimport type { AllAccessKeys, MultiTenantPluginConfig } from '../types.js'\n\nimport { getTenantAccess } from './getTenantAccess.js'\n\nexport const collectionAccessKeys: AllAccessKeys = [\n 'create',\n 'read',\n 'update',\n 'delete',\n 'readVersions',\n 'unlock',\n] as const\n\nexport type TenantAccessConfig = {\n accessResultCallback?: MultiTenantPluginConfig['usersAccessResultOverride']\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n}\n\nconst getTenantAccessResult = ({\n accessKey,\n accessResult,\n accessResultCallback,\n adminUsersSlug,\n args,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n}: {\n accessKey: AllAccessKeys[number]\n accessResult: AccessResult\n args: AccessArgs\n} & TenantAccessConfig): AccessResult | Promise<AccessResult> => {\n const finish = (result: AccessResult): AccessResult | Promise<AccessResult> =>\n accessResultCallback\n ? accessResultCallback({ accessKey, accessResult: result, ...args })\n : result\n\n if (!accessResult) {\n return finish(false)\n }\n\n const user = args.req.user\n\n if (!user || user.collection !== adminUsersSlug || userHasAccessToAllTenants(user as User)) {\n return finish(accessResult)\n }\n\n const tenantConstraint = getTenantAccess({\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n user,\n })\n\n if (tenantConstraint[fieldName]?.in.length === 0) {\n return finish(collection.slug === user.collection ? { id: { equals: user.id } } : false)\n }\n\n const tenantResult: Where =\n collection.slug === user.collection\n ? { or: [{ id: { equals: user.id } }, tenantConstraint] }\n : tenantConstraint\n\n return finish(accessResult === true ? tenantResult : { and: [accessResult, tenantResult] })\n}\n\nconst wrapCollectionAccess = (scope: TenantAccessConfig): void => {\n scope.collection.access ??= {}\n\n for (const accessKey of collectionAccessKeys) {\n const accessFunction =\n scope.collection.access[accessKey] ?? (({ req }: AccessArgs) => Boolean(req.user))\n\n scope.collection.access[accessKey] = async (args) =>\n getTenantAccessResult({\n ...scope,\n accessKey,\n accessResult: await accessFunction(args),\n args,\n fieldName: accessKey === 'readVersions' ? `version.${scope.fieldName}` : scope.fieldName,\n })\n }\n}\n\nexport const addCollectionAccess = ({\n config,\n scopes,\n}: {\n config: Config\n scopes: TenantAccessConfig[]\n}): void => {\n const baseAccessScopes = new Map<string, TenantAccessConfig>()\n\n for (const scope of scopes) {\n if (scope.accessResultCallback) {\n wrapCollectionAccess(scope)\n } else {\n baseAccessScopes.set(scope.collection.slug, scope)\n }\n }\n\n if (!baseAccessScopes.size) {\n return\n }\n\n config.baseAccess ??= {}\n config.baseAccess.collections ??= {}\n\n for (const accessKey of collectionAccessKeys) {\n const baseAccessFunction = config.baseAccess.collections[accessKey]\n\n config.baseAccess.collections[accessKey] = async (args) => {\n const baseResult = baseAccessFunction ? await baseAccessFunction(args) : true\n const scope = baseAccessScopes.get(args.slug)\n\n if (!baseResult || !scope) {\n return baseResult\n }\n\n if (accessKey === 'create' && typeof baseResult === 'object') {\n return baseResult\n }\n\n const tenantResult = await getTenantAccessResult({\n ...scope,\n accessKey,\n accessResult: baseResult,\n args,\n fieldName: accessKey === 'readVersions' ? `version.${scope.fieldName}` : scope.fieldName,\n })\n\n return accessKey === 'create' ? Boolean(tenantResult) : tenantResult\n }\n }\n}\n"],"names":["getTenantAccess","collectionAccessKeys","getTenantAccessResult","accessKey","accessResult","accessResultCallback","adminUsersSlug","args","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","finish","result","user","req","tenantConstraint","in","length","slug","id","equals","tenantResult","or","and","wrapCollectionAccess","scope","access","accessFunction","Boolean","addCollectionAccess","config","scopes","baseAccessScopes","Map","set","size","baseAccess","collections","baseAccessFunction","baseResult","get"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getGlobalViewRedirect.d.ts","sourceRoot":"","sources":["../../src/utilities/getGlobalViewRedirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAItE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAM1D,KAAK,IAAI,GAAG;IACV;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,yBAAyB,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC,2BAA2B,CAAC,CAAA;IACzF,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AACD,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EAAE,cAAc,EACpB,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,UAAU,EACV,IAAI,EACJ,yBAAyB,EACzB,IAAI,GACL,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"getGlobalViewRedirect.d.ts","sourceRoot":"","sources":["../../src/utilities/getGlobalViewRedirect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAItE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAM1D,KAAK,IAAI,GAAG;IACV;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,MAAM,CAAA;IACvB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,yBAAyB,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC,2BAA2B,CAAC,CAAA;IACzF,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AACD,wBAAsB,qBAAqB,CAAC,EAC1C,IAAI,EAAE,cAAc,EACpB,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,eAAe,EACf,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,UAAU,EACV,IAAI,EACJ,yBAAyB,EACzB,IAAI,GACL,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoG/B"}
|
|
@@ -30,6 +30,7 @@ export async function getGlobalViewRedirect({ slug: collectionSlug, docID, heade
|
|
|
30
30
|
collection: collectionSlug,
|
|
31
31
|
depth: 0,
|
|
32
32
|
limit: 1,
|
|
33
|
+
overrideAccess: true,
|
|
33
34
|
pagination: false,
|
|
34
35
|
select: {
|
|
35
36
|
id: true
|
|
@@ -113,6 +114,7 @@ export async function getGlobalViewRedirect({ slug: collectionSlug, docID, heade
|
|
|
113
114
|
},
|
|
114
115
|
depth: 0,
|
|
115
116
|
draft: true,
|
|
117
|
+
overrideAccess: true,
|
|
116
118
|
select: {
|
|
117
119
|
id: true
|
|
118
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, ServerAdapter, User, ViewTypes } from 'payload'\n\nimport { formatAdminURL, hasAutosaveEnabled } 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 /**\n * This is no longer needed and is handled internally.\n *\n * @deprecated\n */\n basePath?: string\n docID?: number | string\n headers: Headers\n payload: Payload\n server: ServerAdapter\n slug: string\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: User\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug: collectionSlug,\n docID,\n headers,\n payload,\n server,\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 server.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 path: '',\n serverURL: payload.config.serverURL,\n })\n }\n\n if (redirectRoute) {\n return formatAdminURL({\n adminRoute: payload.config.routes.admin,\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 collectionConfig = payload.collections[collectionSlug]?.config\n if (hasAutosaveEnabled(collectionConfig!)) {\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":["formatAdminURL","hasAutosaveEnabled","getCollectionIDType","getTenantFromCookie","getTenantOptions","getGlobalViewRedirect","slug","collectionSlug","docID","headers","payload","server","tenantFieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","useAsTitle","user","userHasAccessToAllTenants","view","idType","tenant","redirectRoute","undefined","unauthorized","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","collectionConfig","collections","doc","create","data","draft"],"mappings":"AAEA,SAASA,cAAc,EAAEC,kBAAkB,QAAQ,iBAAgB;AAInE,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,gBAAgB,QAAQ,wBAAuB;AAuBxD,OAAO,eAAeC,sBAAsB,EAC1CC,MAAMC,cAAc,EACpBC,KAAK,EACLC,OAAO,EACPC,OAAO,EACPC,MAAM,EACNC,eAAe,EACfC,qBAAqB,EACrBC,2BAA2B,EAC3BC,qBAAqB,EACrBC,UAAU,EACVC,IAAI,EACJC,yBAAyB,EACzBC,IAAI,EACC;IACL,MAAMC,SAASlB,oBAAoB;QACjCK,gBAAgBQ;QAChBL;IACF;IACA,IAAIW,SAASlB,oBAAoBM,SAASW;IAC1C,IAAIE,gBAAqCC;IAEzC,IAAI,CAACN,MAAM;QACT,OAAON,OAAOa,YAAY;IAC5B;IAEA,IAAI,CAACH,QAAQ;QACX,MAAMI,gBAAgB,MAAMrB,iBAAiB;YAC3CM;YACAG;YACAC;YACAC;YACAC;YACAC;YACAC;QACF;QAEAG,SAASI,aAAa,CAAC,EAAE,EAAEC,SAAS;IACtC;IAEA,IAAIL,QAAQ;QACV,IAAI;YACF,MAAMM,uBAAuB,MAAMjB,QAAQkB,IAAI,CAAC;gBAC9CC,YAAYtB;gBACZuB,OAAO;gBACPC,OAAO;gBACPC,YAAY;gBACZC,QAAQ;oBACNC,IAAI;gBACN;gBACAC,OAAO;oBACL,
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getGlobalViewRedirect.ts"],"sourcesContent":["import type { Payload, ServerAdapter, User, ViewTypes } from 'payload'\n\nimport { formatAdminURL, hasAutosaveEnabled } 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 /**\n * This is no longer needed and is handled internally.\n *\n * @deprecated\n */\n basePath?: string\n docID?: number | string\n headers: Headers\n payload: Payload\n server: ServerAdapter\n slug: string\n tenantFieldName: string\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n tenantsCollectionSlug: string\n useAsTitle: string\n user?: User\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n view: ViewTypes\n}\nexport async function getGlobalViewRedirect({\n slug: collectionSlug,\n docID,\n headers,\n payload,\n server,\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 server.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 overrideAccess: true,\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 path: '',\n serverURL: payload.config.serverURL,\n })\n }\n\n if (redirectRoute) {\n return formatAdminURL({\n adminRoute: payload.config.routes.admin,\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 collectionConfig = payload.collections[collectionSlug]?.config\n if (hasAutosaveEnabled(collectionConfig!)) {\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 overrideAccess: 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":["formatAdminURL","hasAutosaveEnabled","getCollectionIDType","getTenantFromCookie","getTenantOptions","getGlobalViewRedirect","slug","collectionSlug","docID","headers","payload","server","tenantFieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsCollectionSlug","useAsTitle","user","userHasAccessToAllTenants","view","idType","tenant","redirectRoute","undefined","unauthorized","tenantOptions","value","globalTenantDocQuery","find","collection","depth","limit","overrideAccess","pagination","select","id","where","in","globalTenantDocID","docs","generateCreateRedirect","tenantID","e","prefix","message","logger","error","adminRoute","config","routes","admin","path","serverURL","collectionConfig","collections","doc","create","data","draft"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTenantIDsFromValue.d.ts","sourceRoot":"","sources":["../../src/utilities/getTenantIDsFromValue.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,qBAAqB,UAAW,OAAO,KAAG,MAAM,EAU5D,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { extractID } from './extractID.js';
|
|
2
|
+
export const getTenantIDsFromValue = (value)=>{
|
|
3
|
+
if (value === undefined || value === null) {
|
|
4
|
+
return [];
|
|
5
|
+
}
|
|
6
|
+
return (Array.isArray(value) ? value : [
|
|
7
|
+
value
|
|
8
|
+
]).map((entry)=>{
|
|
9
|
+
const id = entry === null || entry === undefined ? undefined : extractID(entry);
|
|
10
|
+
return typeof id === 'number' || typeof id === 'string' ? String(id) : '';
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=getTenantIDsFromValue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getTenantIDsFromValue.ts"],"sourcesContent":["import type { Tenant } from '../types.js'\n\nimport { extractID } from './extractID.js'\n\nexport const getTenantIDsFromValue = (value: unknown): string[] => {\n if (value === undefined || value === null) {\n return []\n }\n\n return (Array.isArray(value) ? value : [value]).map((entry) => {\n const id = entry === null || entry === undefined ? undefined : extractID(entry as Tenant)\n\n return typeof id === 'number' || typeof id === 'string' ? String(id) : ''\n })\n}\n"],"names":["extractID","getTenantIDsFromValue","value","undefined","Array","isArray","map","entry","id","String"],"mappings":"AAEA,SAASA,SAAS,QAAQ,iBAAgB;AAE1C,OAAO,MAAMC,wBAAwB,CAACC;IACpC,IAAIA,UAAUC,aAAaD,UAAU,MAAM;QACzC,OAAO,EAAE;IACX;IAEA,OAAO,AAACE,CAAAA,MAAMC,OAAO,CAACH,SAASA,QAAQ;QAACA;KAAM,AAAD,EAAGI,GAAG,CAAC,CAACC;QACnD,MAAMC,KAAKD,UAAU,QAAQA,UAAUJ,YAAYA,YAAYH,UAAUO;QAEzE,OAAO,OAAOC,OAAO,YAAY,OAAOA,OAAO,WAAWC,OAAOD,MAAM;IACzE;AACF,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUserTenantIDs.d.ts","sourceRoot":"","sources":["../../src/utilities/getUserTenantIDs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAK/D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,QACvD,IAAI,GAAG,oBAAoB,YACvB;IACR,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;CACrC,KACA,MAAM,
|
|
1
|
+
{"version":3,"file":"getUserTenantIDs.d.ts","sourceRoot":"","sources":["../../src/utilities/getUserTenantIDs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAK/D;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,MAAM,GAAG,MAAM,QACvD,IAAI,GAAG,oBAAoB,YACvB;IACR,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,2BAA2B,CAAC,EAAE,MAAM,CAAA;CACrC,KACA,MAAM,EAqBR,CAAA"}
|
|
@@ -12,8 +12,9 @@ import { extractID } from './extractID.js';
|
|
|
12
12
|
const tenantsArrayTenantFieldName = options?.tenantsArrayTenantFieldName || defaults.tenantsArrayTenantFieldName;
|
|
13
13
|
const tenantsArray = user[tenantsArrayFieldName];
|
|
14
14
|
return (Array.isArray(tenantsArray) ? tenantsArray : [])?.reduce((acc, row)=>{
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const tenantRow = row[tenantsArrayTenantFieldName];
|
|
16
|
+
if (tenantRow !== undefined && tenantRow !== null) {
|
|
17
|
+
acc.push(extractID(tenantRow));
|
|
17
18
|
}
|
|
18
19
|
return acc;
|
|
19
20
|
}, []) || [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getUserTenantIDs.ts"],"sourcesContent":["import type { Tenant, UserWithTenantsField } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { extractID } from './extractID.js'\n\n/**\n * Returns array of all tenant IDs assigned to a user\n *\n * @param user - User object with tenants field\n */\nexport const getUserTenantIDs = <IDType extends number | string>(\n user: null | UserWithTenantsField,\n options?: {\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n },\n): IDType[] => {\n if (!user) {\n return []\n }\n\n const tenantsArrayFieldName = options?.tenantsArrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n options?.tenantsArrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n\n const tenantsArray = (user as Record<string, unknown>)[tenantsArrayFieldName]\n\n return (\n (Array.isArray(tenantsArray) ? tenantsArray : [])?.reduce<IDType[]>((acc, row) => {\n
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getUserTenantIDs.ts"],"sourcesContent":["import type { Tenant, UserWithTenantsField } from '../types.js'\n\nimport { defaults } from '../defaults.js'\nimport { extractID } from './extractID.js'\n\n/**\n * Returns array of all tenant IDs assigned to a user\n *\n * @param user - User object with tenants field\n */\nexport const getUserTenantIDs = <IDType extends number | string>(\n user: null | UserWithTenantsField,\n options?: {\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n },\n): IDType[] => {\n if (!user) {\n return []\n }\n\n const tenantsArrayFieldName = options?.tenantsArrayFieldName || defaults.tenantsArrayFieldName\n const tenantsArrayTenantFieldName =\n options?.tenantsArrayTenantFieldName || defaults.tenantsArrayTenantFieldName\n\n const tenantsArray = (user as Record<string, unknown>)[tenantsArrayFieldName]\n\n return (\n (Array.isArray(tenantsArray) ? tenantsArray : [])?.reduce<IDType[]>((acc, row) => {\n const tenantRow = row[tenantsArrayTenantFieldName] as Tenant<IDType>\n if (tenantRow !== undefined && tenantRow !== null) {\n acc.push(extractID(tenantRow))\n }\n\n return acc\n }, []) || []\n )\n}\n"],"names":["defaults","extractID","getUserTenantIDs","user","options","tenantsArrayFieldName","tenantsArrayTenantFieldName","tenantsArray","Array","isArray","reduce","acc","row","tenantRow","undefined","push"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,SAAS,QAAQ,iBAAgB;AAE1C;;;;CAIC,GACD,OAAO,MAAMC,mBAAmB,CAC9BC,MACAC;IAKA,IAAI,CAACD,MAAM;QACT,OAAO,EAAE;IACX;IAEA,MAAME,wBAAwBD,SAASC,yBAAyBL,SAASK,qBAAqB;IAC9F,MAAMC,8BACJF,SAASE,+BAA+BN,SAASM,2BAA2B;IAE9E,MAAMC,eAAe,AAACJ,IAAgC,CAACE,sBAAsB;IAE7E,OACE,AAACG,CAAAA,MAAMC,OAAO,CAACF,gBAAgBA,eAAe,EAAE,AAAD,GAAIG,OAAiB,CAACC,KAAKC;QACxE,MAAMC,YAAYD,GAAG,CAACN,4BAA4B;QAClD,IAAIO,cAAcC,aAAaD,cAAc,MAAM;YACjDF,IAAII,IAAI,CAACd,UAAUY;QACrB;QAEA,OAAOF;IACT,GAAG,EAAE,KAAK,EAAE;AAEhB,EAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PayloadRequest } from 'payload';
|
|
2
|
+
import type { MultiTenantPluginConfig } from '../types.js';
|
|
3
|
+
type Args = {
|
|
4
|
+
previousValue?: unknown;
|
|
5
|
+
req: PayloadRequest;
|
|
6
|
+
tenantsArrayFieldName: string;
|
|
7
|
+
tenantsArrayTenantFieldName: string;
|
|
8
|
+
userHasAccessToAllTenants?: MultiTenantPluginConfig['userHasAccessToAllTenants'];
|
|
9
|
+
value: unknown;
|
|
10
|
+
};
|
|
11
|
+
export declare const isValidTenantAssignment: ({ previousValue, req, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, value, }: Args) => boolean;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=isValidTenantAssignment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isValidTenantAssignment.d.ts","sourceRoot":"","sources":["../../src/utilities/isValidTenantAssignment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAK1D,KAAK,IAAI,GAAG;IACV,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,GAAG,EAAE,cAAc,CAAA;IACnB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,2BAA2B,EAAE,MAAM,CAAA;IACnC,yBAAyB,CAAC,EAAE,uBAAuB,CAAC,2BAA2B,CAAC,CAAA;IAChF,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,eAAO,MAAM,uBAAuB,kHAOjC,IAAI,KAAG,OAgCT,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getTenantIDsFromValue } from './getTenantIDsFromValue.js';
|
|
2
|
+
import { getUserTenantIDs } from './getUserTenantIDs.js';
|
|
3
|
+
export const isValidTenantAssignment = ({ previousValue, req, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, value })=>{
|
|
4
|
+
const { user } = req;
|
|
5
|
+
if (user) {
|
|
6
|
+
if (userHasAccessToAllTenants?.(user)) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
} else if (req.payloadAPI === 'local') {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
const submittedDocumentTenantIDs = getTenantIDsFromValue(value);
|
|
13
|
+
const storedDocumentTenantIDs = getTenantIDsFromValue(previousValue);
|
|
14
|
+
if (!hasTenantValueChanged(submittedDocumentTenantIDs, storedDocumentTenantIDs)) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (submittedDocumentTenantIDs.length === 0) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const userAssignedTenantIDs = getUserTenantIDs(user, {
|
|
21
|
+
tenantsArrayFieldName,
|
|
22
|
+
tenantsArrayTenantFieldName
|
|
23
|
+
});
|
|
24
|
+
return submittedDocumentTenantIDs.every((tenantID)=>userAssignedTenantIDs.some((userAssignedTenantID)=>String(userAssignedTenantID) === String(tenantID)));
|
|
25
|
+
};
|
|
26
|
+
const hasTenantValueChanged = (submittedTenantIDs, storedTenantIDs)=>submittedTenantIDs.length !== storedTenantIDs.length || submittedTenantIDs.some((tenantID)=>!storedTenantIDs.includes(tenantID));
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=isValidTenantAssignment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/isValidTenantAssignment.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport type { MultiTenantPluginConfig } from '../types.js'\n\nimport { getTenantIDsFromValue } from './getTenantIDsFromValue.js'\nimport { getUserTenantIDs } from './getUserTenantIDs.js'\n\ntype Args = {\n previousValue?: unknown\n req: PayloadRequest\n tenantsArrayFieldName: string\n tenantsArrayTenantFieldName: string\n userHasAccessToAllTenants?: MultiTenantPluginConfig['userHasAccessToAllTenants']\n value: unknown\n}\n\nexport const isValidTenantAssignment = ({\n previousValue,\n req,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n value,\n}: Args): boolean => {\n const { user } = req\n\n if (user) {\n if (userHasAccessToAllTenants?.(user)) {\n return true\n }\n } else if (req.payloadAPI === 'local') {\n return true\n }\n\n const submittedDocumentTenantIDs = getTenantIDsFromValue(value)\n const storedDocumentTenantIDs = getTenantIDsFromValue(previousValue)\n\n if (!hasTenantValueChanged(submittedDocumentTenantIDs, storedDocumentTenantIDs)) {\n return true\n }\n\n if (submittedDocumentTenantIDs.length === 0) {\n return false\n }\n\n const userAssignedTenantIDs = getUserTenantIDs(user, {\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n })\n\n return submittedDocumentTenantIDs.every((tenantID) =>\n userAssignedTenantIDs.some(\n (userAssignedTenantID) => String(userAssignedTenantID) === String(tenantID),\n ),\n )\n}\n\nconst hasTenantValueChanged = (\n submittedTenantIDs: (number | string)[],\n storedTenantIDs: (number | string)[],\n): boolean =>\n submittedTenantIDs.length !== storedTenantIDs.length ||\n submittedTenantIDs.some((tenantID) => !storedTenantIDs.includes(tenantID))\n"],"names":["getTenantIDsFromValue","getUserTenantIDs","isValidTenantAssignment","previousValue","req","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","value","user","payloadAPI","submittedDocumentTenantIDs","storedDocumentTenantIDs","hasTenantValueChanged","length","userAssignedTenantIDs","every","tenantID","some","userAssignedTenantID","String","submittedTenantIDs","storedTenantIDs","includes"],"mappings":"AAIA,SAASA,qBAAqB,QAAQ,6BAA4B;AAClE,SAASC,gBAAgB,QAAQ,wBAAuB;AAWxD,OAAO,MAAMC,0BAA0B,CAAC,EACtCC,aAAa,EACbC,GAAG,EACHC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACzBC,KAAK,EACA;IACL,MAAM,EAAEC,IAAI,EAAE,GAAGL;IAEjB,IAAIK,MAAM;QACR,IAAIF,4BAA4BE,OAAO;YACrC,OAAO;QACT;IACF,OAAO,IAAIL,IAAIM,UAAU,KAAK,SAAS;QACrC,OAAO;IACT;IAEA,MAAMC,6BAA6BX,sBAAsBQ;IACzD,MAAMI,0BAA0BZ,sBAAsBG;IAEtD,IAAI,CAACU,sBAAsBF,4BAA4BC,0BAA0B;QAC/E,OAAO;IACT;IAEA,IAAID,2BAA2BG,MAAM,KAAK,GAAG;QAC3C,OAAO;IACT;IAEA,MAAMC,wBAAwBd,iBAAiBQ,MAAM;QACnDJ;QACAC;IACF;IAEA,OAAOK,2BAA2BK,KAAK,CAAC,CAACC,WACvCF,sBAAsBG,IAAI,CACxB,CAACC,uBAAyBC,OAAOD,0BAA0BC,OAAOH;AAGxE,EAAC;AAED,MAAMJ,wBAAwB,CAC5BQ,oBACAC,kBAEAD,mBAAmBP,MAAM,KAAKQ,gBAAgBR,MAAM,IACpDO,mBAAmBH,IAAI,CAAC,CAACD,WAAa,CAACK,gBAAgBC,QAAQ,CAACN"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shouldRefreshTenantSelection.d.ts","sourceRoot":"","sources":["../../src/utilities/shouldRefreshTenantSelection.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,oCAGtC;IACD,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,KAAG,OAAiD,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/shouldRefreshTenantSelection.ts"],"sourcesContent":["export const shouldRefreshTenantSelection = ({\n initialValue,\n tenantCookie,\n}: {\n initialValue?: number | string\n tenantCookie?: string\n}): boolean => !initialValue && Boolean(tenantCookie)\n"],"names":["shouldRefreshTenantSelection","initialValue","tenantCookie","Boolean"],"mappings":"AAAA,OAAO,MAAMA,+BAA+B,CAAC,EAC3CC,YAAY,EACZC,YAAY,EAIb,GAAc,CAACD,gBAAgBE,QAAQD,cAAa"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-multi-tenant",
|
|
3
|
-
"version": "4.0.0-internal.
|
|
3
|
+
"version": "4.0.0-internal.cb69780",
|
|
4
4
|
"description": "Multi Tenant plugin for Payload",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"payload",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
}
|
|
27
27
|
],
|
|
28
28
|
"sideEffects": [
|
|
29
|
-
"*.scss",
|
|
30
29
|
"*.css"
|
|
31
30
|
],
|
|
32
31
|
"type": "module",
|
|
@@ -81,13 +80,13 @@
|
|
|
81
80
|
],
|
|
82
81
|
"devDependencies": {
|
|
83
82
|
"@payloadcms/eslint-config": "3.28.0",
|
|
84
|
-
"
|
|
85
|
-
"@payloadcms/translations": "4.0.0-internal.
|
|
86
|
-
"
|
|
83
|
+
"payload": "4.0.0-internal.cb69780",
|
|
84
|
+
"@payloadcms/translations": "4.0.0-internal.cb69780",
|
|
85
|
+
"@payloadcms/ui": "4.0.0-internal.cb69780"
|
|
87
86
|
},
|
|
88
87
|
"peerDependencies": {
|
|
89
|
-
"@payloadcms/ui": "4.0.0-internal.
|
|
90
|
-
"payload": "4.0.0-internal.
|
|
88
|
+
"@payloadcms/ui": "4.0.0-internal.cb69780",
|
|
89
|
+
"payload": "4.0.0-internal.cb69780"
|
|
91
90
|
},
|
|
92
91
|
"homepage:": "https://payloadcms.com",
|
|
93
92
|
"scripts": {
|
|
@@ -96,7 +95,7 @@
|
|
|
96
95
|
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
|
97
96
|
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
98
97
|
"clean": "rimraf {dist,*.tsbuildinfo}",
|
|
99
|
-
"copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
98
|
+
"copyfiles": "copyfiles -u 1 -e \"**/*.spec.*\" \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
100
99
|
"lint": "eslint .",
|
|
101
100
|
"lint:fix": "eslint . --fix",
|
|
102
101
|
"pack:plugin": "pnpm build && pnpm pack"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"combineWhereConstraints.d.ts","sourceRoot":"","sources":["../../src/utilities/combineWhereConstraints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAgBxE"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export function combineWhereConstraints(constraints) {
|
|
2
|
-
if (constraints.length === 0) {
|
|
3
|
-
return {};
|
|
4
|
-
}
|
|
5
|
-
if (constraints.length === 1 && constraints[0]) {
|
|
6
|
-
return constraints[0];
|
|
7
|
-
}
|
|
8
|
-
const andConstraint = {
|
|
9
|
-
and: []
|
|
10
|
-
};
|
|
11
|
-
constraints.forEach((constraint)=>{
|
|
12
|
-
if (andConstraint.and && constraint && typeof constraint === 'object') {
|
|
13
|
-
andConstraint.and.push(constraint);
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
return andConstraint;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
//# sourceMappingURL=combineWhereConstraints.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/combineWhereConstraints.ts"],"sourcesContent":["import type { Where } from 'payload'\n\nexport function combineWhereConstraints(constraints: Array<Where>): Where {\n if (constraints.length === 0) {\n return {}\n }\n if (constraints.length === 1 && constraints[0]) {\n return constraints[0]\n }\n const andConstraint: Where = {\n and: [],\n }\n constraints.forEach((constraint) => {\n if (andConstraint.and && constraint && typeof constraint === 'object') {\n andConstraint.and.push(constraint)\n }\n })\n return andConstraint\n}\n"],"names":["combineWhereConstraints","constraints","length","andConstraint","and","forEach","constraint","push"],"mappings":"AAEA,OAAO,SAASA,wBAAwBC,WAAyB;IAC/D,IAAIA,YAAYC,MAAM,KAAK,GAAG;QAC5B,OAAO,CAAC;IACV;IACA,IAAID,YAAYC,MAAM,KAAK,KAAKD,WAAW,CAAC,EAAE,EAAE;QAC9C,OAAOA,WAAW,CAAC,EAAE;IACvB;IACA,MAAME,gBAAuB;QAC3BC,KAAK,EAAE;IACT;IACAH,YAAYI,OAAO,CAAC,CAACC;QACnB,IAAIH,cAAcC,GAAG,IAAIE,cAAc,OAAOA,eAAe,UAAU;YACrEH,cAAcC,GAAG,CAACG,IAAI,CAACD;QACzB;IACF;IACA,OAAOH;AACT"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Access, AccessArgs, AccessResult, CollectionConfig } from 'payload';
|
|
2
|
-
import type { AllAccessKeys, MultiTenantPluginConfig } from '../types.js';
|
|
3
|
-
type Args = {
|
|
4
|
-
accessFunction?: Access;
|
|
5
|
-
accessKey: AllAccessKeys[number];
|
|
6
|
-
accessResultCallback?: MultiTenantPluginConfig['usersAccessResultOverride'];
|
|
7
|
-
adminUsersSlug: string;
|
|
8
|
-
collection: CollectionConfig;
|
|
9
|
-
fieldName: string;
|
|
10
|
-
tenantsArrayFieldName?: string;
|
|
11
|
-
tenantsArrayTenantFieldName?: string;
|
|
12
|
-
userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants'];
|
|
13
|
-
};
|
|
14
|
-
export declare const withTenantAccess: ({ accessFunction, accessKey, accessResultCallback, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants, }: Args) => (args: AccessArgs) => Promise<AccessResult>;
|
|
15
|
-
export {};
|
|
16
|
-
//# sourceMappingURL=withTenantAccess.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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,EAAe,MAAM,SAAS,CAAA;AAE9F,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAwB,MAAM,aAAa,CAAA;AAK/F,KAAK,IAAI,GAAG;IACV,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAChC,oBAAoB,CAAC,EAAE,uBAAuB,CAAC,2BAA2B,CAAC,CAAA;IAC3E,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,CAAC,uBAAuB,CAAC,CAAC,2BAA2B,CAAC,CAAA;CAC1F,CAAA;AACD,eAAO,MAAM,gBAAgB,+KAWxB,IAAI,YACM,UAAU,KAAG,OAAO,CAAC,YAAY,CAkF7C,CAAA"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { combineWhereConstraints } from './combineWhereConstraints.js';
|
|
2
|
-
import { getTenantAccess } from './getTenantAccess.js';
|
|
3
|
-
export const withTenantAccess = ({ accessFunction, accessKey, accessResultCallback, adminUsersSlug, collection, fieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, userHasAccessToAllTenants })=>async (args)=>{
|
|
4
|
-
const constraints = [];
|
|
5
|
-
const accessFn = typeof accessFunction === 'function' ? accessFunction : ({ req })=>Boolean(req.user);
|
|
6
|
-
const accessResult = await accessFn(args);
|
|
7
|
-
if (accessResult === false) {
|
|
8
|
-
if (accessResultCallback) {
|
|
9
|
-
return accessResultCallback({
|
|
10
|
-
accessKey,
|
|
11
|
-
accessResult: false,
|
|
12
|
-
...args
|
|
13
|
-
});
|
|
14
|
-
} else {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
} else if (accessResult && typeof accessResult === 'object') {
|
|
18
|
-
constraints.push(accessResult);
|
|
19
|
-
}
|
|
20
|
-
if (args.req.user && args.req.user.collection === adminUsersSlug && !userHasAccessToAllTenants(args.req.user)) {
|
|
21
|
-
const tenantConstraint = getTenantAccess({
|
|
22
|
-
fieldName,
|
|
23
|
-
tenantsArrayFieldName,
|
|
24
|
-
tenantsArrayTenantFieldName,
|
|
25
|
-
user: args.req.user
|
|
26
|
-
});
|
|
27
|
-
// User with no tenants should have no access to tenant-scoped documents
|
|
28
|
-
// except for their own user document
|
|
29
|
-
if (tenantConstraint[fieldName]?.in.length === 0) {
|
|
30
|
-
const result = collection.slug === args.req.user.collection ? {
|
|
31
|
-
id: {
|
|
32
|
-
equals: args.req.user.id
|
|
33
|
-
}
|
|
34
|
-
} : false;
|
|
35
|
-
return accessResultCallback ? accessResultCallback({
|
|
36
|
-
accessKey,
|
|
37
|
-
accessResult: result,
|
|
38
|
-
...args
|
|
39
|
-
}) : result;
|
|
40
|
-
}
|
|
41
|
-
if (collection.slug === args.req.user.collection) {
|
|
42
|
-
constraints.push({
|
|
43
|
-
or: [
|
|
44
|
-
{
|
|
45
|
-
id: {
|
|
46
|
-
equals: args.req.user.id
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
tenantConstraint
|
|
50
|
-
]
|
|
51
|
-
});
|
|
52
|
-
} else {
|
|
53
|
-
constraints.push(tenantConstraint);
|
|
54
|
-
}
|
|
55
|
-
if (accessResultCallback) {
|
|
56
|
-
return accessResultCallback({
|
|
57
|
-
accessKey,
|
|
58
|
-
accessResult: combineWhereConstraints(constraints),
|
|
59
|
-
...args
|
|
60
|
-
});
|
|
61
|
-
} else {
|
|
62
|
-
return combineWhereConstraints(constraints);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (accessResultCallback) {
|
|
66
|
-
return accessResultCallback({
|
|
67
|
-
accessKey,
|
|
68
|
-
accessResult,
|
|
69
|
-
...args
|
|
70
|
-
});
|
|
71
|
-
} else {
|
|
72
|
-
return accessResult;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
//# sourceMappingURL=withTenantAccess.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/withTenantAccess.ts"],"sourcesContent":["import type { Access, AccessArgs, AccessResult, CollectionConfig, User, 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 = {\n accessFunction?: Access\n accessKey: AllAccessKeys[number]\n accessResultCallback?: MultiTenantPluginConfig['usersAccessResultOverride']\n adminUsersSlug: string\n collection: CollectionConfig\n fieldName: string\n tenantsArrayFieldName?: string\n tenantsArrayTenantFieldName?: string\n userHasAccessToAllTenants: Required<MultiTenantPluginConfig>['userHasAccessToAllTenants']\n}\nexport const withTenantAccess =\n ({\n accessFunction,\n accessKey,\n accessResultCallback,\n adminUsersSlug,\n collection,\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n userHasAccessToAllTenants,\n }: Args) =>\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 accessResult: false,\n ...args,\n })\n } else {\n return false\n }\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(args.req.user as User)\n ) {\n const tenantConstraint = getTenantAccess({\n fieldName,\n tenantsArrayFieldName,\n tenantsArrayTenantFieldName,\n user: args.req.user as UserWithTenantsField,\n })\n\n // User with no tenants should have no access to tenant-scoped documents\n // except for their own user document\n if (tenantConstraint[fieldName]?.in.length === 0) {\n const result: AccessResult =\n collection.slug === args.req.user.collection\n ? { id: { equals: args.req.user.id } }\n : false\n\n return accessResultCallback\n ? accessResultCallback({ accessKey, accessResult: result, ...args })\n : result\n }\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 accessResult: combineWhereConstraints(constraints),\n ...args,\n })\n } else {\n return combineWhereConstraints(constraints)\n }\n }\n\n if (accessResultCallback) {\n return accessResultCallback({\n accessKey,\n accessResult,\n ...args,\n })\n } else {\n return accessResult\n }\n }\n"],"names":["combineWhereConstraints","getTenantAccess","withTenantAccess","accessFunction","accessKey","accessResultCallback","adminUsersSlug","collection","fieldName","tenantsArrayFieldName","tenantsArrayTenantFieldName","userHasAccessToAllTenants","args","constraints","accessFn","req","Boolean","user","accessResult","push","tenantConstraint","in","length","result","slug","id","equals","or"],"mappings":"AAIA,SAASA,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,eAAe,QAAQ,uBAAsB;AAatD,OAAO,MAAMC,mBACX,CAAC,EACCC,cAAc,EACdC,SAAS,EACTC,oBAAoB,EACpBC,cAAc,EACdC,UAAU,EACVC,SAAS,EACTC,qBAAqB,EACrBC,2BAA2B,EAC3BC,yBAAyB,EACpB,GACP,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;oBACAc,cAAc;oBACd,GAAGN,IAAI;gBACT;YACF,OAAO;gBACL,OAAO;YACT;QACF,OAAO,IAAIM,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,0BAA0BC,KAAKG,GAAG,CAACE,IAAI,GACxC;YACA,MAAMG,mBAAmBnB,gBAAgB;gBACvCO;gBACAC;gBACAC;gBACAO,MAAML,KAAKG,GAAG,CAACE,IAAI;YACrB;YAEA,wEAAwE;YACxE,qCAAqC;YACrC,IAAIG,gBAAgB,CAACZ,UAAU,EAAEa,GAAGC,WAAW,GAAG;gBAChD,MAAMC,SACJhB,WAAWiB,IAAI,KAAKZ,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,GACxC;oBAAEkB,IAAI;wBAAEC,QAAQd,KAAKG,GAAG,CAACE,IAAI,CAACQ,EAAE;oBAAC;gBAAE,IACnC;gBAEN,OAAOpB,uBACHA,qBAAqB;oBAAED;oBAAWc,cAAcK;oBAAQ,GAAGX,IAAI;gBAAC,KAChEW;YACN;YAEA,IAAIhB,WAAWiB,IAAI,KAAKZ,KAAKG,GAAG,CAACE,IAAI,CAACV,UAAU,EAAE;gBAChDM,YAAYM,IAAI,CAAC;oBACfQ,IAAI;wBACF;4BACEF,IAAI;gCACFC,QAAQd,KAAKG,GAAG,CAACE,IAAI,CAACQ,EAAE;4BAC1B;wBACF;wBACAL;qBACD;gBACH;YACF,OAAO;gBACLP,YAAYM,IAAI,CAACC;YACnB;YAEA,IAAIf,sBAAsB;gBACxB,OAAOA,qBAAqB;oBAC1BD;oBACAc,cAAclB,wBAAwBa;oBACtC,GAAGD,IAAI;gBACT;YACF,OAAO;gBACL,OAAOZ,wBAAwBa;YACjC;QACF;QAEA,IAAIR,sBAAsB;YACxB,OAAOA,qBAAqB;gBAC1BD;gBACAc;gBACA,GAAGN,IAAI;YACT;QACF,OAAO;YACL,OAAOM;QACT;IACF,EAAC"}
|