@7365admin1/core 3.57.0 → 3.58.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/CHANGELOG.md +17 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +22 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/role-template-restore.e2e.test.mjs +369 -0
- package/test/role-scope-separation.test.mjs +149 -0
- package/test/role-scope.test.mjs +15 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @iservice365/core
|
|
2
2
|
|
|
3
|
+
## 3.58.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f20014d: Allow a Seven365 platform admin to restore a shared client role template to allow-all.
|
|
8
|
+
|
|
9
|
+
The role-scope guard refuses every write to an org-less client template. That is correct for
|
|
10
|
+
preventing the 2026-09-07 outage and it left no way to repair one: "Org Owner" still holds the 34
|
|
11
|
+
platform permission strings and the guard refuses the write that would give its members their
|
|
12
|
+
modules back.
|
|
13
|
+
|
|
14
|
+
`refuseSharedClientTemplate` now takes the permission list the write would store and permits it when
|
|
15
|
+
that list MEANS EVERYTHING (`["*"]` or `[]`). Every other list stays refused with the same message,
|
|
16
|
+
including the 34 strings and including a hand-built superset — a template has no editor that draws
|
|
17
|
+
the right catalogue, and an equal-set write is the broken state being re-saved. The restore is only
|
|
18
|
+
reachable after the existing staff console check, and is recorded with actor, role and before/after.
|
|
19
|
+
|
|
3
20
|
## 3.57.0
|
|
4
21
|
|
|
5
22
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -11713,7 +11713,7 @@ declare function MHidAmicoIdentity(value: THidAmicoIdentity): {
|
|
|
11713
11713
|
member: ObjectId | undefined;
|
|
11714
11714
|
serviceProvider: ObjectId | undefined;
|
|
11715
11715
|
visitor: ObjectId | undefined;
|
|
11716
|
-
type: "admin" | "resident" | "contractor" | "
|
|
11716
|
+
type: "admin" | "resident" | "contractor" | "unknown" | "visitor" | "staff";
|
|
11717
11717
|
status: "deleted" | "active" | "inactive";
|
|
11718
11718
|
metadata: Record<string, unknown>;
|
|
11719
11719
|
createdAt: string | Date;
|
|
@@ -11825,7 +11825,7 @@ declare function useHidAmicoRepo(): {
|
|
|
11825
11825
|
member: ObjectId | undefined;
|
|
11826
11826
|
serviceProvider: ObjectId | undefined;
|
|
11827
11827
|
visitor: ObjectId | undefined;
|
|
11828
|
-
type: "admin" | "resident" | "contractor" | "
|
|
11828
|
+
type: "admin" | "resident" | "contractor" | "unknown" | "visitor" | "staff";
|
|
11829
11829
|
status: "deleted" | "active" | "inactive";
|
|
11830
11830
|
metadata: Record<string, unknown>;
|
|
11831
11831
|
createdAt: string | Date;
|
|
@@ -12229,7 +12229,7 @@ declare function useHidAmicoService(): {
|
|
|
12229
12229
|
member: bson.ObjectId | undefined;
|
|
12230
12230
|
serviceProvider: bson.ObjectId | undefined;
|
|
12231
12231
|
visitor: bson.ObjectId | undefined;
|
|
12232
|
-
type: "admin" | "resident" | "contractor" | "
|
|
12232
|
+
type: "admin" | "resident" | "contractor" | "unknown" | "visitor" | "staff";
|
|
12233
12233
|
status: "deleted" | "active" | "inactive";
|
|
12234
12234
|
metadata: Record<string, unknown>;
|
|
12235
12235
|
createdAt: string | Date;
|
package/dist/index.js
CHANGED
|
@@ -19331,9 +19331,14 @@ function requireNoPlatformGrant(role, next) {
|
|
|
19331
19331
|
"These are Seven365 console permissions and cannot be granted on a client role: " + added.join(", ")
|
|
19332
19332
|
);
|
|
19333
19333
|
}
|
|
19334
|
-
function
|
|
19334
|
+
function permissionsMeanEverything(permissions) {
|
|
19335
|
+
return !permissions?.length || permissions.includes("*");
|
|
19336
|
+
}
|
|
19337
|
+
function refuseSharedClientTemplate(role, next) {
|
|
19335
19338
|
if (roleScope(role) !== "client-template")
|
|
19336
|
-
return;
|
|
19339
|
+
return false;
|
|
19340
|
+
if (Array.isArray(next) && permissionsMeanEverything(next))
|
|
19341
|
+
return true;
|
|
19337
19342
|
throw new import_node_server_utils45.UnauthorizedError(
|
|
19338
19343
|
"This role is shared by every client that was invited with it and cannot be changed here."
|
|
19339
19344
|
);
|
|
@@ -19353,9 +19358,16 @@ async function requireRoleRead(req, roleId, org) {
|
|
|
19353
19358
|
return;
|
|
19354
19359
|
await requireRoleOrg(req, org);
|
|
19355
19360
|
}
|
|
19356
|
-
async function requireRoleWrite(req, role) {
|
|
19357
|
-
refuseSharedClientTemplate(role);
|
|
19361
|
+
async function requireRoleWrite(req, role, next) {
|
|
19362
|
+
const isTemplateRestore = refuseSharedClientTemplate(role, next);
|
|
19358
19363
|
await requireRoleOrg(req, role?.org);
|
|
19364
|
+
return isTemplateRestore;
|
|
19365
|
+
}
|
|
19366
|
+
function logTemplateRestore(req, roleId, before, after) {
|
|
19367
|
+
import_node_server_utils46.logger.log({
|
|
19368
|
+
level: "warn",
|
|
19369
|
+
message: `SHARED CLIENT TEMPLATE RESTORED TO ALLOW-ALL. actor=${callerId(req) || "unknown"} role=${roleId} before=${(before ?? []).length} permission(s) after=${JSON.stringify(after)}`
|
|
19370
|
+
});
|
|
19359
19371
|
}
|
|
19360
19372
|
function useRoleController() {
|
|
19361
19373
|
const {
|
|
@@ -19501,9 +19513,11 @@ function useRoleController() {
|
|
|
19501
19513
|
const existing = await _getRoleById(_id);
|
|
19502
19514
|
if (!existing)
|
|
19503
19515
|
throw new import_node_server_utils46.NotFoundError("Role not found.");
|
|
19504
|
-
await requireRoleWrite(req, existing);
|
|
19516
|
+
const isRestore = await requireRoleWrite(req, existing, permissions);
|
|
19505
19517
|
requireNoPlatformGrant(existing, permissions);
|
|
19506
19518
|
const role = await _updateRole(_id, { name, permissions });
|
|
19519
|
+
if (isRestore)
|
|
19520
|
+
logTemplateRestore(req, _id, existing?.permissions, permissions);
|
|
19507
19521
|
res.json({ message: "Successfully updated role.", data: { role } });
|
|
19508
19522
|
return;
|
|
19509
19523
|
} catch (error2) {
|
|
@@ -19530,9 +19544,11 @@ function useRoleController() {
|
|
|
19530
19544
|
const existing = await _getRoleById(_id);
|
|
19531
19545
|
if (!existing)
|
|
19532
19546
|
throw new import_node_server_utils46.NotFoundError("Role not found.");
|
|
19533
|
-
await requireRoleWrite(req, existing);
|
|
19547
|
+
const isRestore = await requireRoleWrite(req, existing, permissions);
|
|
19534
19548
|
requireNoPlatformGrant(existing, permissions);
|
|
19535
19549
|
await _updatePermissionsById(_id, permissions);
|
|
19550
|
+
if (isRestore)
|
|
19551
|
+
logTemplateRestore(req, _id, existing?.permissions, permissions);
|
|
19536
19552
|
res.json({ message: "Successfully updated role permissions." });
|
|
19537
19553
|
return;
|
|
19538
19554
|
} catch (error2) {
|