@7365admin1/core 3.53.1 → 3.53.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/index.d.ts +26 -2
- package/dist/index.js +209 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +270 -134
- 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/file-delete-scope.test.mjs +64 -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/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
|
|
@@ -16237,6 +16226,8 @@ var MFile = class {
|
|
|
16237
16226
|
this.size = value.size ?? 0;
|
|
16238
16227
|
this.status = value.status ?? "draft";
|
|
16239
16228
|
this.createdAt = value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
16229
|
+
if (value.createdBy)
|
|
16230
|
+
this.createdBy = value.createdBy.toString();
|
|
16240
16231
|
}
|
|
16241
16232
|
};
|
|
16242
16233
|
|
|
@@ -18070,32 +18061,127 @@ function usePersonRepo() {
|
|
|
18070
18061
|
|
|
18071
18062
|
// src/utils/console-authz.util.ts
|
|
18072
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
|
|
18073
18150
|
function callerId(req) {
|
|
18074
18151
|
const user = req.user;
|
|
18075
18152
|
return user?.user?.toString?.() || user?._id?.toString?.() || "";
|
|
18076
18153
|
}
|
|
18077
|
-
async function requirePlatformStaff(req) {
|
|
18154
|
+
async function requirePlatformStaff(req, grant) {
|
|
18078
18155
|
const id = callerId(req);
|
|
18079
|
-
|
|
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)) {
|
|
18080
18161
|
throw new UnauthorizedError3("Not authorized.");
|
|
18081
18162
|
}
|
|
18082
18163
|
return id;
|
|
18083
18164
|
}
|
|
18084
|
-
async function
|
|
18165
|
+
async function requireConsolePermission(req, resource, action) {
|
|
18166
|
+
return await requirePlatformStaff(req, { resource, action });
|
|
18167
|
+
}
|
|
18168
|
+
async function requireSelfOrPlatformStaff(req, userId, grant) {
|
|
18085
18169
|
const id = callerId(req);
|
|
18086
18170
|
const target = userId?.toString() ?? "";
|
|
18087
18171
|
if (id && target && target === id)
|
|
18088
18172
|
return id;
|
|
18089
|
-
return await requirePlatformStaff(req);
|
|
18173
|
+
return await requirePlatformStaff(req, grant);
|
|
18090
18174
|
}
|
|
18091
18175
|
async function requireOrgAccess(req, orgId) {
|
|
18092
18176
|
return await requireOrgReach(req, orgId);
|
|
18093
18177
|
}
|
|
18094
|
-
async function requirePlatformOwner(req) {
|
|
18178
|
+
async function requirePlatformOwner(req, grant) {
|
|
18095
18179
|
const id = callerId(req);
|
|
18096
18180
|
if (!id || !await isPlatformOwner(id)) {
|
|
18097
18181
|
throw new UnauthorizedError3("Not authorized.");
|
|
18098
18182
|
}
|
|
18183
|
+
if (grant)
|
|
18184
|
+
await requirePlatformStaff(req, grant);
|
|
18099
18185
|
return id;
|
|
18100
18186
|
}
|
|
18101
18187
|
async function requireOrgReach(req, orgId) {
|
|
@@ -18122,10 +18208,10 @@ async function requireInviteReach(req, org, app) {
|
|
|
18122
18208
|
if (org)
|
|
18123
18209
|
await requireOrgReach(req, org);
|
|
18124
18210
|
}
|
|
18125
|
-
async function requireUserFieldWrite(req, userId, field) {
|
|
18211
|
+
async function requireUserFieldWrite(req, userId, field, grant) {
|
|
18126
18212
|
if (field === "email")
|
|
18127
|
-
return await requirePlatformStaff(req);
|
|
18128
|
-
return await requireSelfOrPlatformStaff(req, userId);
|
|
18213
|
+
return await requirePlatformStaff(req, grant);
|
|
18214
|
+
return await requireSelfOrPlatformStaff(req, userId, grant);
|
|
18129
18215
|
}
|
|
18130
18216
|
|
|
18131
18217
|
// src/utils/user-response.util.ts
|
|
@@ -18165,7 +18251,7 @@ function useUserController() {
|
|
|
18165
18251
|
return;
|
|
18166
18252
|
}
|
|
18167
18253
|
try {
|
|
18168
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
18254
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users", action: "see-user-details" });
|
|
18169
18255
|
const user = await _getById(_id);
|
|
18170
18256
|
res.json(user);
|
|
18171
18257
|
return;
|
|
@@ -18250,7 +18336,7 @@ function useUserController() {
|
|
|
18250
18336
|
const page = parseInt(req.query.page ?? "1");
|
|
18251
18337
|
const status = req.query.status ?? "active";
|
|
18252
18338
|
try {
|
|
18253
|
-
await
|
|
18339
|
+
await requireConsolePermission(req, "users", "see-all-users");
|
|
18254
18340
|
const data = await _getUsers({ search, page, status });
|
|
18255
18341
|
res.json(data);
|
|
18256
18342
|
return;
|
|
@@ -18345,7 +18431,7 @@ function useUserController() {
|
|
|
18345
18431
|
return;
|
|
18346
18432
|
}
|
|
18347
18433
|
try {
|
|
18348
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
18434
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users" });
|
|
18349
18435
|
const message = await _updateBirthday({ _id, ...payload });
|
|
18350
18436
|
res.json({ message });
|
|
18351
18437
|
return;
|
|
@@ -18387,7 +18473,7 @@ function useUserController() {
|
|
|
18387
18473
|
return;
|
|
18388
18474
|
}
|
|
18389
18475
|
try {
|
|
18390
|
-
await requireUserFieldWrite(req, _id, payload.field);
|
|
18476
|
+
await requireUserFieldWrite(req, _id, payload.field, { resource: "users" });
|
|
18391
18477
|
let message;
|
|
18392
18478
|
if (payload.field === "plateNumber") {
|
|
18393
18479
|
message = await updatePlateNumberByUserId(
|
|
@@ -18429,7 +18515,7 @@ function useUserController() {
|
|
|
18429
18515
|
const newPassword = req.body.newPassword ?? "";
|
|
18430
18516
|
const passwordConfirmation = req.body.passwordConfirmation ?? "";
|
|
18431
18517
|
try {
|
|
18432
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
18518
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users" });
|
|
18433
18519
|
await _updatePasswordById(
|
|
18434
18520
|
_id,
|
|
18435
18521
|
currentPassword,
|
|
@@ -18538,7 +18624,7 @@ function useRoleService() {
|
|
|
18538
18624
|
async function requireRoleOrg(req, org) {
|
|
18539
18625
|
const orgId = org?.toString() ?? "";
|
|
18540
18626
|
if (!orgId) {
|
|
18541
|
-
await
|
|
18627
|
+
await requireConsolePermission(req, "roles-and-permissions");
|
|
18542
18628
|
return;
|
|
18543
18629
|
}
|
|
18544
18630
|
await requireOrgAccess(req, orgId);
|
|
@@ -18580,7 +18666,7 @@ function useRoleController() {
|
|
|
18580
18666
|
}
|
|
18581
18667
|
try {
|
|
18582
18668
|
if (payload.type === PLATFORM_STAFF_ROLE_TYPE) {
|
|
18583
|
-
await
|
|
18669
|
+
await requireConsolePermission(req, "roles-and-permissions", "add-role");
|
|
18584
18670
|
}
|
|
18585
18671
|
if (payload.org) {
|
|
18586
18672
|
await requireOrgReach(req, payload.org);
|
|
@@ -21988,13 +22074,14 @@ function useFileService() {
|
|
|
21988
22074
|
bucket: SPACES_BUCKET,
|
|
21989
22075
|
forcePathStyle: true
|
|
21990
22076
|
});
|
|
21991
|
-
async function createFile(value, folder = "default") {
|
|
22077
|
+
async function createFile(value, folder = "default", createdBy) {
|
|
21992
22078
|
const session = useAtlas29.getClient()?.startSession();
|
|
21993
22079
|
session?.startTransaction();
|
|
21994
22080
|
const file = {
|
|
21995
22081
|
name: value.originalname,
|
|
21996
22082
|
size: value.size ?? (value.buffer ? value.buffer.length : 0),
|
|
21997
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
22083
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22084
|
+
...createdBy ? { createdBy } : {}
|
|
21998
22085
|
};
|
|
21999
22086
|
try {
|
|
22000
22087
|
const id = await _createFile(file, session);
|
|
@@ -26204,7 +26291,7 @@ async function entitledSites(req) {
|
|
|
26204
26291
|
async function requireMemberOrg(req, org) {
|
|
26205
26292
|
const orgId = org?.toString() ?? "";
|
|
26206
26293
|
if (!orgId) {
|
|
26207
|
-
await
|
|
26294
|
+
await requireConsolePermission(req, "members");
|
|
26208
26295
|
return;
|
|
26209
26296
|
}
|
|
26210
26297
|
await requireOrgAccess(req, orgId);
|
|
@@ -26251,7 +26338,7 @@ function useMemberController() {
|
|
|
26251
26338
|
return;
|
|
26252
26339
|
}
|
|
26253
26340
|
try {
|
|
26254
|
-
await requireSelfOrPlatformStaff(req, userId);
|
|
26341
|
+
await requireSelfOrPlatformStaff(req, userId, { resource: "members", action: "view-members" });
|
|
26255
26342
|
const data = await _getByUserId(userId);
|
|
26256
26343
|
res.json(data);
|
|
26257
26344
|
return;
|
|
@@ -26301,7 +26388,7 @@ function useMemberController() {
|
|
|
26301
26388
|
const user = req.params.id;
|
|
26302
26389
|
const type = req.params.type;
|
|
26303
26390
|
try {
|
|
26304
|
-
await requireSelfOrPlatformStaff(req, user);
|
|
26391
|
+
await requireSelfOrPlatformStaff(req, user, { resource: "members", action: "view-members" });
|
|
26305
26392
|
const data = await _getByUserIdType(user, type);
|
|
26306
26393
|
res.json(data);
|
|
26307
26394
|
return;
|
|
@@ -26347,11 +26434,11 @@ function useMemberController() {
|
|
|
26347
26434
|
}
|
|
26348
26435
|
try {
|
|
26349
26436
|
if (type === "admin") {
|
|
26350
|
-
await
|
|
26437
|
+
await requireConsolePermission(req, "members", "view-members");
|
|
26351
26438
|
} else if (org) {
|
|
26352
26439
|
await requireOrgAccess(req, org);
|
|
26353
26440
|
} else if (user && user !== callerId(req)) {
|
|
26354
|
-
await
|
|
26441
|
+
await requireConsolePermission(req, "users", "see-all-users");
|
|
26355
26442
|
}
|
|
26356
26443
|
const items = await _getAll({
|
|
26357
26444
|
search,
|
|
@@ -26546,7 +26633,7 @@ function useMemberController() {
|
|
|
26546
26633
|
const type = req.params.type;
|
|
26547
26634
|
const org = req.query.org;
|
|
26548
26635
|
try {
|
|
26549
|
-
await requireSelfOrPlatformStaff(req, user);
|
|
26636
|
+
await requireSelfOrPlatformStaff(req, user, { resource: "members", action: "view-members" });
|
|
26550
26637
|
const data = await _getByUserIdTypeOrg(
|
|
26551
26638
|
user,
|
|
26552
26639
|
type,
|
|
@@ -27078,8 +27165,55 @@ function useVerificationController() {
|
|
|
27078
27165
|
}
|
|
27079
27166
|
|
|
27080
27167
|
// src/controllers/file.controller.ts
|
|
27081
|
-
import {
|
|
27168
|
+
import {
|
|
27169
|
+
BadRequestError as BadRequestError50,
|
|
27170
|
+
UnauthorizedError as UnauthorizedError7,
|
|
27171
|
+
logger as logger35
|
|
27172
|
+
} from "@7365admin1/node-server-utils";
|
|
27082
27173
|
import Joi27 from "joi";
|
|
27174
|
+
|
|
27175
|
+
// src/utils/file-owner.util.ts
|
|
27176
|
+
function fileOwnerId(file) {
|
|
27177
|
+
return file?.createdBy?.toString?.() ?? "";
|
|
27178
|
+
}
|
|
27179
|
+
function mayDeleteFile(params) {
|
|
27180
|
+
if (!params.ownerId)
|
|
27181
|
+
return true;
|
|
27182
|
+
if (!params.callerId)
|
|
27183
|
+
return false;
|
|
27184
|
+
if (params.callerId === params.ownerId)
|
|
27185
|
+
return true;
|
|
27186
|
+
if (params.callerIsSuperAdmin)
|
|
27187
|
+
return true;
|
|
27188
|
+
const ownerOrgs = new Set((params.ownerOrgIds ?? []).map(String));
|
|
27189
|
+
return (params.callerOrgIds ?? []).some((org) => ownerOrgs.has(String(org)));
|
|
27190
|
+
}
|
|
27191
|
+
|
|
27192
|
+
// src/controllers/file.controller.ts
|
|
27193
|
+
async function requireFileDelete(req, file) {
|
|
27194
|
+
const ownerId = fileOwnerId(file);
|
|
27195
|
+
if (!ownerId)
|
|
27196
|
+
return;
|
|
27197
|
+
const caller = callerId(req);
|
|
27198
|
+
if (!caller)
|
|
27199
|
+
throw new UnauthorizedError7("Not authorized.");
|
|
27200
|
+
if (caller === ownerId)
|
|
27201
|
+
return;
|
|
27202
|
+
const [me, owner] = await Promise.all([
|
|
27203
|
+
resolveInviteActor(caller),
|
|
27204
|
+
resolveInviteActor(ownerId)
|
|
27205
|
+
]);
|
|
27206
|
+
if (mayDeleteFile({
|
|
27207
|
+
ownerId,
|
|
27208
|
+
callerId: caller,
|
|
27209
|
+
callerIsSuperAdmin: me.isSuperAdmin,
|
|
27210
|
+
callerOrgIds: me.orgIds,
|
|
27211
|
+
ownerOrgIds: owner.orgIds
|
|
27212
|
+
})) {
|
|
27213
|
+
return;
|
|
27214
|
+
}
|
|
27215
|
+
throw new UnauthorizedError7("Not authorized.");
|
|
27216
|
+
}
|
|
27083
27217
|
function useFileController() {
|
|
27084
27218
|
const { createFile, deleteFile: _deleteFile } = useFileService();
|
|
27085
27219
|
const { getFileById: _getFileById } = useFileRepo();
|
|
@@ -27089,7 +27223,7 @@ function useFileController() {
|
|
|
27089
27223
|
return;
|
|
27090
27224
|
}
|
|
27091
27225
|
try {
|
|
27092
|
-
const id = await createFile(req.file);
|
|
27226
|
+
const id = await createFile(req.file, "default", callerId(req) || void 0);
|
|
27093
27227
|
res.status(201).json({ message: "Successfully uploaded file", id });
|
|
27094
27228
|
return;
|
|
27095
27229
|
} catch (error) {
|
|
@@ -27108,6 +27242,7 @@ function useFileController() {
|
|
|
27108
27242
|
return;
|
|
27109
27243
|
}
|
|
27110
27244
|
try {
|
|
27245
|
+
await requireFileDelete(req, await _getFileById(_id));
|
|
27111
27246
|
const message = await _deleteFile(_id);
|
|
27112
27247
|
res.json({ message });
|
|
27113
27248
|
return;
|
|
@@ -27150,7 +27285,7 @@ import {
|
|
|
27150
27285
|
BadRequestError as BadRequestError54,
|
|
27151
27286
|
logger as logger38,
|
|
27152
27287
|
NotFoundError as NotFoundError17,
|
|
27153
|
-
UnauthorizedError as
|
|
27288
|
+
UnauthorizedError as UnauthorizedError8
|
|
27154
27289
|
} from "@7365admin1/node-server-utils";
|
|
27155
27290
|
import Joi31 from "joi";
|
|
27156
27291
|
|
|
@@ -28354,7 +28489,7 @@ function useOrgController() {
|
|
|
28354
28489
|
return;
|
|
28355
28490
|
}
|
|
28356
28491
|
try {
|
|
28357
|
-
const createdBy = await
|
|
28492
|
+
const createdBy = await requireConsolePermission(req, "organizations");
|
|
28358
28493
|
await _add({ ...req.body, createdBy });
|
|
28359
28494
|
res.status(201).json({ message: "Successfully created organization." });
|
|
28360
28495
|
return;
|
|
@@ -28423,7 +28558,7 @@ function useOrgController() {
|
|
|
28423
28558
|
try {
|
|
28424
28559
|
const createdBy = callerId(req);
|
|
28425
28560
|
if (!createdBy)
|
|
28426
|
-
throw new
|
|
28561
|
+
throw new UnauthorizedError8("Not authorized.");
|
|
28427
28562
|
const _id = await _add({ ...req.body, createdBy });
|
|
28428
28563
|
const data = await _getById(_id);
|
|
28429
28564
|
res.status(201).json({
|
|
@@ -28460,7 +28595,7 @@ function useOrgController() {
|
|
|
28460
28595
|
const type = req.query.type ?? "";
|
|
28461
28596
|
try {
|
|
28462
28597
|
if (user !== callerId(req)) {
|
|
28463
|
-
await
|
|
28598
|
+
await requireConsolePermission(req, "organizations", "see-all-organizations");
|
|
28464
28599
|
}
|
|
28465
28600
|
const data = await getOrgsByMembership({
|
|
28466
28601
|
search,
|
|
@@ -28487,7 +28622,7 @@ function useOrgController() {
|
|
|
28487
28622
|
return;
|
|
28488
28623
|
}
|
|
28489
28624
|
try {
|
|
28490
|
-
await
|
|
28625
|
+
await requireConsolePermission(req, "organizations", "see-organization-details");
|
|
28491
28626
|
const data = await _getByName(name);
|
|
28492
28627
|
res.json(data);
|
|
28493
28628
|
return;
|
|
@@ -28525,7 +28660,7 @@ function useOrgController() {
|
|
|
28525
28660
|
return;
|
|
28526
28661
|
}
|
|
28527
28662
|
try {
|
|
28528
|
-
await
|
|
28663
|
+
await requireConsolePermission(req, "organizations", "see-organization-details");
|
|
28529
28664
|
const data = await _getByEmail(email);
|
|
28530
28665
|
if (!data) {
|
|
28531
28666
|
next(new NotFoundError17("Organization not found."));
|
|
@@ -28555,7 +28690,7 @@ function useOrgController() {
|
|
|
28555
28690
|
try {
|
|
28556
28691
|
const self = await _getUserById(callerId(req)).catch(() => null);
|
|
28557
28692
|
if (!self?.email || self.email.toLowerCase() !== email.toLowerCase()) {
|
|
28558
|
-
await
|
|
28693
|
+
await requireConsolePermission(req, "organizations", "see-all-organizations");
|
|
28559
28694
|
}
|
|
28560
28695
|
const data = await _getOrgsByEmail(email);
|
|
28561
28696
|
res.json(data);
|
|
@@ -28615,7 +28750,7 @@ function useOrgController() {
|
|
|
28615
28750
|
const orgId = req.params.id;
|
|
28616
28751
|
const { status } = req.body;
|
|
28617
28752
|
try {
|
|
28618
|
-
const ownerId = await requirePlatformOwner(req);
|
|
28753
|
+
const ownerId = await requirePlatformOwner(req, { resource: "organizations" });
|
|
28619
28754
|
await _updateStatusById(orgId, status);
|
|
28620
28755
|
const subscription = await _getSubscriptionByOrgId(orgId);
|
|
28621
28756
|
if (subscription) {
|
|
@@ -28686,7 +28821,7 @@ function useOrgControllerV2() {
|
|
|
28686
28821
|
const nature = value.nature ?? "";
|
|
28687
28822
|
const status = value.status;
|
|
28688
28823
|
try {
|
|
28689
|
-
await
|
|
28824
|
+
await requireConsolePermission(req, "organizations", "see-all-organizations");
|
|
28690
28825
|
const data = await _getAll({
|
|
28691
28826
|
search,
|
|
28692
28827
|
page,
|
|
@@ -28723,7 +28858,7 @@ function useOrgControllerV2() {
|
|
|
28723
28858
|
return;
|
|
28724
28859
|
}
|
|
28725
28860
|
try {
|
|
28726
|
-
await
|
|
28861
|
+
await requireConsolePermission(req, "organizations", "see-all-organizations");
|
|
28727
28862
|
const data = await _getOrganizationsWithSubscription({
|
|
28728
28863
|
search: value.search ?? "",
|
|
28729
28864
|
page: value.page ?? 1,
|
|
@@ -30924,7 +31059,7 @@ function useSubscriptionService() {
|
|
|
30924
31059
|
import Joi36 from "joi";
|
|
30925
31060
|
import {
|
|
30926
31061
|
BadRequestError as BadRequestError70,
|
|
30927
|
-
UnauthorizedError as
|
|
31062
|
+
UnauthorizedError as UnauthorizedError9,
|
|
30928
31063
|
logger as logger48
|
|
30929
31064
|
} from "@7365admin1/node-server-utils";
|
|
30930
31065
|
|
|
@@ -31252,7 +31387,7 @@ function useSubscriptionController() {
|
|
|
31252
31387
|
return;
|
|
31253
31388
|
}
|
|
31254
31389
|
try {
|
|
31255
|
-
await
|
|
31390
|
+
await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31256
31391
|
const id = await _add(payload);
|
|
31257
31392
|
res.status(201).json({ message: "Successfully added subscription.", id });
|
|
31258
31393
|
return;
|
|
@@ -31299,7 +31434,7 @@ function useSubscriptionController() {
|
|
|
31299
31434
|
const page = parseInt(req.query.page ?? "1");
|
|
31300
31435
|
const status = req.query.status ?? "active";
|
|
31301
31436
|
try {
|
|
31302
|
-
await
|
|
31437
|
+
await requireConsolePermission(req, "subscriptions", "see-all-subscriptions");
|
|
31303
31438
|
const data = await _getSubscriptions({ search, page, status });
|
|
31304
31439
|
res.json(data);
|
|
31305
31440
|
return;
|
|
@@ -31345,7 +31480,7 @@ function useSubscriptionController() {
|
|
|
31345
31480
|
try {
|
|
31346
31481
|
const subscription = await _getSubscriptionById(subscriptionId);
|
|
31347
31482
|
if (!subscription) {
|
|
31348
|
-
throw new
|
|
31483
|
+
throw new UnauthorizedError9("Not authorized.");
|
|
31349
31484
|
}
|
|
31350
31485
|
await requireOrgAccess(req, subscription.org?.toString());
|
|
31351
31486
|
const _res = await _updateSubscriptionSeats({
|
|
@@ -31433,7 +31568,7 @@ function useSubscriptionController() {
|
|
|
31433
31568
|
}
|
|
31434
31569
|
async function createConsoleSubscription(req, res, next) {
|
|
31435
31570
|
try {
|
|
31436
|
-
const staffId = await
|
|
31571
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31437
31572
|
const form = await readConsoleForm(req);
|
|
31438
31573
|
const existing = await _getByOrgId(form.orgId);
|
|
31439
31574
|
if (existing && existing.status !== "ended") {
|
|
@@ -31479,7 +31614,7 @@ function useSubscriptionController() {
|
|
|
31479
31614
|
}
|
|
31480
31615
|
async function updateConsoleSubscription(req, res, next) {
|
|
31481
31616
|
try {
|
|
31482
|
-
const staffId = await
|
|
31617
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31483
31618
|
const form = await readConsoleForm(req);
|
|
31484
31619
|
const existing = await _getByOrgId(form.orgId);
|
|
31485
31620
|
if (!existing?._id) {
|
|
@@ -31519,7 +31654,7 @@ function useSubscriptionController() {
|
|
|
31519
31654
|
}
|
|
31520
31655
|
async function getConsoleSubscription(req, res, next) {
|
|
31521
31656
|
try {
|
|
31522
|
-
await
|
|
31657
|
+
await requireConsolePermission(req, "subscriptions", "see-subscription-details");
|
|
31523
31658
|
const orgId = req.params.id;
|
|
31524
31659
|
if (!/^[0-9a-fA-F]{24}$/.test(orgId ?? "")) {
|
|
31525
31660
|
throw new BadRequestError70("That client could not be found.");
|
|
@@ -31588,7 +31723,7 @@ function useSubscriptionPlanController() {
|
|
|
31588
31723
|
return;
|
|
31589
31724
|
}
|
|
31590
31725
|
try {
|
|
31591
|
-
const staffId = await
|
|
31726
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31592
31727
|
const _id = await _add(req.body);
|
|
31593
31728
|
const data = await _getById(_id);
|
|
31594
31729
|
await recordConsoleAction({
|
|
@@ -31684,7 +31819,7 @@ function useSubscriptionPlanController() {
|
|
|
31684
31819
|
}
|
|
31685
31820
|
const id = req.params.id;
|
|
31686
31821
|
try {
|
|
31687
|
-
const staffId = await
|
|
31822
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31688
31823
|
const before = await _getById(id);
|
|
31689
31824
|
await _update(id, req.body);
|
|
31690
31825
|
const data = await _getById(id);
|
|
@@ -31716,7 +31851,7 @@ function useSubscriptionPlanController() {
|
|
|
31716
31851
|
const id = req.params.id;
|
|
31717
31852
|
const { status } = req.body;
|
|
31718
31853
|
try {
|
|
31719
|
-
const staffId = await
|
|
31854
|
+
const staffId = await requireConsolePermission(req, "subscriptions", "manage-subscription");
|
|
31720
31855
|
await _updateStatusById(id, status);
|
|
31721
31856
|
const data = await _getById(id);
|
|
31722
31857
|
await recordConsoleAction({
|
|
@@ -31861,7 +31996,7 @@ function usePromoCodeController() {
|
|
|
31861
31996
|
payload.code = payload.code.trim().toUpperCase();
|
|
31862
31997
|
payload.fixed_rate = parseInt(payload.fixed_rate ?? "0");
|
|
31863
31998
|
try {
|
|
31864
|
-
const staffId = await
|
|
31999
|
+
const staffId = await requireConsolePermission(req, "promo-codes", "create-promo-code");
|
|
31865
32000
|
const created = await _add(payload);
|
|
31866
32001
|
await recordConsoleAction({
|
|
31867
32002
|
action: "promo-code.created" /* PROMO_CODE_CREATED */,
|
|
@@ -31914,7 +32049,7 @@ function usePromoCodeController() {
|
|
|
31914
32049
|
return;
|
|
31915
32050
|
}
|
|
31916
32051
|
try {
|
|
31917
|
-
await
|
|
32052
|
+
await requireConsolePermission(req, "promo-codes", "see-promo-code-details");
|
|
31918
32053
|
const data = await _getById(_id);
|
|
31919
32054
|
res.json(data);
|
|
31920
32055
|
return;
|
|
@@ -31943,7 +32078,7 @@ function usePromoCodeController() {
|
|
|
31943
32078
|
const limit = parseInt(req.query.limit ?? "10");
|
|
31944
32079
|
const status = req.query.status ?? "active";
|
|
31945
32080
|
try {
|
|
31946
|
-
await
|
|
32081
|
+
await requireConsolePermission(req, "promo-codes");
|
|
31947
32082
|
const data = await _getPromoCodes({
|
|
31948
32083
|
search,
|
|
31949
32084
|
page,
|
|
@@ -31968,7 +32103,7 @@ function usePromoCodeController() {
|
|
|
31968
32103
|
return;
|
|
31969
32104
|
}
|
|
31970
32105
|
try {
|
|
31971
|
-
const staffId = await
|
|
32106
|
+
const staffId = await requireConsolePermission(req, "promo-codes", "edit-promo-code-details");
|
|
31972
32107
|
const before = await _getById(req.params.id);
|
|
31973
32108
|
await _updateById(req.params.id, req.body);
|
|
31974
32109
|
await recordConsoleAction({
|
|
@@ -32004,7 +32139,7 @@ function usePromoCodeController() {
|
|
|
32004
32139
|
return;
|
|
32005
32140
|
}
|
|
32006
32141
|
try {
|
|
32007
|
-
const staffId = await
|
|
32142
|
+
const staffId = await requireConsolePermission(req, "promo-codes", "change-promo-code-status");
|
|
32008
32143
|
await _updateStatusById(req.params.id, status.value.status);
|
|
32009
32144
|
await recordConsoleAction({
|
|
32010
32145
|
action: "promo-code.status-changed" /* PROMO_CODE_STATUS_CHANGED */,
|
|
@@ -32033,7 +32168,7 @@ function usePromoCodeController() {
|
|
|
32033
32168
|
return;
|
|
32034
32169
|
}
|
|
32035
32170
|
try {
|
|
32036
|
-
const staffId = await
|
|
32171
|
+
const staffId = await requireConsolePermission(req, "promo-codes", "delete-promo-code");
|
|
32037
32172
|
await _softDeleteById(req.params.id, staffId);
|
|
32038
32173
|
await recordConsoleAction({
|
|
32039
32174
|
action: "promo-code.removed" /* PROMO_CODE_REMOVED */,
|
|
@@ -41677,7 +41812,7 @@ function useCustomerSiteService() {
|
|
|
41677
41812
|
import Joi59 from "joi";
|
|
41678
41813
|
import {
|
|
41679
41814
|
BadRequestError as BadRequestError106,
|
|
41680
|
-
UnauthorizedError as
|
|
41815
|
+
UnauthorizedError as UnauthorizedError10,
|
|
41681
41816
|
logger as logger78
|
|
41682
41817
|
} from "@7365admin1/node-server-utils";
|
|
41683
41818
|
async function requireEitherOrg(req, ...orgs) {
|
|
@@ -41686,7 +41821,7 @@ async function requireEitherOrg(req, ...orgs) {
|
|
|
41686
41821
|
if (actor.isSuperAdmin)
|
|
41687
41822
|
return;
|
|
41688
41823
|
if (wanted.length === 0 || !wanted.some((org) => actor.orgIds.includes(org))) {
|
|
41689
|
-
throw new
|
|
41824
|
+
throw new UnauthorizedError10("Not authorized.");
|
|
41690
41825
|
}
|
|
41691
41826
|
}
|
|
41692
41827
|
function useCustomerSiteController() {
|
|
@@ -44899,7 +45034,7 @@ import {
|
|
|
44899
45034
|
BadRequestError as BadRequestError120,
|
|
44900
45035
|
InternalServerError as InternalServerError42,
|
|
44901
45036
|
NotFoundError as NotFoundError34,
|
|
44902
|
-
UnauthorizedError as
|
|
45037
|
+
UnauthorizedError as UnauthorizedError11,
|
|
44903
45038
|
logger as logger90
|
|
44904
45039
|
} from "@7365admin1/node-server-utils";
|
|
44905
45040
|
|
|
@@ -48433,8 +48568,8 @@ function useHidAmicoService() {
|
|
|
48433
48568
|
await siteAccess.authorizeSite({ siteId, userId: value.userId, permissions });
|
|
48434
48569
|
}
|
|
48435
48570
|
} catch (error) {
|
|
48436
|
-
if (error instanceof
|
|
48437
|
-
throw new
|
|
48571
|
+
if (error instanceof UnauthorizedError11) {
|
|
48572
|
+
throw new UnauthorizedError11("You do not have permission to manage HID access at this site.");
|
|
48438
48573
|
}
|
|
48439
48574
|
throw error;
|
|
48440
48575
|
}
|
|
@@ -48458,7 +48593,7 @@ function useHidAmicoService() {
|
|
|
48458
48593
|
try {
|
|
48459
48594
|
await authorizeSiteForCaller(String(reader.site || ""), userId);
|
|
48460
48595
|
} catch (error) {
|
|
48461
|
-
if (error instanceof
|
|
48596
|
+
if (error instanceof UnauthorizedError11)
|
|
48462
48597
|
throw error;
|
|
48463
48598
|
throw new NotFoundError34(HID_READER_NOT_FOUND);
|
|
48464
48599
|
}
|
|
@@ -48510,10 +48645,10 @@ function useHidAmicoService() {
|
|
|
48510
48645
|
async function assertUserReaderPermission(reader, userId, options = {}) {
|
|
48511
48646
|
const permission = await getReaderPermissionForUser(reader, userId);
|
|
48512
48647
|
if (!permission.granted) {
|
|
48513
|
-
throw new
|
|
48648
|
+
throw new UnauthorizedError11("You do not have HID access permission for this reader.");
|
|
48514
48649
|
}
|
|
48515
48650
|
if (options.intercom && !permission.intercom) {
|
|
48516
|
-
throw new
|
|
48651
|
+
throw new UnauthorizedError11("You do not have HID intercom permission for this reader.");
|
|
48517
48652
|
}
|
|
48518
48653
|
return permission;
|
|
48519
48654
|
}
|
|
@@ -49851,10 +49986,10 @@ function useHidAmicoService() {
|
|
|
49851
49986
|
const hasActiveMembership = memberships.some((membership) => membership.status !== "deleted" && membership.status !== "inactive");
|
|
49852
49987
|
const resolvedIssuer = issuer || (hasResidentMembership ? "resident" : "property_management");
|
|
49853
49988
|
if (resolvedIssuer === "resident" && !hasResidentMembership) {
|
|
49854
|
-
throw new
|
|
49989
|
+
throw new UnauthorizedError11("Only a Resident account can issue a Resident visitor QR code.");
|
|
49855
49990
|
}
|
|
49856
49991
|
if (resolvedIssuer === "property_management" && !hasActiveMembership) {
|
|
49857
|
-
throw new
|
|
49992
|
+
throw new UnauthorizedError11("Only a site Property Management account can issue this visitor QR code.");
|
|
49858
49993
|
}
|
|
49859
49994
|
const configuredGateIds = site?.metadata?.hidQrCodePass?.qrGatePermissions?.[resolvedIssuer === "resident" ? "resident" : "propertyManagement"] || [];
|
|
49860
49995
|
const gateReaderIds = configuredGateIds.filter((readerId) => typeof readerId === "string" && /^[a-f0-9]{24}$/i.test(readerId)).map(String);
|
|
@@ -52447,7 +52582,7 @@ function useVisitorTransactionService() {
|
|
|
52447
52582
|
import Joi68 from "joi";
|
|
52448
52583
|
import moment5 from "moment-timezone";
|
|
52449
52584
|
import { ObjectId as ObjectId89 } from "mongodb";
|
|
52450
|
-
import { BadRequestError as BadRequestError123, NotFoundError as NotFoundError36, InternalServerError as InternalServerError44, UnauthorizedError as
|
|
52585
|
+
import { BadRequestError as BadRequestError123, NotFoundError as NotFoundError36, InternalServerError as InternalServerError44, UnauthorizedError as UnauthorizedError12, logger as logger94 } from "@7365admin1/node-server-utils";
|
|
52451
52586
|
|
|
52452
52587
|
// src/models/visitor-invite.model.ts
|
|
52453
52588
|
import Joi66 from "joi";
|
|
@@ -57231,7 +57366,7 @@ function useVisitorTransactionController() {
|
|
|
57231
57366
|
}
|
|
57232
57367
|
const inviterUserId = callerId(req);
|
|
57233
57368
|
if (!inviterUserId) {
|
|
57234
|
-
next(new
|
|
57369
|
+
next(new UnauthorizedError12("Not authorized."));
|
|
57235
57370
|
return;
|
|
57236
57371
|
}
|
|
57237
57372
|
try {
|
|
@@ -57795,7 +57930,7 @@ function useGuestManagementController() {
|
|
|
57795
57930
|
// src/controllers/person.controller.ts
|
|
57796
57931
|
import Joi71 from "joi";
|
|
57797
57932
|
import { BadRequestError as BadRequestError126, logger as logger97 } from "@7365admin1/node-server-utils";
|
|
57798
|
-
import { NotFoundError as NotFoundError37, UnauthorizedError as
|
|
57933
|
+
import { NotFoundError as NotFoundError37, UnauthorizedError as UnauthorizedError13 } from "@7365admin1/node-server-utils";
|
|
57799
57934
|
function usePersonController() {
|
|
57800
57935
|
const {
|
|
57801
57936
|
getAll: _getAll,
|
|
@@ -57829,7 +57964,7 @@ function usePersonController() {
|
|
|
57829
57964
|
}
|
|
57830
57965
|
const org = person.org?.toString() ?? "";
|
|
57831
57966
|
if (!org || !actor.orgIds.includes(org)) {
|
|
57832
|
-
throw new
|
|
57967
|
+
throw new UnauthorizedError13("Not authorized.");
|
|
57833
57968
|
}
|
|
57834
57969
|
return actor;
|
|
57835
57970
|
}
|
|
@@ -57955,7 +58090,7 @@ function usePersonController() {
|
|
|
57955
58090
|
});
|
|
57956
58091
|
} else if (org) {
|
|
57957
58092
|
if (!actor.orgIds.includes(org)) {
|
|
57958
|
-
throw new
|
|
58093
|
+
throw new UnauthorizedError13("Not authorized.");
|
|
57959
58094
|
}
|
|
57960
58095
|
} else {
|
|
57961
58096
|
orgs = actor.orgIds;
|
|
@@ -62275,7 +62410,7 @@ function useSiteFacilityService() {
|
|
|
62275
62410
|
import {
|
|
62276
62411
|
BadRequestError as BadRequestError148,
|
|
62277
62412
|
NotFoundError as NotFoundError43,
|
|
62278
|
-
UnauthorizedError as
|
|
62413
|
+
UnauthorizedError as UnauthorizedError14,
|
|
62279
62414
|
logger as logger116
|
|
62280
62415
|
} from "@7365admin1/node-server-utils";
|
|
62281
62416
|
import Joi83 from "joi";
|
|
@@ -62362,7 +62497,7 @@ function useSiteFacilityController() {
|
|
|
62362
62497
|
} else {
|
|
62363
62498
|
const { actor } = await siteReachOf(req);
|
|
62364
62499
|
if (!actor.isSuperAdmin)
|
|
62365
|
-
throw new
|
|
62500
|
+
throw new UnauthorizedError14("Not authorized.");
|
|
62366
62501
|
}
|
|
62367
62502
|
const data = await _getAll({
|
|
62368
62503
|
search,
|
|
@@ -65397,7 +65532,7 @@ function useBulletinBoardService() {
|
|
|
65397
65532
|
import {
|
|
65398
65533
|
BadRequestError as BadRequestError157,
|
|
65399
65534
|
NotFoundError as NotFoundError51,
|
|
65400
|
-
UnauthorizedError as
|
|
65535
|
+
UnauthorizedError as UnauthorizedError15,
|
|
65401
65536
|
logger as logger125
|
|
65402
65537
|
} from "@7365admin1/node-server-utils";
|
|
65403
65538
|
import Joi91 from "joi";
|
|
@@ -65433,7 +65568,7 @@ function useBulletinBoardController() {
|
|
|
65433
65568
|
} else {
|
|
65434
65569
|
const { canReach } = await siteReachOf(req);
|
|
65435
65570
|
if (!await canReach(scopeOf(value))) {
|
|
65436
|
-
throw new
|
|
65571
|
+
throw new UnauthorizedError15("Not authorized.");
|
|
65437
65572
|
}
|
|
65438
65573
|
}
|
|
65439
65574
|
const data = await _add(value);
|
|
@@ -65990,7 +66125,7 @@ import { BadRequestError as BadRequestError163, logger as logger131 } from "@736
|
|
|
65990
66125
|
import {
|
|
65991
66126
|
BadRequestError as BadRequestError162,
|
|
65992
66127
|
logger as logger130,
|
|
65993
|
-
UnauthorizedError as
|
|
66128
|
+
UnauthorizedError as UnauthorizedError16,
|
|
65994
66129
|
useAtlas as useAtlas88
|
|
65995
66130
|
} from "@7365admin1/node-server-utils";
|
|
65996
66131
|
|
|
@@ -66374,7 +66509,7 @@ function useSiteBillingItemService() {
|
|
|
66374
66509
|
function assertUnitAtSite(buildingUnit, site) {
|
|
66375
66510
|
const siteId = site?.toString?.() ?? "";
|
|
66376
66511
|
if (!siteId || (buildingUnit?.site?.toString() ?? "") !== siteId) {
|
|
66377
|
-
throw new
|
|
66512
|
+
throw new UnauthorizedError16("Not authorized.");
|
|
66378
66513
|
}
|
|
66379
66514
|
}
|
|
66380
66515
|
async function add(value) {
|
|
@@ -66545,7 +66680,7 @@ function useSiteBillingItemService() {
|
|
|
66545
66680
|
message: error.message
|
|
66546
66681
|
});
|
|
66547
66682
|
await session.abortTransaction();
|
|
66548
|
-
if (error instanceof BadRequestError162 || error instanceof
|
|
66683
|
+
if (error instanceof BadRequestError162 || error instanceof UnauthorizedError16) {
|
|
66549
66684
|
throw error;
|
|
66550
66685
|
}
|
|
66551
66686
|
throw new BadRequestError162("Failed to update Site Billing Item.");
|
|
@@ -68514,7 +68649,7 @@ import Joi99 from "joi";
|
|
|
68514
68649
|
|
|
68515
68650
|
// src/utils/resident-unit.util.ts
|
|
68516
68651
|
import { ObjectId as ObjectId123 } from "mongodb";
|
|
68517
|
-
import { UnauthorizedError as
|
|
68652
|
+
import { UnauthorizedError as UnauthorizedError17, useAtlas as useAtlas94 } from "@7365admin1/node-server-utils";
|
|
68518
68653
|
async function requireOwnUnit(req, site, unitId) {
|
|
68519
68654
|
const actor = await resolveInviteActor(callerId(req));
|
|
68520
68655
|
if (actor.isSuperAdmin)
|
|
@@ -68522,7 +68657,7 @@ async function requireOwnUnit(req, site, unitId) {
|
|
|
68522
68657
|
const unit = unitId?.toString?.() ?? "";
|
|
68523
68658
|
const siteId = site?.toString?.() ?? "";
|
|
68524
68659
|
if (!ObjectId123.isValid(unit) || !ObjectId123.isValid(siteId) || !actor.id) {
|
|
68525
|
-
throw new
|
|
68660
|
+
throw new UnauthorizedError17("Not authorized.");
|
|
68526
68661
|
}
|
|
68527
68662
|
const db2 = useAtlas94.getDb();
|
|
68528
68663
|
if (!db2)
|
|
@@ -68534,7 +68669,7 @@ async function requireOwnUnit(req, site, unitId) {
|
|
|
68534
68669
|
status: { $ne: "deleted" }
|
|
68535
68670
|
});
|
|
68536
68671
|
if (!own)
|
|
68537
|
-
throw new
|
|
68672
|
+
throw new UnauthorizedError17("Not authorized.");
|
|
68538
68673
|
}
|
|
68539
68674
|
|
|
68540
68675
|
// src/controllers/site-unit-billing.controller.ts
|
|
@@ -77086,7 +77221,7 @@ function useOnlineFormRepo() {
|
|
|
77086
77221
|
import {
|
|
77087
77222
|
BadRequestError as BadRequestError203,
|
|
77088
77223
|
NotFoundError as NotFoundError71,
|
|
77089
|
-
UnauthorizedError as
|
|
77224
|
+
UnauthorizedError as UnauthorizedError18,
|
|
77090
77225
|
logger as logger169
|
|
77091
77226
|
} from "@7365admin1/node-server-utils";
|
|
77092
77227
|
import Joi122 from "joi";
|
|
@@ -77158,10 +77293,10 @@ function useOnlineFormController() {
|
|
|
77158
77293
|
if (site) {
|
|
77159
77294
|
await requireSiteReach(req, site);
|
|
77160
77295
|
} else if (!actor.isSuperAdmin) {
|
|
77161
|
-
throw new
|
|
77296
|
+
throw new UnauthorizedError18("Not authorized.");
|
|
77162
77297
|
}
|
|
77163
77298
|
if (org && !actor.isSuperAdmin && !actor.orgIds.includes(org)) {
|
|
77164
|
-
throw new
|
|
77299
|
+
throw new UnauthorizedError18("Not authorized.");
|
|
77165
77300
|
}
|
|
77166
77301
|
const data = await _getAll({ search, page, limit, status, org, site });
|
|
77167
77302
|
res.json(data);
|
|
@@ -77226,7 +77361,7 @@ function useOnlineFormController() {
|
|
|
77226
77361
|
if (payload.org) {
|
|
77227
77362
|
const { actor } = await siteReachOf(req);
|
|
77228
77363
|
if (!actor.isSuperAdmin && !actor.orgIds.includes(payload.org)) {
|
|
77229
|
-
throw new
|
|
77364
|
+
throw new UnauthorizedError18("Not authorized.");
|
|
77230
77365
|
}
|
|
77231
77366
|
}
|
|
77232
77367
|
await _updateOnlineFormById(_id, payload);
|
|
@@ -84472,7 +84607,7 @@ import {
|
|
|
84472
84607
|
BadRequestError as BadRequestError228,
|
|
84473
84608
|
NotFoundError as NotFoundError78,
|
|
84474
84609
|
InternalServerError as InternalServerError81,
|
|
84475
|
-
UnauthorizedError as
|
|
84610
|
+
UnauthorizedError as UnauthorizedError19,
|
|
84476
84611
|
useAtlas as useAtlas131,
|
|
84477
84612
|
hashPassword as hashPassword4
|
|
84478
84613
|
} from "@7365admin1/node-server-utils";
|
|
@@ -84741,10 +84876,10 @@ function useVerificationServiceV2() {
|
|
|
84741
84876
|
const org = await getOrgById(orgId);
|
|
84742
84877
|
const actor = await resolveInviteActor(invitedBy);
|
|
84743
84878
|
if (!actor.id) {
|
|
84744
|
-
throw new
|
|
84879
|
+
throw new UnauthorizedError19("Sign in to continue.");
|
|
84745
84880
|
}
|
|
84746
84881
|
if (!actor.isSuperAdmin && !actor.orgIds.includes(orgId)) {
|
|
84747
|
-
throw new
|
|
84882
|
+
throw new UnauthorizedError19(
|
|
84748
84883
|
"You can only invite service providers to your own organisation's sites."
|
|
84749
84884
|
);
|
|
84750
84885
|
}
|
|
@@ -86422,7 +86557,7 @@ function useUserControllerV2() {
|
|
|
86422
86557
|
return;
|
|
86423
86558
|
}
|
|
86424
86559
|
try {
|
|
86425
|
-
await requireSelfOrPlatformStaff(req, value);
|
|
86560
|
+
await requireSelfOrPlatformStaff(req, value, { resource: "users", action: "see-user-details" });
|
|
86426
86561
|
const user = await _getById(value);
|
|
86427
86562
|
res.json(user);
|
|
86428
86563
|
return;
|
|
@@ -86459,7 +86594,7 @@ function useUserControllerV2() {
|
|
|
86459
86594
|
if (error)
|
|
86460
86595
|
return rejectValidation(error, next);
|
|
86461
86596
|
try {
|
|
86462
|
-
await
|
|
86597
|
+
await requireConsolePermission(req, "users", "see-all-users");
|
|
86463
86598
|
const users = await _getUsers({
|
|
86464
86599
|
search: value.search ?? "",
|
|
86465
86600
|
page: value.page,
|
|
@@ -86584,7 +86719,7 @@ function useUserControllerV2() {
|
|
|
86584
86719
|
return;
|
|
86585
86720
|
}
|
|
86586
86721
|
try {
|
|
86587
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
86722
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users" });
|
|
86588
86723
|
const message = await _updateBirthday({ _id, ...payload });
|
|
86589
86724
|
res.json({ message });
|
|
86590
86725
|
return;
|
|
@@ -86616,7 +86751,7 @@ function useUserControllerV2() {
|
|
|
86616
86751
|
return;
|
|
86617
86752
|
}
|
|
86618
86753
|
try {
|
|
86619
|
-
await requireUserFieldWrite(req, _id, payload.field);
|
|
86754
|
+
await requireUserFieldWrite(req, _id, payload.field, { resource: "users" });
|
|
86620
86755
|
const message = await _updateUserFieldById({ _id, ...payload });
|
|
86621
86756
|
res.json({ message });
|
|
86622
86757
|
return;
|
|
@@ -86647,7 +86782,7 @@ function useUserControllerV2() {
|
|
|
86647
86782
|
const newPassword = req.body.newPassword ?? "";
|
|
86648
86783
|
const passwordConfirmation = req.body.passwordConfirmation ?? "";
|
|
86649
86784
|
try {
|
|
86650
|
-
await requireSelfOrPlatformStaff(req, _id);
|
|
86785
|
+
await requireSelfOrPlatformStaff(req, _id, { resource: "users" });
|
|
86651
86786
|
await _updatePasswordById(
|
|
86652
86787
|
_id,
|
|
86653
86788
|
currentPassword,
|
|
@@ -86831,7 +86966,7 @@ function useRoleControllerV2() {
|
|
|
86831
86966
|
}
|
|
86832
86967
|
try {
|
|
86833
86968
|
if (value.type === PLATFORM_STAFF_ROLE_TYPE) {
|
|
86834
|
-
await
|
|
86969
|
+
await requireConsolePermission(req, "roles-and-permissions", "add-role");
|
|
86835
86970
|
}
|
|
86836
86971
|
if (value.org) {
|
|
86837
86972
|
await requireOrgReach(req, value.org);
|
|
@@ -89147,7 +89282,7 @@ import Joi158 from "joi";
|
|
|
89147
89282
|
import { ObjectId as ObjectId178 } from "mongodb";
|
|
89148
89283
|
import {
|
|
89149
89284
|
InternalServerError as InternalServerError93,
|
|
89150
|
-
UnauthorizedError as
|
|
89285
|
+
UnauthorizedError as UnauthorizedError20,
|
|
89151
89286
|
useAtlas as useAtlas145
|
|
89152
89287
|
} from "@7365admin1/node-server-utils";
|
|
89153
89288
|
function db() {
|
|
@@ -89163,7 +89298,7 @@ function asObjectId(value) {
|
|
|
89163
89298
|
function requireCaller(req) {
|
|
89164
89299
|
const id = callerId(req);
|
|
89165
89300
|
if (!id || !ObjectId178.isValid(id)) {
|
|
89166
|
-
throw new
|
|
89301
|
+
throw new UnauthorizedError20("Not authorized.");
|
|
89167
89302
|
}
|
|
89168
89303
|
return id;
|
|
89169
89304
|
}
|
|
@@ -89171,7 +89306,7 @@ function requireSelfId(req, claimed) {
|
|
|
89171
89306
|
const caller = requireCaller(req);
|
|
89172
89307
|
const asked = claimed?.toString?.() ?? "";
|
|
89173
89308
|
if (!asked || asked !== caller) {
|
|
89174
|
-
throw new
|
|
89309
|
+
throw new UnauthorizedError20("Not authorized.");
|
|
89175
89310
|
}
|
|
89176
89311
|
return caller;
|
|
89177
89312
|
}
|
|
@@ -89179,11 +89314,11 @@ async function requireOwnChannel(req, channelId) {
|
|
|
89179
89314
|
const caller = requireCaller(req);
|
|
89180
89315
|
const _id = asObjectId(channelId);
|
|
89181
89316
|
if (!_id)
|
|
89182
|
-
throw new
|
|
89317
|
+
throw new UnauthorizedError20("Not authorized.");
|
|
89183
89318
|
const channel = await db().collection("channel-preloved").findOne({ _id }, { projection: { senderId: 1, receiverId: 1, postId: 1 } });
|
|
89184
89319
|
const participants = [channel?.senderId, channel?.receiverId].map((id) => id?.toString?.() ?? "").filter(Boolean);
|
|
89185
89320
|
if (!channel || !participants.includes(caller)) {
|
|
89186
|
-
throw new
|
|
89321
|
+
throw new UnauthorizedError20("Not authorized.");
|
|
89187
89322
|
}
|
|
89188
89323
|
return { caller, channel };
|
|
89189
89324
|
}
|
|
@@ -89191,10 +89326,10 @@ async function requireOwnChatMessage(req, chatId) {
|
|
|
89191
89326
|
const caller = requireCaller(req);
|
|
89192
89327
|
const _id = asObjectId(chatId);
|
|
89193
89328
|
if (!_id)
|
|
89194
|
-
throw new
|
|
89329
|
+
throw new UnauthorizedError20("Not authorized.");
|
|
89195
89330
|
const message = await db().collection("chat-preloved").findOne({ _id }, { projection: { senderId: 1 } });
|
|
89196
89331
|
if (!message || message.senderId?.toString?.() !== caller) {
|
|
89197
|
-
throw new
|
|
89332
|
+
throw new UnauthorizedError20("Not authorized.");
|
|
89198
89333
|
}
|
|
89199
89334
|
return caller;
|
|
89200
89335
|
}
|
|
@@ -89620,7 +89755,7 @@ function useBidPrelovedService() {
|
|
|
89620
89755
|
// src/controllers/bid-preloved.controller.ts
|
|
89621
89756
|
import {
|
|
89622
89757
|
BadRequestError as BadRequestError251,
|
|
89623
|
-
UnauthorizedError as
|
|
89758
|
+
UnauthorizedError as UnauthorizedError21,
|
|
89624
89759
|
logger as logger212
|
|
89625
89760
|
} from "@7365admin1/node-server-utils";
|
|
89626
89761
|
import Joi161 from "joi";
|
|
@@ -89672,7 +89807,7 @@ function useBidPrelovedController() {
|
|
|
89672
89807
|
const bid = await _getById(params.id);
|
|
89673
89808
|
const seller = await sellerOfPost(bid?.postId);
|
|
89674
89809
|
if (!seller || seller !== caller) {
|
|
89675
|
-
throw new
|
|
89810
|
+
throw new UnauthorizedError21("Not authorized.");
|
|
89676
89811
|
}
|
|
89677
89812
|
const data = await _updateStatus(params.id, body.status);
|
|
89678
89813
|
res.status(200).json(data);
|
|
@@ -89696,7 +89831,7 @@ function useBidPrelovedController() {
|
|
|
89696
89831
|
const data = await _getById(params.id);
|
|
89697
89832
|
const seller = await sellerOfPost(data?.postId);
|
|
89698
89833
|
if (data?.buyerId?.toString?.() !== caller && seller !== caller) {
|
|
89699
|
-
throw new
|
|
89834
|
+
throw new UnauthorizedError21("Not authorized.");
|
|
89700
89835
|
}
|
|
89701
89836
|
res.status(200).json(data);
|
|
89702
89837
|
} catch (error2) {
|
|
@@ -90094,7 +90229,7 @@ function useFormEntryRepo() {
|
|
|
90094
90229
|
import {
|
|
90095
90230
|
BadRequestError as BadRequestError253,
|
|
90096
90231
|
NotFoundError as NotFoundError89,
|
|
90097
|
-
UnauthorizedError as
|
|
90232
|
+
UnauthorizedError as UnauthorizedError22,
|
|
90098
90233
|
logger as logger214
|
|
90099
90234
|
} from "@7365admin1/node-server-utils";
|
|
90100
90235
|
import Joi163 from "joi";
|
|
@@ -90204,7 +90339,7 @@ function useFormEntryController() {
|
|
|
90204
90339
|
} else {
|
|
90205
90340
|
const { actor } = await siteReachOf(req);
|
|
90206
90341
|
if (!actor.isSuperAdmin)
|
|
90207
|
-
throw new
|
|
90342
|
+
throw new UnauthorizedError22("Not authorized.");
|
|
90208
90343
|
}
|
|
90209
90344
|
const data = await _getAll({ search, page, limit, status, org, site });
|
|
90210
90345
|
res.json(data);
|
|
@@ -90255,7 +90390,7 @@ function useFormEntryController() {
|
|
|
90255
90390
|
await requireSiteReach(req, rest.site);
|
|
90256
90391
|
delete rest.userId;
|
|
90257
90392
|
if (isOwner && rest.status && rest.status !== "pending") {
|
|
90258
|
-
throw new
|
|
90393
|
+
throw new UnauthorizedError22("Not authorized.");
|
|
90259
90394
|
}
|
|
90260
90395
|
await _updateFormEntryById(_id, rest);
|
|
90261
90396
|
res.json({ message: "Successfully updated online form." });
|
|
@@ -90312,7 +90447,7 @@ function useFormEntryController() {
|
|
|
90312
90447
|
async function residentFormSubmission(req, res, next) {
|
|
90313
90448
|
const userId = callerId(req);
|
|
90314
90449
|
if (!userId) {
|
|
90315
|
-
next(new
|
|
90450
|
+
next(new UnauthorizedError22("Not authorized."));
|
|
90316
90451
|
return;
|
|
90317
90452
|
}
|
|
90318
90453
|
const payload = { ...req.body, userId };
|
|
@@ -91543,7 +91678,7 @@ function useHidAmicoController() {
|
|
|
91543
91678
|
import {
|
|
91544
91679
|
BadRequestError as BadRequestError256,
|
|
91545
91680
|
logger as logger216,
|
|
91546
|
-
UnauthorizedError as
|
|
91681
|
+
UnauthorizedError as UnauthorizedError23
|
|
91547
91682
|
} from "@7365admin1/node-server-utils";
|
|
91548
91683
|
import Joi165 from "joi";
|
|
91549
91684
|
function usePlatformTermsController() {
|
|
@@ -91559,15 +91694,15 @@ function usePlatformTermsController() {
|
|
|
91559
91694
|
async function requireOwnRecord(req, user, { staffMayRead = false } = {}) {
|
|
91560
91695
|
const id = callerId(req);
|
|
91561
91696
|
if (!id) {
|
|
91562
|
-
throw new
|
|
91697
|
+
throw new UnauthorizedError23("Not authorized.");
|
|
91563
91698
|
}
|
|
91564
91699
|
if (id === user) {
|
|
91565
91700
|
return id;
|
|
91566
91701
|
}
|
|
91567
91702
|
if (staffMayRead) {
|
|
91568
|
-
return await
|
|
91703
|
+
return await requireConsolePermission(req, "platform-terms", "see-platform-terms");
|
|
91569
91704
|
}
|
|
91570
|
-
throw new
|
|
91705
|
+
throw new UnauthorizedError23("Not authorized.");
|
|
91571
91706
|
}
|
|
91572
91707
|
async function getLatest(_req, res, next) {
|
|
91573
91708
|
try {
|
|
@@ -91657,7 +91792,7 @@ function usePlatformTermsController() {
|
|
|
91657
91792
|
return;
|
|
91658
91793
|
}
|
|
91659
91794
|
try {
|
|
91660
|
-
await
|
|
91795
|
+
await requireConsolePermission(req, "platform-terms", "see-platform-terms");
|
|
91661
91796
|
res.json(
|
|
91662
91797
|
await _listAcceptance({
|
|
91663
91798
|
version: value.version || null,
|
|
@@ -91689,7 +91824,7 @@ function usePlatformTermsController() {
|
|
|
91689
91824
|
return;
|
|
91690
91825
|
}
|
|
91691
91826
|
try {
|
|
91692
|
-
const staffId = await
|
|
91827
|
+
const staffId = await requireConsolePermission(req, "platform-terms", "edit-platform-terms");
|
|
91693
91828
|
const created = await _add({
|
|
91694
91829
|
terms: value.terms,
|
|
91695
91830
|
policies: value.policies,
|
|
@@ -91747,7 +91882,7 @@ function useConsoleAuditController() {
|
|
|
91747
91882
|
}
|
|
91748
91883
|
const to = value.to && value.to.length === 10 ? `${value.to}T23:59:59.999Z` : value.to;
|
|
91749
91884
|
try {
|
|
91750
|
-
await
|
|
91885
|
+
await requireConsolePermission(req, "activity-history", "see-activity-history");
|
|
91751
91886
|
res.json(
|
|
91752
91887
|
await _list({
|
|
91753
91888
|
org: value.org || "",
|
|
@@ -91773,7 +91908,7 @@ function useConsoleAuditController() {
|
|
|
91773
91908
|
// src/controllers/notification.controller.ts
|
|
91774
91909
|
import {
|
|
91775
91910
|
BadRequestError as BadRequestError258,
|
|
91776
|
-
UnauthorizedError as
|
|
91911
|
+
UnauthorizedError as UnauthorizedError24,
|
|
91777
91912
|
logger as logger218
|
|
91778
91913
|
} from "@7365admin1/node-server-utils";
|
|
91779
91914
|
function useNotificationController() {
|
|
@@ -91791,10 +91926,10 @@ function useNotificationController() {
|
|
|
91791
91926
|
function inboxOwner(req, claimed) {
|
|
91792
91927
|
const caller = callerId5(req);
|
|
91793
91928
|
if (!caller) {
|
|
91794
|
-
throw new
|
|
91929
|
+
throw new UnauthorizedError24("Not authorized.");
|
|
91795
91930
|
}
|
|
91796
91931
|
if (claimed && claimed !== caller) {
|
|
91797
|
-
throw new
|
|
91932
|
+
throw new UnauthorizedError24("Not authorized.");
|
|
91798
91933
|
}
|
|
91799
91934
|
return caller;
|
|
91800
91935
|
}
|
|
@@ -91806,7 +91941,7 @@ function useNotificationController() {
|
|
|
91806
91941
|
}
|
|
91807
91942
|
try {
|
|
91808
91943
|
if (!await isSuperAdmin(callerId5(req))) {
|
|
91809
|
-
throw new
|
|
91944
|
+
throw new UnauthorizedError24("Not authorized.");
|
|
91810
91945
|
}
|
|
91811
91946
|
const inserted = await _addMany(value.to, {
|
|
91812
91947
|
title: value.title,
|
|
@@ -92413,6 +92548,7 @@ export {
|
|
|
92413
92548
|
resolveHidPhysicalCardValue,
|
|
92414
92549
|
resolveInviteActor,
|
|
92415
92550
|
resolveSiteTimezone,
|
|
92551
|
+
resolveStaffRole,
|
|
92416
92552
|
robotSchema,
|
|
92417
92553
|
rtspUrl,
|
|
92418
92554
|
schema,
|