@7365admin1/core 3.53.2 → 3.53.4
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 +35 -0
- package/dist/index.d.ts +143 -1
- package/dist/index.js +183 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +176 -73
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/test/console-audit.test.mjs +4 -4
- package/test/console-permission.test.mjs +273 -0
- package/test/e2e/console-permission.e2e.test.mjs +286 -0
- package/test/member-scope.test.mjs +4 -4
- package/test/org-suspension.test.mjs +22 -7
- package/test/resident-ownership-scope.test.mjs +1 -1
- package/test/role-member-org-scope.test.mjs +1 -1
- package/test/role-scope.test.mjs +4 -4
- package/test/sp-approvals-console-gate.test.mjs +117 -0
- package/test/staff-console-authz.test.mjs +25 -25
- package/test/terms-acceptance-list.test.mjs +2 -2
package/dist/index.mjs
CHANGED
|
@@ -10221,39 +10221,28 @@ import { ObjectId as ObjectId15 } from "mongodb";
|
|
|
10221
10221
|
import { useAtlas as useAtlas8 } from "@7365admin1/node-server-utils";
|
|
10222
10222
|
import { ObjectId as ObjectId14 } from "mongodb";
|
|
10223
10223
|
var LIVE_ROLE = { status: { $ne: "deleted" } };
|
|
10224
|
-
async function
|
|
10224
|
+
async function resolveStaffRole(userId) {
|
|
10225
10225
|
const id = userId?.toString() ?? "";
|
|
10226
10226
|
if (!id || !ObjectId14.isValid(id))
|
|
10227
|
-
return
|
|
10227
|
+
return null;
|
|
10228
10228
|
const db2 = useAtlas8.getDb();
|
|
10229
10229
|
if (!db2)
|
|
10230
|
-
return
|
|
10230
|
+
return null;
|
|
10231
10231
|
const member = await db2.collection("members").findOne({
|
|
10232
10232
|
user: new ObjectId14(id),
|
|
10233
10233
|
type: "admin",
|
|
10234
10234
|
status: { $ne: "deleted" }
|
|
10235
10235
|
});
|
|
10236
10236
|
if (!member?.role || !ObjectId14.isValid(member.role.toString()))
|
|
10237
|
-
return
|
|
10237
|
+
return null;
|
|
10238
10238
|
const role = await db2.collection("roles").findOne({ _id: new ObjectId14(member.role.toString()), ...LIVE_ROLE });
|
|
10239
|
-
return role?.type === "admin";
|
|
10239
|
+
return role?.type === "admin" ? role : null;
|
|
10240
|
+
}
|
|
10241
|
+
async function isSuperAdmin(userId) {
|
|
10242
|
+
return await resolveStaffRole(userId) !== null;
|
|
10240
10243
|
}
|
|
10241
10244
|
async function isPlatformOwner(userId) {
|
|
10242
|
-
|
|
10243
|
-
if (!id || !ObjectId14.isValid(id))
|
|
10244
|
-
return false;
|
|
10245
|
-
const db2 = useAtlas8.getDb();
|
|
10246
|
-
if (!db2)
|
|
10247
|
-
return false;
|
|
10248
|
-
const member = await db2.collection("members").findOne({
|
|
10249
|
-
user: new ObjectId14(id),
|
|
10250
|
-
type: "admin",
|
|
10251
|
-
status: { $ne: "deleted" }
|
|
10252
|
-
});
|
|
10253
|
-
if (!member?.role || !ObjectId14.isValid(member.role.toString()))
|
|
10254
|
-
return false;
|
|
10255
|
-
const role = await db2.collection("roles").findOne({ _id: new ObjectId14(member.role.toString()), ...LIVE_ROLE });
|
|
10256
|
-
return role?.type === "admin" && role?.default === true;
|
|
10245
|
+
return (await resolveStaffRole(userId))?.default === true;
|
|
10257
10246
|
}
|
|
10258
10247
|
|
|
10259
10248
|
// src/utils/org-suspension.util.ts
|
|
@@ -18072,32 +18061,127 @@ function usePersonRepo() {
|
|
|
18072
18061
|
|
|
18073
18062
|
// src/utils/console-authz.util.ts
|
|
18074
18063
|
import { UnauthorizedError as UnauthorizedError3 } from "@7365admin1/node-server-utils";
|
|
18064
|
+
|
|
18065
|
+
// src/utils/console-permission.util.ts
|
|
18066
|
+
var CONSOLE_PERMISSIONS = Object.freeze({
|
|
18067
|
+
organizations: Object.freeze([
|
|
18068
|
+
"see-all-organizations",
|
|
18069
|
+
"see-organization-details"
|
|
18070
|
+
]),
|
|
18071
|
+
"promo-codes": Object.freeze([
|
|
18072
|
+
"create-promo-code",
|
|
18073
|
+
"see-promo-code-details",
|
|
18074
|
+
"edit-promo-code-details",
|
|
18075
|
+
"change-promo-code-status",
|
|
18076
|
+
"delete-promo-code"
|
|
18077
|
+
]),
|
|
18078
|
+
users: Object.freeze(["see-all-users", "see-user-details"]),
|
|
18079
|
+
invitations: Object.freeze([
|
|
18080
|
+
"create-invitation",
|
|
18081
|
+
"view-invitations",
|
|
18082
|
+
"cancel-invitation"
|
|
18083
|
+
]),
|
|
18084
|
+
subscriptions: Object.freeze([
|
|
18085
|
+
"see-all-subscriptions",
|
|
18086
|
+
"see-subscription-details",
|
|
18087
|
+
"manage-subscription"
|
|
18088
|
+
]),
|
|
18089
|
+
"sp-approvals": Object.freeze([
|
|
18090
|
+
"see-all-sp-approvals",
|
|
18091
|
+
"approve-sp",
|
|
18092
|
+
"reject-sp",
|
|
18093
|
+
"delete-sp-approval"
|
|
18094
|
+
]),
|
|
18095
|
+
"marketplace-vendors": Object.freeze([
|
|
18096
|
+
"see-all-marketplace-vendors",
|
|
18097
|
+
"see-marketplace-vendor-details"
|
|
18098
|
+
]),
|
|
18099
|
+
"platform-terms": Object.freeze([
|
|
18100
|
+
"see-platform-terms",
|
|
18101
|
+
"edit-platform-terms"
|
|
18102
|
+
]),
|
|
18103
|
+
"activity-history": Object.freeze(["see-activity-history"]),
|
|
18104
|
+
members: Object.freeze([
|
|
18105
|
+
"view-members",
|
|
18106
|
+
"assign-member-role",
|
|
18107
|
+
"suspend-member",
|
|
18108
|
+
"activate-member",
|
|
18109
|
+
"delete-member"
|
|
18110
|
+
]),
|
|
18111
|
+
"roles-and-permissions": Object.freeze([
|
|
18112
|
+
"add-role",
|
|
18113
|
+
"see-all-roles",
|
|
18114
|
+
"see-role-details",
|
|
18115
|
+
"update-role",
|
|
18116
|
+
"delete-role"
|
|
18117
|
+
])
|
|
18118
|
+
});
|
|
18119
|
+
var RESOURCE_SPELLINGS = Object.freeze({
|
|
18120
|
+
"roles-and-permissions": Object.freeze([
|
|
18121
|
+
"roles-and-permissions",
|
|
18122
|
+
"roles"
|
|
18123
|
+
]),
|
|
18124
|
+
roles: Object.freeze(["roles", "roles-and-permissions"])
|
|
18125
|
+
});
|
|
18126
|
+
function consoleSpellings(resource, action) {
|
|
18127
|
+
const resources = RESOURCE_SPELLINGS[resource] ?? [resource];
|
|
18128
|
+
return resources.map((name) => `${name}:${action}`);
|
|
18129
|
+
}
|
|
18130
|
+
function consoleRoleAllowsAll(held) {
|
|
18131
|
+
if (!Array.isArray(held) || held.length === 0)
|
|
18132
|
+
return true;
|
|
18133
|
+
return held.includes("*");
|
|
18134
|
+
}
|
|
18135
|
+
function consoleRoleAllows(held, resource, action) {
|
|
18136
|
+
if (consoleRoleAllowsAll(held))
|
|
18137
|
+
return true;
|
|
18138
|
+
const actions = CONSOLE_PERMISSIONS[resource];
|
|
18139
|
+
if (!actions?.length)
|
|
18140
|
+
return false;
|
|
18141
|
+
const wanted = action ? actions.includes(action) ? [action] : [] : actions;
|
|
18142
|
+
return wanted.some(
|
|
18143
|
+
(name) => consoleSpellings(resource, name).some(
|
|
18144
|
+
(spelling) => held.includes(spelling)
|
|
18145
|
+
)
|
|
18146
|
+
);
|
|
18147
|
+
}
|
|
18148
|
+
|
|
18149
|
+
// src/utils/console-authz.util.ts
|
|
18075
18150
|
function callerId(req) {
|
|
18076
18151
|
const user = req.user;
|
|
18077
18152
|
return user?.user?.toString?.() || user?._id?.toString?.() || "";
|
|
18078
18153
|
}
|
|
18079
|
-
async function requirePlatformStaff(req) {
|
|
18154
|
+
async function requirePlatformStaff(req, grant) {
|
|
18080
18155
|
const id = callerId(req);
|
|
18081
|
-
|
|
18156
|
+
const role = id ? await resolveStaffRole(id) : null;
|
|
18157
|
+
if (!role) {
|
|
18158
|
+
throw new UnauthorizedError3("Not authorized.");
|
|
18159
|
+
}
|
|
18160
|
+
if (grant && !consoleRoleAllows(role.permissions, grant.resource, grant.action)) {
|
|
18082
18161
|
throw new UnauthorizedError3("Not authorized.");
|
|
18083
18162
|
}
|
|
18084
18163
|
return id;
|
|
18085
18164
|
}
|
|
18086
|
-
async function
|
|
18165
|
+
async function requireConsolePermission(req, resource, action) {
|
|
18166
|
+
return await requirePlatformStaff(req, { resource, action });
|
|
18167
|
+
}
|
|
18168
|
+
async function requireSelfOrPlatformStaff(req, userId, grant) {
|
|
18087
18169
|
const id = callerId(req);
|
|
18088
18170
|
const target = userId?.toString() ?? "";
|
|
18089
18171
|
if (id && target && target === id)
|
|
18090
18172
|
return id;
|
|
18091
|
-
return await requirePlatformStaff(req);
|
|
18173
|
+
return await requirePlatformStaff(req, grant);
|
|
18092
18174
|
}
|
|
18093
18175
|
async function requireOrgAccess(req, orgId) {
|
|
18094
18176
|
return await requireOrgReach(req, orgId);
|
|
18095
18177
|
}
|
|
18096
|
-
async function requirePlatformOwner(req) {
|
|
18178
|
+
async function requirePlatformOwner(req, grant) {
|
|
18097
18179
|
const id = callerId(req);
|
|
18098
18180
|
if (!id || !await isPlatformOwner(id)) {
|
|
18099
18181
|
throw new UnauthorizedError3("Not authorized.");
|
|
18100
18182
|
}
|
|
18183
|
+
if (grant)
|
|
18184
|
+
await requirePlatformStaff(req, grant);
|
|
18101
18185
|
return id;
|
|
18102
18186
|
}
|
|
18103
18187
|
async function requireOrgReach(req, orgId) {
|
|
@@ -18124,10 +18208,10 @@ async function requireInviteReach(req, org, app) {
|
|
|
18124
18208
|
if (org)
|
|
18125
18209
|
await requireOrgReach(req, org);
|
|
18126
18210
|
}
|
|
18127
|
-
async function requireUserFieldWrite(req, userId, field) {
|
|
18211
|
+
async function requireUserFieldWrite(req, userId, field, grant) {
|
|
18128
18212
|
if (field === "email")
|
|
18129
|
-
return await requirePlatformStaff(req);
|
|
18130
|
-
return await requireSelfOrPlatformStaff(req, userId);
|
|
18213
|
+
return await requirePlatformStaff(req, grant);
|
|
18214
|
+
return await requireSelfOrPlatformStaff(req, userId, grant);
|
|
18131
18215
|
}
|
|
18132
18216
|
|
|
18133
18217
|
// src/utils/user-response.util.ts
|
|
@@ -18167,7 +18251,7 @@ function useUserController() {
|
|
|
18167
18251
|
return;
|
|
18168
18252
|
}
|
|
18169
18253
|
try {
|
|
18170
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
18254
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users", action: "see-user-details" });
|
|
18171
18255
|
const user = await _getById(_id);
|
|
18172
18256
|
res.json(user);
|
|
18173
18257
|
return;
|
|
@@ -18252,7 +18336,7 @@ function useUserController() {
|
|
|
18252
18336
|
const page = parseInt(req.query.page ?? "1");
|
|
18253
18337
|
const status = req.query.status ?? "active";
|
|
18254
18338
|
try {
|
|
18255
|
-
await
|
|
18339
|
+
await requireConsolePermission(req, "users", "see-all-users");
|
|
18256
18340
|
const data = await _getUsers({ search, page, status });
|
|
18257
18341
|
res.json(data);
|
|
18258
18342
|
return;
|
|
@@ -18347,7 +18431,7 @@ function useUserController() {
|
|
|
18347
18431
|
return;
|
|
18348
18432
|
}
|
|
18349
18433
|
try {
|
|
18350
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
18434
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users" });
|
|
18351
18435
|
const message = await _updateBirthday({ _id, ...payload });
|
|
18352
18436
|
res.json({ message });
|
|
18353
18437
|
return;
|
|
@@ -18389,7 +18473,7 @@ function useUserController() {
|
|
|
18389
18473
|
return;
|
|
18390
18474
|
}
|
|
18391
18475
|
try {
|
|
18392
|
-
await requireUserFieldWrite(req, _id, payload.field);
|
|
18476
|
+
await requireUserFieldWrite(req, _id, payload.field, { resource: "users" });
|
|
18393
18477
|
let message;
|
|
18394
18478
|
if (payload.field === "plateNumber") {
|
|
18395
18479
|
message = await updatePlateNumberByUserId(
|
|
@@ -18431,7 +18515,7 @@ function useUserController() {
|
|
|
18431
18515
|
const newPassword = req.body.newPassword ?? "";
|
|
18432
18516
|
const passwordConfirmation = req.body.passwordConfirmation ?? "";
|
|
18433
18517
|
try {
|
|
18434
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
18518
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users" });
|
|
18435
18519
|
await _updatePasswordById(
|
|
18436
18520
|
_id,
|
|
18437
18521
|
currentPassword,
|
|
@@ -18540,7 +18624,7 @@ function useRoleService() {
|
|
|
18540
18624
|
async function requireRoleOrg(req, org) {
|
|
18541
18625
|
const orgId = org?.toString() ?? "";
|
|
18542
18626
|
if (!orgId) {
|
|
18543
|
-
await
|
|
18627
|
+
await requireConsolePermission(req, "roles-and-permissions");
|
|
18544
18628
|
return;
|
|
18545
18629
|
}
|
|
18546
18630
|
await requireOrgAccess(req, orgId);
|
|
@@ -18582,7 +18666,7 @@ function useRoleController() {
|
|
|
18582
18666
|
}
|
|
18583
18667
|
try {
|
|
18584
18668
|
if (payload.type === PLATFORM_STAFF_ROLE_TYPE) {
|
|
18585
|
-
await
|
|
18669
|
+
await requireConsolePermission(req, "roles-and-permissions", "add-role");
|
|
18586
18670
|
}
|
|
18587
18671
|
if (payload.org) {
|
|
18588
18672
|
await requireOrgReach(req, payload.org);
|
|
@@ -26207,7 +26291,7 @@ async function entitledSites(req) {
|
|
|
26207
26291
|
async function requireMemberOrg(req, org) {
|
|
26208
26292
|
const orgId = org?.toString() ?? "";
|
|
26209
26293
|
if (!orgId) {
|
|
26210
|
-
await
|
|
26294
|
+
await requireConsolePermission(req, "members");
|
|
26211
26295
|
return;
|
|
26212
26296
|
}
|
|
26213
26297
|
await requireOrgAccess(req, orgId);
|
|
@@ -26254,7 +26338,7 @@ function useMemberController() {
|
|
|
26254
26338
|
return;
|
|
26255
26339
|
}
|
|
26256
26340
|
try {
|
|
26257
|
-
await requireSelfOrPlatformStaff(req, userId);
|
|
26341
|
+
await requireSelfOrPlatformStaff(req, userId, { resource: "members", action: "view-members" });
|
|
26258
26342
|
const data = await _getByUserId(userId);
|
|
26259
26343
|
res.json(data);
|
|
26260
26344
|
return;
|
|
@@ -26304,7 +26388,7 @@ function useMemberController() {
|
|
|
26304
26388
|
const user = req.params.id;
|
|
26305
26389
|
const type = req.params.type;
|
|
26306
26390
|
try {
|
|
26307
|
-
await requireSelfOrPlatformStaff(req, user);
|
|
26391
|
+
await requireSelfOrPlatformStaff(req, user, { resource: "members", action: "view-members" });
|
|
26308
26392
|
const data = await _getByUserIdType(user, type);
|
|
26309
26393
|
res.json(data);
|
|
26310
26394
|
return;
|
|
@@ -26350,11 +26434,11 @@ function useMemberController() {
|
|
|
26350
26434
|
}
|
|
26351
26435
|
try {
|
|
26352
26436
|
if (type === "admin") {
|
|
26353
|
-
await
|
|
26437
|
+
await requireConsolePermission(req, "members", "view-members");
|
|
26354
26438
|
} else if (org) {
|
|
26355
26439
|
await requireOrgAccess(req, org);
|
|
26356
26440
|
} else if (user && user !== callerId(req)) {
|
|
26357
|
-
await
|
|
26441
|
+
await requireConsolePermission(req, "users", "see-all-users");
|
|
26358
26442
|
}
|
|
26359
26443
|
const items = await _getAll({
|
|
26360
26444
|
search,
|
|
@@ -26549,7 +26633,7 @@ function useMemberController() {
|
|
|
26549
26633
|
const type = req.params.type;
|
|
26550
26634
|
const org = req.query.org;
|
|
26551
26635
|
try {
|
|
26552
|
-
await requireSelfOrPlatformStaff(req, user);
|
|
26636
|
+
await requireSelfOrPlatformStaff(req, user, { resource: "members", action: "view-members" });
|
|
26553
26637
|
const data = await _getByUserIdTypeOrg(
|
|
26554
26638
|
user,
|
|
26555
26639
|
type,
|
|
@@ -28405,7 +28489,7 @@ function useOrgController() {
|
|
|
28405
28489
|
return;
|
|
28406
28490
|
}
|
|
28407
28491
|
try {
|
|
28408
|
-
const createdBy = await
|
|
28492
|
+
const createdBy = await requireConsolePermission(req, "organizations");
|
|
28409
28493
|
await _add({ ...req.body, createdBy });
|
|
28410
28494
|
res.status(201).json({ message: "Successfully created organization." });
|
|
28411
28495
|
return;
|
|
@@ -28511,7 +28595,7 @@ function useOrgController() {
|
|
|
28511
28595
|
const type = req.query.type ?? "";
|
|
28512
28596
|
try {
|
|
28513
28597
|
if (user !== callerId(req)) {
|
|
28514
|
-
await
|
|
28598
|
+
await requireConsolePermission(req, "organizations", "see-all-organizations");
|
|
28515
28599
|
}
|
|
28516
28600
|
const data = await getOrgsByMembership({
|
|
28517
28601
|
search,
|
|
@@ -28538,7 +28622,7 @@ function useOrgController() {
|
|
|
28538
28622
|
return;
|
|
28539
28623
|
}
|
|
28540
28624
|
try {
|
|
28541
|
-
await
|
|
28625
|
+
await requireConsolePermission(req, "organizations", "see-organization-details");
|
|
28542
28626
|
const data = await _getByName(name);
|
|
28543
28627
|
res.json(data);
|
|
28544
28628
|
return;
|
|
@@ -28576,7 +28660,7 @@ function useOrgController() {
|
|
|
28576
28660
|
return;
|
|
28577
28661
|
}
|
|
28578
28662
|
try {
|
|
28579
|
-
await
|
|
28663
|
+
await requireConsolePermission(req, "organizations", "see-organization-details");
|
|
28580
28664
|
const data = await _getByEmail(email);
|
|
28581
28665
|
if (!data) {
|
|
28582
28666
|
next(new NotFoundError17("Organization not found."));
|
|
@@ -28606,7 +28690,7 @@ function useOrgController() {
|
|
|
28606
28690
|
try {
|
|
28607
28691
|
const self = await _getUserById(callerId(req)).catch(() => null);
|
|
28608
28692
|
if (!self?.email || self.email.toLowerCase() !== email.toLowerCase()) {
|
|
28609
|
-
await
|
|
28693
|
+
await requireConsolePermission(req, "organizations", "see-all-organizations");
|
|
28610
28694
|
}
|
|
28611
28695
|
const data = await _getOrgsByEmail(email);
|
|
28612
28696
|
res.json(data);
|
|
@@ -28666,7 +28750,7 @@ function useOrgController() {
|
|
|
28666
28750
|
const orgId = req.params.id;
|
|
28667
28751
|
const { status } = req.body;
|
|
28668
28752
|
try {
|
|
28669
|
-
const ownerId = await requirePlatformOwner(req);
|
|
28753
|
+
const ownerId = await requirePlatformOwner(req, { resource: "organizations" });
|
|
28670
28754
|
await _updateStatusById(orgId, status);
|
|
28671
28755
|
const subscription = await _getSubscriptionByOrgId(orgId);
|
|
28672
28756
|
if (subscription) {
|
|
@@ -28737,7 +28821,7 @@ function useOrgControllerV2() {
|
|
|
28737
28821
|
const nature = value.nature ?? "";
|
|
28738
28822
|
const status = value.status;
|
|
28739
28823
|
try {
|
|
28740
|
-
await
|
|
28824
|
+
await requireConsolePermission(req, "organizations", "see-all-organizations");
|
|
28741
28825
|
const data = await _getAll({
|
|
28742
28826
|
search,
|
|
28743
28827
|
page,
|
|
@@ -28774,7 +28858,7 @@ function useOrgControllerV2() {
|
|
|
28774
28858
|
return;
|
|
28775
28859
|
}
|
|
28776
28860
|
try {
|
|
28777
|
-
await
|
|
28861
|
+
await requireConsolePermission(req, "organizations", "see-all-organizations");
|
|
28778
28862
|
const data = await _getOrganizationsWithSubscription({
|
|
28779
28863
|
search: value.search ?? "",
|
|
28780
28864
|
page: value.page ?? 1,
|
|
@@ -31303,7 +31387,7 @@ function useSubscriptionController() {
|
|
|
31303
31387
|
return;
|
|
31304
31388
|
}
|
|
31305
31389
|
try {
|
|
31306
|
-
await
|
|
31390
|
+
await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31307
31391
|
const id = await _add(payload);
|
|
31308
31392
|
res.status(201).json({ message: "Successfully added subscription.", id });
|
|
31309
31393
|
return;
|
|
@@ -31350,7 +31434,7 @@ function useSubscriptionController() {
|
|
|
31350
31434
|
const page = parseInt(req.query.page ?? "1");
|
|
31351
31435
|
const status = req.query.status ?? "active";
|
|
31352
31436
|
try {
|
|
31353
|
-
await
|
|
31437
|
+
await requireConsolePermission(req, "subscriptions", "see-all-subscriptions");
|
|
31354
31438
|
const data = await _getSubscriptions({ search, page, status });
|
|
31355
31439
|
res.json(data);
|
|
31356
31440
|
return;
|
|
@@ -31484,7 +31568,7 @@ function useSubscriptionController() {
|
|
|
31484
31568
|
}
|
|
31485
31569
|
async function createConsoleSubscription(req, res, next) {
|
|
31486
31570
|
try {
|
|
31487
|
-
const staffId = await
|
|
31571
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31488
31572
|
const form = await readConsoleForm(req);
|
|
31489
31573
|
const existing = await _getByOrgId(form.orgId);
|
|
31490
31574
|
if (existing && existing.status !== "ended") {
|
|
@@ -31530,7 +31614,7 @@ function useSubscriptionController() {
|
|
|
31530
31614
|
}
|
|
31531
31615
|
async function updateConsoleSubscription(req, res, next) {
|
|
31532
31616
|
try {
|
|
31533
|
-
const staffId = await
|
|
31617
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31534
31618
|
const form = await readConsoleForm(req);
|
|
31535
31619
|
const existing = await _getByOrgId(form.orgId);
|
|
31536
31620
|
if (!existing?._id) {
|
|
@@ -31570,7 +31654,7 @@ function useSubscriptionController() {
|
|
|
31570
31654
|
}
|
|
31571
31655
|
async function getConsoleSubscription(req, res, next) {
|
|
31572
31656
|
try {
|
|
31573
|
-
await
|
|
31657
|
+
await requireConsolePermission(req, "subscriptions", "see-subscription-details");
|
|
31574
31658
|
const orgId = req.params.id;
|
|
31575
31659
|
if (!/^[0-9a-fA-F]{24}$/.test(orgId ?? "")) {
|
|
31576
31660
|
throw new BadRequestError70("That client could not be found.");
|
|
@@ -31639,7 +31723,7 @@ function useSubscriptionPlanController() {
|
|
|
31639
31723
|
return;
|
|
31640
31724
|
}
|
|
31641
31725
|
try {
|
|
31642
|
-
const staffId = await
|
|
31726
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31643
31727
|
const _id = await _add(req.body);
|
|
31644
31728
|
const data = await _getById(_id);
|
|
31645
31729
|
await recordConsoleAction({
|
|
@@ -31735,7 +31819,7 @@ function useSubscriptionPlanController() {
|
|
|
31735
31819
|
}
|
|
31736
31820
|
const id = req.params.id;
|
|
31737
31821
|
try {
|
|
31738
|
-
const staffId = await
|
|
31822
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31739
31823
|
const before = await _getById(id);
|
|
31740
31824
|
await _update(id, req.body);
|
|
31741
31825
|
const data = await _getById(id);
|
|
@@ -31767,7 +31851,7 @@ function useSubscriptionPlanController() {
|
|
|
31767
31851
|
const id = req.params.id;
|
|
31768
31852
|
const { status } = req.body;
|
|
31769
31853
|
try {
|
|
31770
|
-
const staffId = await
|
|
31854
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31771
31855
|
await _updateStatusById(id, status);
|
|
31772
31856
|
const data = await _getById(id);
|
|
31773
31857
|
await recordConsoleAction({
|
|
@@ -31912,7 +31996,7 @@ function usePromoCodeController() {
|
|
|
31912
31996
|
payload.code = payload.code.trim().toUpperCase();
|
|
31913
31997
|
payload.fixed_rate = parseInt(payload.fixed_rate ?? "0");
|
|
31914
31998
|
try {
|
|
31915
|
-
const staffId = await
|
|
31999
|
+
const staffId = await requireConsolePermission(req, "promo-codes", "create-promo-code");
|
|
31916
32000
|
const created = await _add(payload);
|
|
31917
32001
|
await recordConsoleAction({
|
|
31918
32002
|
action: "promo-code.created" /* PROMO_CODE_CREATED */,
|
|
@@ -31965,7 +32049,7 @@ function usePromoCodeController() {
|
|
|
31965
32049
|
return;
|
|
31966
32050
|
}
|
|
31967
32051
|
try {
|
|
31968
|
-
await
|
|
32052
|
+
await requireConsolePermission(req, "promo-codes", "see-promo-code-details");
|
|
31969
32053
|
const data = await _getById(_id);
|
|
31970
32054
|
res.json(data);
|
|
31971
32055
|
return;
|
|
@@ -31994,7 +32078,7 @@ function usePromoCodeController() {
|
|
|
31994
32078
|
const limit = parseInt(req.query.limit ?? "10");
|
|
31995
32079
|
const status = req.query.status ?? "active";
|
|
31996
32080
|
try {
|
|
31997
|
-
await
|
|
32081
|
+
await requireConsolePermission(req, "promo-codes");
|
|
31998
32082
|
const data = await _getPromoCodes({
|
|
31999
32083
|
search,
|
|
32000
32084
|
page,
|
|
@@ -32019,7 +32103,7 @@ function usePromoCodeController() {
|
|
|
32019
32103
|
return;
|
|
32020
32104
|
}
|
|
32021
32105
|
try {
|
|
32022
|
-
const staffId = await
|
|
32106
|
+
const staffId = await requireConsolePermission(req, "promo-codes", "edit-promo-code-details");
|
|
32023
32107
|
const before = await _getById(req.params.id);
|
|
32024
32108
|
await _updateById(req.params.id, req.body);
|
|
32025
32109
|
await recordConsoleAction({
|
|
@@ -32055,7 +32139,7 @@ function usePromoCodeController() {
|
|
|
32055
32139
|
return;
|
|
32056
32140
|
}
|
|
32057
32141
|
try {
|
|
32058
|
-
const staffId = await
|
|
32142
|
+
const staffId = await requireConsolePermission(req, "promo-codes", "change-promo-code-status");
|
|
32059
32143
|
await _updateStatusById(req.params.id, status.value.status);
|
|
32060
32144
|
await recordConsoleAction({
|
|
32061
32145
|
action: "promo-code.status-changed" /* PROMO_CODE_STATUS_CHANGED */,
|
|
@@ -32084,7 +32168,7 @@ function usePromoCodeController() {
|
|
|
32084
32168
|
return;
|
|
32085
32169
|
}
|
|
32086
32170
|
try {
|
|
32087
|
-
const staffId = await
|
|
32171
|
+
const staffId = await requireConsolePermission(req, "promo-codes", "delete-promo-code");
|
|
32088
32172
|
await _softDeleteById(req.params.id, staffId);
|
|
32089
32173
|
await recordConsoleAction({
|
|
32090
32174
|
action: "promo-code.removed" /* PROMO_CODE_REMOVED */,
|
|
@@ -85296,6 +85380,11 @@ function useServiceProviderInviteController() {
|
|
|
85296
85380
|
}
|
|
85297
85381
|
async function approvals(req, res, next) {
|
|
85298
85382
|
try {
|
|
85383
|
+
await requireConsolePermission(
|
|
85384
|
+
req,
|
|
85385
|
+
"sp-approvals",
|
|
85386
|
+
"see-all-sp-approvals"
|
|
85387
|
+
);
|
|
85299
85388
|
const schema2 = Joi143.object({
|
|
85300
85389
|
status: Joi143.string().valid(
|
|
85301
85390
|
"awaiting-approval",
|
|
@@ -85322,6 +85411,11 @@ function useServiceProviderInviteController() {
|
|
|
85322
85411
|
}
|
|
85323
85412
|
async function pendingApprovalCount(req, res, next) {
|
|
85324
85413
|
try {
|
|
85414
|
+
await requireConsolePermission(
|
|
85415
|
+
req,
|
|
85416
|
+
"sp-approvals",
|
|
85417
|
+
"see-all-sp-approvals"
|
|
85418
|
+
);
|
|
85325
85419
|
res.json(await approvalCount({ userId: callerId5(req) }));
|
|
85326
85420
|
} catch (error) {
|
|
85327
85421
|
next(error);
|
|
@@ -85329,6 +85423,7 @@ function useServiceProviderInviteController() {
|
|
|
85329
85423
|
}
|
|
85330
85424
|
async function approve(req, res, next) {
|
|
85331
85425
|
try {
|
|
85426
|
+
await requireConsolePermission(req, "sp-approvals", "approve-sp");
|
|
85332
85427
|
res.json(await _approve({ id: inviteId(req), userId: callerId5(req) }));
|
|
85333
85428
|
} catch (error) {
|
|
85334
85429
|
logger198.log({ level: "error", message: `${error.message}` });
|
|
@@ -85337,6 +85432,7 @@ function useServiceProviderInviteController() {
|
|
|
85337
85432
|
}
|
|
85338
85433
|
async function reject(req, res, next) {
|
|
85339
85434
|
try {
|
|
85435
|
+
await requireConsolePermission(req, "sp-approvals", "reject-sp");
|
|
85340
85436
|
const { error, value } = Joi143.object({
|
|
85341
85437
|
reason: Joi143.string().trim().min(1).max(1e3).required()
|
|
85342
85438
|
}).validate(req.body ?? {});
|
|
@@ -86473,7 +86569,7 @@ function useUserControllerV2() {
|
|
|
86473
86569
|
return;
|
|
86474
86570
|
}
|
|
86475
86571
|
try {
|
|
86476
|
-
await requireSelfOrPlatformStaff(req, value);
|
|
86572
|
+
await requireSelfOrPlatformStaff(req, value, { resource: "users", action: "see-user-details" });
|
|
86477
86573
|
const user = await _getById(value);
|
|
86478
86574
|
res.json(user);
|
|
86479
86575
|
return;
|
|
@@ -86510,7 +86606,7 @@ function useUserControllerV2() {
|
|
|
86510
86606
|
if (error)
|
|
86511
86607
|
return rejectValidation(error, next);
|
|
86512
86608
|
try {
|
|
86513
|
-
await
|
|
86609
|
+
await requireConsolePermission(req, "users", "see-all-users");
|
|
86514
86610
|
const users = await _getUsers({
|
|
86515
86611
|
search: value.search ?? "",
|
|
86516
86612
|
page: value.page,
|
|
@@ -86635,7 +86731,7 @@ function useUserControllerV2() {
|
|
|
86635
86731
|
return;
|
|
86636
86732
|
}
|
|
86637
86733
|
try {
|
|
86638
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
86734
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users" });
|
|
86639
86735
|
const message = await _updateBirthday({ _id, ...payload });
|
|
86640
86736
|
res.json({ message });
|
|
86641
86737
|
return;
|
|
@@ -86667,7 +86763,7 @@ function useUserControllerV2() {
|
|
|
86667
86763
|
return;
|
|
86668
86764
|
}
|
|
86669
86765
|
try {
|
|
86670
|
-
await requireUserFieldWrite(req, _id, payload.field);
|
|
86766
|
+
await requireUserFieldWrite(req, _id, payload.field, { resource: "users" });
|
|
86671
86767
|
const message = await _updateUserFieldById({ _id, ...payload });
|
|
86672
86768
|
res.json({ message });
|
|
86673
86769
|
return;
|
|
@@ -86698,7 +86794,7 @@ function useUserControllerV2() {
|
|
|
86698
86794
|
const newPassword = req.body.newPassword ?? "";
|
|
86699
86795
|
const passwordConfirmation = req.body.passwordConfirmation ?? "";
|
|
86700
86796
|
try {
|
|
86701
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
86797
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users" });
|
|
86702
86798
|
await _updatePasswordById(
|
|
86703
86799
|
_id,
|
|
86704
86800
|
currentPassword,
|
|
@@ -86882,7 +86978,7 @@ function useRoleControllerV2() {
|
|
|
86882
86978
|
}
|
|
86883
86979
|
try {
|
|
86884
86980
|
if (value.type === PLATFORM_STAFF_ROLE_TYPE) {
|
|
86885
|
-
await
|
|
86981
|
+
await requireConsolePermission(req, "roles-and-permissions", "add-role");
|
|
86886
86982
|
}
|
|
86887
86983
|
if (value.org) {
|
|
86888
86984
|
await requireOrgReach(req, value.org);
|
|
@@ -91616,7 +91712,7 @@ function usePlatformTermsController() {
|
|
|
91616
91712
|
return id;
|
|
91617
91713
|
}
|
|
91618
91714
|
if (staffMayRead) {
|
|
91619
|
-
return await
|
|
91715
|
+
return await requireConsolePermission(req, "platform-terms", "see-platform-terms");
|
|
91620
91716
|
}
|
|
91621
91717
|
throw new UnauthorizedError23("Not authorized.");
|
|
91622
91718
|
}
|
|
@@ -91708,7 +91804,7 @@ function usePlatformTermsController() {
|
|
|
91708
91804
|
return;
|
|
91709
91805
|
}
|
|
91710
91806
|
try {
|
|
91711
|
-
await
|
|
91807
|
+
await requireConsolePermission(req, "platform-terms", "see-platform-terms");
|
|
91712
91808
|
res.json(
|
|
91713
91809
|
await _listAcceptance({
|
|
91714
91810
|
version: value.version || null,
|
|
@@ -91740,7 +91836,7 @@ function usePlatformTermsController() {
|
|
|
91740
91836
|
return;
|
|
91741
91837
|
}
|
|
91742
91838
|
try {
|
|
91743
|
-
const staffId = await
|
|
91839
|
+
const staffId = await requireConsolePermission(req, "platform-terms", "edit-platform-terms");
|
|
91744
91840
|
const created = await _add({
|
|
91745
91841
|
terms: value.terms,
|
|
91746
91842
|
policies: value.policies,
|
|
@@ -91798,7 +91894,7 @@ function useConsoleAuditController() {
|
|
|
91798
91894
|
}
|
|
91799
91895
|
const to = value.to && value.to.length === 10 ? `${value.to}T23:59:59.999Z` : value.to;
|
|
91800
91896
|
try {
|
|
91801
|
-
await
|
|
91897
|
+
await requireConsolePermission(req, "activity-history", "see-activity-history");
|
|
91802
91898
|
res.json(
|
|
91803
91899
|
await _list({
|
|
91804
91900
|
org: value.org || "",
|
|
@@ -92144,6 +92240,7 @@ export {
|
|
|
92144
92240
|
CLIENT_ACTIONS,
|
|
92145
92241
|
CLOCK_DRIFT_WARN_SECONDS,
|
|
92146
92242
|
CONSOLE_AUDIT_LABELS,
|
|
92243
|
+
CONSOLE_PERMISSIONS,
|
|
92147
92244
|
CONTRACTOR_TYPE_LABELS,
|
|
92148
92245
|
CURRENT_TIME_ENDPOINT,
|
|
92149
92246
|
CameraType,
|
|
@@ -92356,6 +92453,9 @@ export {
|
|
|
92356
92453
|
chatSchema,
|
|
92357
92454
|
clampPtzSpeed,
|
|
92358
92455
|
clockDriftSeconds,
|
|
92456
|
+
consoleRoleAllows,
|
|
92457
|
+
consoleRoleAllowsAll,
|
|
92458
|
+
consoleSpellings,
|
|
92359
92459
|
console_audit_namespace_collection,
|
|
92360
92460
|
createManpowerRemarksDaily,
|
|
92361
92461
|
customerSchema,
|
|
@@ -92455,6 +92555,8 @@ export {
|
|
|
92455
92555
|
relayForRecorder,
|
|
92456
92556
|
remarksSchema,
|
|
92457
92557
|
renderPagePdf,
|
|
92558
|
+
requireConsolePermission,
|
|
92559
|
+
requirePlatformStaff,
|
|
92458
92560
|
resetCameraTransports,
|
|
92459
92561
|
residentAppModuleKeys,
|
|
92460
92562
|
residentFormEntry,
|
|
@@ -92464,6 +92566,7 @@ export {
|
|
|
92464
92566
|
resolveHidPhysicalCardValue,
|
|
92465
92567
|
resolveInviteActor,
|
|
92466
92568
|
resolveSiteTimezone,
|
|
92569
|
+
resolveStaffRole,
|
|
92467
92570
|
robotSchema,
|
|
92468
92571
|
rtspUrl,
|
|
92469
92572
|
schema,
|