@easy-cms/plugin-multi-tenant 0.65.0 → 0.66.0
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/index.js +57 -3
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -62,7 +62,7 @@ var INFO = {
|
|
|
62
62
|
name: "@easy-cms/plugin-multi-tenant",
|
|
63
63
|
// The plugin API it is written for (`PLUGIN_API_VERSION` of @easy-cms/core).
|
|
64
64
|
apiVersion: 1,
|
|
65
|
-
...true ? { version: "0.
|
|
65
|
+
...true ? { version: "0.66.0" } : {}
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
// src/members.ts
|
|
@@ -234,6 +234,23 @@ function membersEndpoints(options) {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
// src/plugin.ts
|
|
237
|
+
var PLUGIN_GROUPS = [
|
|
238
|
+
{ plugin: "formBuilderPlugin", slugs: ["forms", "form-submissions"] },
|
|
239
|
+
{
|
|
240
|
+
plugin: "ecommercePlugin",
|
|
241
|
+
slugs: [
|
|
242
|
+
"products",
|
|
243
|
+
"variant-types",
|
|
244
|
+
"variant-options",
|
|
245
|
+
"variants",
|
|
246
|
+
"carts",
|
|
247
|
+
"addresses",
|
|
248
|
+
"orders",
|
|
249
|
+
"transactions",
|
|
250
|
+
"shop-counters"
|
|
251
|
+
]
|
|
252
|
+
}
|
|
253
|
+
];
|
|
237
254
|
var BUILTIN_ACCESS = {
|
|
238
255
|
[MEDIA]: { read: () => true, create: isStaff, update: isStaff, delete: isStaff },
|
|
239
256
|
[MEDIA_FOLDERS]: { read: isStaff, create: isStaff, update: isStaff, delete: isStaff }
|
|
@@ -266,6 +283,15 @@ function multiTenantPlugin(options) {
|
|
|
266
283
|
);
|
|
267
284
|
if (scoped.has(tenantsSlug) || scoped.has("users"))
|
|
268
285
|
throw new Error(`multiTenantPlugin: "${tenantsSlug}" and "users" can't belong to a tenant`);
|
|
286
|
+
const partly = PLUGIN_GROUPS.flatMap(({ plugin, slugs }) => {
|
|
287
|
+
const present = slugs.filter((slug) => declared.has(slug));
|
|
288
|
+
const listed = present.filter((slug) => scoped.has(slug));
|
|
289
|
+
const shared = present.filter((slug) => !scoped.has(slug));
|
|
290
|
+
return listed.length > 0 && shared.length > 0 ? [
|
|
291
|
+
`multiTenantPlugin: ${shared.map((x) => `"${x}"`).join(", ")} of ${plugin} are shared by all tenants while ${listed.map((x) => `"${x}"`).join(", ")} belong to one; list them all in \`collections\`, or none`
|
|
292
|
+
] : [];
|
|
293
|
+
});
|
|
294
|
+
let warned = partly.length === 0;
|
|
269
295
|
const perTenant = new Set(options.globals ?? []);
|
|
270
296
|
const unknownGlobals = [...perTenant].filter(
|
|
271
297
|
(g) => !(config.globals ?? []).some((global) => global.slug === g)
|
|
@@ -439,6 +465,23 @@ function multiTenantPlugin(options) {
|
|
|
439
465
|
delete: and(custom?.delete, ({ user, context }) => superUser(user, context))
|
|
440
466
|
};
|
|
441
467
|
};
|
|
468
|
+
const ownMemberships = ({ doc, user, context }) => {
|
|
469
|
+
if (!user || superUser(user, context) || sameId(doc.id, user.id)) return doc;
|
|
470
|
+
const list = doc[MEMBERSHIPS_FIELD];
|
|
471
|
+
if (!Array.isArray(list)) return doc;
|
|
472
|
+
const { tenant } = tenantOf(context);
|
|
473
|
+
const idOf = (value) => typeof value === "object" && value !== null ? value.id : value;
|
|
474
|
+
return {
|
|
475
|
+
...doc,
|
|
476
|
+
[MEMBERSHIPS_FIELD]: list.filter(
|
|
477
|
+
(m) => tenant !== null && sameId(idOf(m.tenant), tenant)
|
|
478
|
+
)
|
|
479
|
+
};
|
|
480
|
+
};
|
|
481
|
+
const usersHooks = (hooks = {}) => ({
|
|
482
|
+
...hooks,
|
|
483
|
+
afterRead: [...hooks.afterRead ?? [], ownMemberships]
|
|
484
|
+
});
|
|
442
485
|
const tenantsAccess = {
|
|
443
486
|
read: ({ user, context }) => {
|
|
444
487
|
if (!user) return false;
|
|
@@ -517,7 +560,8 @@ function multiTenantPlugin(options) {
|
|
|
517
560
|
collections.push({
|
|
518
561
|
...c,
|
|
519
562
|
fields: [...withTenantFilters(c.fields), memberships],
|
|
520
|
-
access: { ...c.access, ...usersAccess(c.access) }
|
|
563
|
+
access: { ...c.access, ...usersAccess(c.access) },
|
|
564
|
+
hooks: usersHooks(c.hooks)
|
|
521
565
|
});
|
|
522
566
|
} else if (scoped.has(c.slug)) collections.push(scopeCollection(c, BUILTIN_ACCESS[c.slug]));
|
|
523
567
|
else
|
|
@@ -532,7 +576,13 @@ function multiTenantPlugin(options) {
|
|
|
532
576
|
}
|
|
533
577
|
});
|
|
534
578
|
}
|
|
535
|
-
if (!hasUsers)
|
|
579
|
+
if (!hasUsers)
|
|
580
|
+
collections.push({
|
|
581
|
+
slug: "users",
|
|
582
|
+
fields: [memberships],
|
|
583
|
+
access: usersAccess(),
|
|
584
|
+
hooks: usersHooks()
|
|
585
|
+
});
|
|
536
586
|
for (const builtin of [MEDIA, MEDIA_FOLDERS]) {
|
|
537
587
|
if (scoped.has(builtin) && !declared.has(builtin))
|
|
538
588
|
collections.push(
|
|
@@ -564,6 +614,10 @@ function multiTenantPlugin(options) {
|
|
|
564
614
|
});
|
|
565
615
|
const previous = config.onRequest;
|
|
566
616
|
const onRequest = async (args) => {
|
|
617
|
+
if (!warned) {
|
|
618
|
+
warned = true;
|
|
619
|
+
for (const message of partly) args.cms.logger.warn(message);
|
|
620
|
+
}
|
|
567
621
|
const user = args.user;
|
|
568
622
|
const list = await tenantList(args.cms, tenantsSlug);
|
|
569
623
|
const asked = args.headers.get(header) ?? args.url?.searchParams.get("tenant") ?? readCookie(args.headers.get("cookie"), cookie) ?? null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easy-cms/plugin-multi-tenant",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.66.0",
|
|
4
4
|
"description": "Multi-tenant Easy CMS: several sites or clients in one CMS, each with its own content, members and roles",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@easy-cms/core": "^0.
|
|
20
|
+
"@easy-cms/core": "^0.66.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@easy-cms/core": "^0.
|
|
24
|
-
"@easy-cms/
|
|
25
|
-
"@easy-cms/
|
|
26
|
-
"@easy-cms/plugin-nested-docs": "^0.
|
|
27
|
-
"@easy-cms/plugin-redirects": "^0.
|
|
23
|
+
"@easy-cms/core": "^0.66.0",
|
|
24
|
+
"@easy-cms/db-sqlite": "^0.66.0",
|
|
25
|
+
"@easy-cms/plugin-form-builder": "^0.66.0",
|
|
26
|
+
"@easy-cms/plugin-nested-docs": "^0.66.0",
|
|
27
|
+
"@easy-cms/plugin-redirects": "^0.66.0"
|
|
28
28
|
},
|
|
29
29
|
"engines": {
|
|
30
30
|
"node": ">=22.12"
|