@7365admin1/core 3.53.4 → 3.53.5
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 +6 -0
- package/dist/index.d.ts +106 -36
- package/dist/index.js +495 -477
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +201 -185
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/invite-org-scope.test.mjs +7 -1
- package/test/role-member-org-scope.test.mjs +4 -1
- package/test/staff-bypass-tenant-scope.test.mjs +38 -0
package/dist/index.js
CHANGED
|
@@ -5928,6 +5928,7 @@ __export(src_exports, {
|
|
|
5928
5928
|
CONSOLE_AUDIT_LABELS: () => CONSOLE_AUDIT_LABELS,
|
|
5929
5929
|
CONSOLE_PERMISSIONS: () => CONSOLE_PERMISSIONS,
|
|
5930
5930
|
CONTRACTOR_TYPE_LABELS: () => CONTRACTOR_TYPE_LABELS,
|
|
5931
|
+
CROSS_CLIENT_GRANT: () => CROSS_CLIENT_GRANT,
|
|
5931
5932
|
CURRENT_TIME_ENDPOINT: () => CURRENT_TIME_ENDPOINT,
|
|
5932
5933
|
CameraType: () => CameraType,
|
|
5933
5934
|
ConsoleAuditAction: () => ConsoleAuditAction,
|
|
@@ -6414,6 +6415,7 @@ __export(src_exports, {
|
|
|
6414
6415
|
site_people_namespace_collection: () => site_people_namespace_collection,
|
|
6415
6416
|
snapshotEndpoint: () => snapshotEndpoint,
|
|
6416
6417
|
snapshotRefusalReason: () => snapshotRefusalReason,
|
|
6418
|
+
staffMayBypass: () => staffMayBypass,
|
|
6417
6419
|
stringifyHidJson: () => stringifyHidJson,
|
|
6418
6420
|
stripFacialImageMetadata: () => stripFacialImageMetadata,
|
|
6419
6421
|
subscriptionPlanSchema: () => subscriptionPlanSchema,
|
|
@@ -11197,10 +11199,10 @@ function useAuthService() {
|
|
|
11197
11199
|
|
|
11198
11200
|
// src/controllers/auth.controller.ts
|
|
11199
11201
|
var import_joi16 = __toESM(require("joi"));
|
|
11200
|
-
var
|
|
11202
|
+
var import_node_server_utils40 = require("@7365admin1/node-server-utils");
|
|
11201
11203
|
|
|
11202
11204
|
// src/services/verification.service.ts
|
|
11203
|
-
var
|
|
11205
|
+
var import_node_server_utils35 = require("@7365admin1/node-server-utils");
|
|
11204
11206
|
|
|
11205
11207
|
// src/repositories/verification.repo.ts
|
|
11206
11208
|
var import_node_server_utils19 = require("@7365admin1/node-server-utils");
|
|
@@ -14083,9 +14085,13 @@ async function resolveInviteActor(userId) {
|
|
|
14083
14085
|
const members = await db2.collection("members").find({ user: new import_mongodb25.ObjectId(id), status: { $ne: "deleted" } }).toArray();
|
|
14084
14086
|
const adminMember = members.find((m) => m.type === "admin");
|
|
14085
14087
|
let isSuperAdmin2 = false;
|
|
14088
|
+
let staffPermissions;
|
|
14086
14089
|
if (adminMember?.role && import_mongodb25.ObjectId.isValid(adminMember.role.toString())) {
|
|
14087
14090
|
const role = await db2.collection("roles").findOne({ _id: new import_mongodb25.ObjectId(adminMember.role.toString()), ...LIVE_ROLE });
|
|
14088
14091
|
isSuperAdmin2 = role?.type === "admin";
|
|
14092
|
+
if (isSuperAdmin2) {
|
|
14093
|
+
staffPermissions = Array.isArray(role?.permissions) ? role?.permissions : [];
|
|
14094
|
+
}
|
|
14089
14095
|
}
|
|
14090
14096
|
const orgIds = Array.from(
|
|
14091
14097
|
new Set(
|
|
@@ -14108,6 +14114,7 @@ async function resolveInviteActor(userId) {
|
|
|
14108
14114
|
id,
|
|
14109
14115
|
name: user?.name ?? adminMember?.name ?? "",
|
|
14110
14116
|
isSuperAdmin: isSuperAdmin2,
|
|
14117
|
+
staffPermissions,
|
|
14111
14118
|
orgIds,
|
|
14112
14119
|
propertyManagementOrgIds,
|
|
14113
14120
|
memberships: members.map((m) => ({
|
|
@@ -14208,7 +14215,7 @@ async function holdsRole(userId, roleId) {
|
|
|
14208
14215
|
}
|
|
14209
14216
|
|
|
14210
14217
|
// src/services/service-provider-invite.service.ts
|
|
14211
|
-
var
|
|
14218
|
+
var import_node_server_utils34 = require("@7365admin1/node-server-utils");
|
|
14212
14219
|
var import_mongodb30 = require("mongodb");
|
|
14213
14220
|
|
|
14214
14221
|
// src/services/notification.service.ts
|
|
@@ -15427,10 +15434,173 @@ var NotificationService = class {
|
|
|
15427
15434
|
}
|
|
15428
15435
|
};
|
|
15429
15436
|
|
|
15437
|
+
// src/utils/console-authz.util.ts
|
|
15438
|
+
var import_node_server_utils33 = require("@7365admin1/node-server-utils");
|
|
15439
|
+
|
|
15440
|
+
// src/utils/console-permission.util.ts
|
|
15441
|
+
var CONSOLE_PERMISSIONS = Object.freeze({
|
|
15442
|
+
organizations: Object.freeze([
|
|
15443
|
+
"see-all-organizations",
|
|
15444
|
+
"see-organization-details"
|
|
15445
|
+
]),
|
|
15446
|
+
"promo-codes": Object.freeze([
|
|
15447
|
+
"create-promo-code",
|
|
15448
|
+
"see-promo-code-details",
|
|
15449
|
+
"edit-promo-code-details",
|
|
15450
|
+
"change-promo-code-status",
|
|
15451
|
+
"delete-promo-code"
|
|
15452
|
+
]),
|
|
15453
|
+
users: Object.freeze(["see-all-users", "see-user-details"]),
|
|
15454
|
+
invitations: Object.freeze([
|
|
15455
|
+
"create-invitation",
|
|
15456
|
+
"view-invitations",
|
|
15457
|
+
"cancel-invitation"
|
|
15458
|
+
]),
|
|
15459
|
+
subscriptions: Object.freeze([
|
|
15460
|
+
"see-all-subscriptions",
|
|
15461
|
+
"see-subscription-details",
|
|
15462
|
+
"manage-subscription"
|
|
15463
|
+
]),
|
|
15464
|
+
"sp-approvals": Object.freeze([
|
|
15465
|
+
"see-all-sp-approvals",
|
|
15466
|
+
"approve-sp",
|
|
15467
|
+
"reject-sp",
|
|
15468
|
+
"delete-sp-approval"
|
|
15469
|
+
]),
|
|
15470
|
+
"marketplace-vendors": Object.freeze([
|
|
15471
|
+
"see-all-marketplace-vendors",
|
|
15472
|
+
"see-marketplace-vendor-details"
|
|
15473
|
+
]),
|
|
15474
|
+
"platform-terms": Object.freeze([
|
|
15475
|
+
"see-platform-terms",
|
|
15476
|
+
"edit-platform-terms"
|
|
15477
|
+
]),
|
|
15478
|
+
"activity-history": Object.freeze(["see-activity-history"]),
|
|
15479
|
+
members: Object.freeze([
|
|
15480
|
+
"view-members",
|
|
15481
|
+
"assign-member-role",
|
|
15482
|
+
"suspend-member",
|
|
15483
|
+
"activate-member",
|
|
15484
|
+
"delete-member"
|
|
15485
|
+
]),
|
|
15486
|
+
"roles-and-permissions": Object.freeze([
|
|
15487
|
+
"add-role",
|
|
15488
|
+
"see-all-roles",
|
|
15489
|
+
"see-role-details",
|
|
15490
|
+
"update-role",
|
|
15491
|
+
"delete-role"
|
|
15492
|
+
])
|
|
15493
|
+
});
|
|
15494
|
+
var RESOURCE_SPELLINGS = Object.freeze({
|
|
15495
|
+
"roles-and-permissions": Object.freeze([
|
|
15496
|
+
"roles-and-permissions",
|
|
15497
|
+
"roles"
|
|
15498
|
+
]),
|
|
15499
|
+
roles: Object.freeze(["roles", "roles-and-permissions"])
|
|
15500
|
+
});
|
|
15501
|
+
function consoleSpellings(resource, action) {
|
|
15502
|
+
const resources = RESOURCE_SPELLINGS[resource] ?? [resource];
|
|
15503
|
+
return resources.map((name) => `${name}:${action}`);
|
|
15504
|
+
}
|
|
15505
|
+
function consoleRoleAllowsAll(held) {
|
|
15506
|
+
if (!Array.isArray(held) || held.length === 0)
|
|
15507
|
+
return true;
|
|
15508
|
+
return held.includes("*");
|
|
15509
|
+
}
|
|
15510
|
+
function consoleRoleAllows(held, resource, action) {
|
|
15511
|
+
if (consoleRoleAllowsAll(held))
|
|
15512
|
+
return true;
|
|
15513
|
+
const actions = CONSOLE_PERMISSIONS[resource];
|
|
15514
|
+
if (!actions?.length)
|
|
15515
|
+
return false;
|
|
15516
|
+
const wanted = action ? actions.includes(action) ? [action] : [] : actions;
|
|
15517
|
+
return wanted.some(
|
|
15518
|
+
(name) => consoleSpellings(resource, name).some(
|
|
15519
|
+
(spelling) => held.includes(spelling)
|
|
15520
|
+
)
|
|
15521
|
+
);
|
|
15522
|
+
}
|
|
15523
|
+
var CROSS_CLIENT_GRANT = {
|
|
15524
|
+
resource: "organizations"
|
|
15525
|
+
};
|
|
15526
|
+
function staffMayBypass(actor, grant = CROSS_CLIENT_GRANT) {
|
|
15527
|
+
if (!actor.isSuperAdmin)
|
|
15528
|
+
return false;
|
|
15529
|
+
return consoleRoleAllows(actor.staffPermissions, grant.resource, grant.action);
|
|
15530
|
+
}
|
|
15531
|
+
|
|
15532
|
+
// src/utils/console-authz.util.ts
|
|
15533
|
+
function callerId(req) {
|
|
15534
|
+
const user = req.user;
|
|
15535
|
+
return user?.user?.toString?.() || user?._id?.toString?.() || "";
|
|
15536
|
+
}
|
|
15537
|
+
async function requirePlatformStaff(req, grant) {
|
|
15538
|
+
const id = callerId(req);
|
|
15539
|
+
const role = id ? await resolveStaffRole(id) : null;
|
|
15540
|
+
if (!role) {
|
|
15541
|
+
throw new import_node_server_utils33.UnauthorizedError("Not authorized.");
|
|
15542
|
+
}
|
|
15543
|
+
if (grant && !consoleRoleAllows(role.permissions, grant.resource, grant.action)) {
|
|
15544
|
+
throw new import_node_server_utils33.UnauthorizedError("Not authorized.");
|
|
15545
|
+
}
|
|
15546
|
+
return id;
|
|
15547
|
+
}
|
|
15548
|
+
async function requireConsolePermission(req, resource, action) {
|
|
15549
|
+
return await requirePlatformStaff(req, { resource, action });
|
|
15550
|
+
}
|
|
15551
|
+
async function requireSelfOrPlatformStaff(req, userId, grant) {
|
|
15552
|
+
const id = callerId(req);
|
|
15553
|
+
const target = userId?.toString() ?? "";
|
|
15554
|
+
if (id && target && target === id)
|
|
15555
|
+
return id;
|
|
15556
|
+
return await requirePlatformStaff(req, grant);
|
|
15557
|
+
}
|
|
15558
|
+
async function requireOrgAccess(req, orgId) {
|
|
15559
|
+
return await requireOrgReach(req, orgId);
|
|
15560
|
+
}
|
|
15561
|
+
async function requirePlatformOwner(req, grant) {
|
|
15562
|
+
const id = callerId(req);
|
|
15563
|
+
if (!id || !await isPlatformOwner(id)) {
|
|
15564
|
+
throw new import_node_server_utils33.UnauthorizedError("Not authorized.");
|
|
15565
|
+
}
|
|
15566
|
+
if (grant)
|
|
15567
|
+
await requirePlatformStaff(req, grant);
|
|
15568
|
+
return id;
|
|
15569
|
+
}
|
|
15570
|
+
async function requireOrgReach(req, orgId) {
|
|
15571
|
+
const id = callerId(req);
|
|
15572
|
+
if (!id)
|
|
15573
|
+
throw new import_node_server_utils33.UnauthorizedError("Not authorized.");
|
|
15574
|
+
const org = orgId?.toString() ?? "";
|
|
15575
|
+
const actor = await resolveInviteActor(id);
|
|
15576
|
+
if (staffMayBypass(actor))
|
|
15577
|
+
return id;
|
|
15578
|
+
if (org && actor.orgIds.includes(org))
|
|
15579
|
+
return id;
|
|
15580
|
+
if (org && await hasOrgInvitation(id, org))
|
|
15581
|
+
return id;
|
|
15582
|
+
if (org && await hasOrgOwnership(id, org))
|
|
15583
|
+
return id;
|
|
15584
|
+
throw new import_node_server_utils33.UnauthorizedError("Not authorized.");
|
|
15585
|
+
}
|
|
15586
|
+
async function requireInviteReach(req, org, app) {
|
|
15587
|
+
const apps = Array.isArray(app) ? app : [app];
|
|
15588
|
+
if (apps.some((a) => a === PLATFORM_STAFF_MEMBER_TYPE)) {
|
|
15589
|
+
await requirePlatformStaff(req);
|
|
15590
|
+
}
|
|
15591
|
+
if (org)
|
|
15592
|
+
await requireOrgReach(req, org);
|
|
15593
|
+
}
|
|
15594
|
+
async function requireUserFieldWrite(req, userId, field, grant) {
|
|
15595
|
+
if (field === "email")
|
|
15596
|
+
return await requirePlatformStaff(req, grant);
|
|
15597
|
+
return await requireSelfOrPlatformStaff(req, userId, grant);
|
|
15598
|
+
}
|
|
15599
|
+
|
|
15430
15600
|
// src/services/service-provider-invite.service.ts
|
|
15431
15601
|
var INVITE_VALID_HOURS = 72;
|
|
15432
15602
|
function useServiceProviderInviteService() {
|
|
15433
|
-
const mailer = new
|
|
15603
|
+
const mailer = new import_node_server_utils34.useMailer({
|
|
15434
15604
|
host: MAILER_TRANSPORT_HOST,
|
|
15435
15605
|
port: MAILER_TRANSPORT_PORT,
|
|
15436
15606
|
secure: MAILER_TRANSPORT_SECURE,
|
|
@@ -15484,16 +15654,16 @@ function useServiceProviderInviteService() {
|
|
|
15484
15654
|
});
|
|
15485
15655
|
}
|
|
15486
15656
|
} catch (error) {
|
|
15487
|
-
|
|
15657
|
+
import_node_server_utils34.logger.log({
|
|
15488
15658
|
level: "error",
|
|
15489
15659
|
message: `Invitation in-app notification failed: ${error?.message}`
|
|
15490
15660
|
});
|
|
15491
15661
|
}
|
|
15492
|
-
const filePath = (0,
|
|
15662
|
+
const filePath = (0, import_node_server_utils34.getDirectory)(
|
|
15493
15663
|
__dirname,
|
|
15494
15664
|
`./public/handlebars/${invite.type}`
|
|
15495
15665
|
);
|
|
15496
|
-
const emailContent = (0,
|
|
15666
|
+
const emailContent = (0, import_node_server_utils34.compileHandlebar)({
|
|
15497
15667
|
context: {
|
|
15498
15668
|
email,
|
|
15499
15669
|
orgName,
|
|
@@ -15513,22 +15683,22 @@ function useServiceProviderInviteService() {
|
|
|
15513
15683
|
async function load(id) {
|
|
15514
15684
|
const invite = await _getById(id);
|
|
15515
15685
|
if (!invite)
|
|
15516
|
-
throw new
|
|
15686
|
+
throw new import_node_server_utils34.NotFoundError("Invitation not found.");
|
|
15517
15687
|
return invite;
|
|
15518
15688
|
}
|
|
15519
15689
|
function assertOwnerOrSuperAdmin(actor, invite) {
|
|
15520
|
-
if (actor
|
|
15690
|
+
if (staffMayBypass(actor))
|
|
15521
15691
|
return;
|
|
15522
15692
|
const org = inviteOrgId(invite);
|
|
15523
15693
|
if (org && actor.orgIds.includes(org))
|
|
15524
15694
|
return;
|
|
15525
|
-
throw new
|
|
15695
|
+
throw new import_node_server_utils34.UnauthorizedError(
|
|
15526
15696
|
"This invitation belongs to another organisation."
|
|
15527
15697
|
);
|
|
15528
15698
|
}
|
|
15529
15699
|
function assertSuperAdmin(actor) {
|
|
15530
|
-
if (!actor
|
|
15531
|
-
throw new
|
|
15700
|
+
if (!staffMayBypass(actor)) {
|
|
15701
|
+
throw new import_node_server_utils34.UnauthorizedError(
|
|
15532
15702
|
"Only a Seven365 administrator can approve or reject invitations."
|
|
15533
15703
|
);
|
|
15534
15704
|
}
|
|
@@ -15536,12 +15706,12 @@ function useServiceProviderInviteService() {
|
|
|
15536
15706
|
function assertAllowed(action, invite) {
|
|
15537
15707
|
const refusal = refuseServiceProviderInviteAction(action, invite.status);
|
|
15538
15708
|
if (refusal)
|
|
15539
|
-
throw new
|
|
15709
|
+
throw new import_node_server_utils34.BadRequestError(refusal);
|
|
15540
15710
|
}
|
|
15541
15711
|
async function actorFor(userId) {
|
|
15542
15712
|
const actor = await resolveInviteActor(userId);
|
|
15543
15713
|
if (!actor.id)
|
|
15544
|
-
throw new
|
|
15714
|
+
throw new import_node_server_utils34.UnauthorizedError("Sign in to continue.");
|
|
15545
15715
|
return actor;
|
|
15546
15716
|
}
|
|
15547
15717
|
async function listApprovals({
|
|
@@ -15577,8 +15747,8 @@ function useServiceProviderInviteService() {
|
|
|
15577
15747
|
const actor = await actorFor(userId);
|
|
15578
15748
|
let scope = actor.orgIds;
|
|
15579
15749
|
if (orgId) {
|
|
15580
|
-
if (!actor
|
|
15581
|
-
throw new
|
|
15750
|
+
if (!staffMayBypass(actor) && !actor.orgIds.includes(orgId)) {
|
|
15751
|
+
throw new import_node_server_utils34.UnauthorizedError(
|
|
15582
15752
|
"You are not a member of that organisation."
|
|
15583
15753
|
);
|
|
15584
15754
|
}
|
|
@@ -15588,7 +15758,7 @@ function useServiceProviderInviteService() {
|
|
|
15588
15758
|
statuses: statuses ?? [],
|
|
15589
15759
|
// A super admin asking for everything passes no scope; everyone else is
|
|
15590
15760
|
// pinned to their own organisations even if they ask for more.
|
|
15591
|
-
orgIds: actor
|
|
15761
|
+
orgIds: staffMayBypass(actor) && !orgId ? void 0 : scope,
|
|
15592
15762
|
search,
|
|
15593
15763
|
page,
|
|
15594
15764
|
limit
|
|
@@ -15647,7 +15817,7 @@ function useServiceProviderInviteService() {
|
|
|
15647
15817
|
assertSuperAdmin(actor);
|
|
15648
15818
|
const trimmed = String(reason ?? "").trim();
|
|
15649
15819
|
if (!trimmed) {
|
|
15650
|
-
throw new
|
|
15820
|
+
throw new import_node_server_utils34.BadRequestError(
|
|
15651
15821
|
"Give a reason for not approving this invitation. The property manager will see it."
|
|
15652
15822
|
);
|
|
15653
15823
|
}
|
|
@@ -15701,7 +15871,7 @@ function useServiceProviderInviteService() {
|
|
|
15701
15871
|
set: { expireAt }
|
|
15702
15872
|
});
|
|
15703
15873
|
if (!updated) {
|
|
15704
|
-
throw new
|
|
15874
|
+
throw new import_node_server_utils34.BadRequestError(
|
|
15705
15875
|
refuseServiceProviderInviteAction("resend", invite.status) ?? "This invitation cannot be sent again."
|
|
15706
15876
|
);
|
|
15707
15877
|
}
|
|
@@ -15737,7 +15907,7 @@ function useServiceProviderInviteService() {
|
|
|
15737
15907
|
);
|
|
15738
15908
|
const invitedUserId = user?._id?.toString();
|
|
15739
15909
|
if (!invitedUserId || invitedUserId !== userId) {
|
|
15740
|
-
throw new
|
|
15910
|
+
throw new import_node_server_utils34.UnauthorizedError("This invitation was sent to someone else.");
|
|
15741
15911
|
}
|
|
15742
15912
|
}
|
|
15743
15913
|
async function decline({ id, userId }) {
|
|
@@ -15767,7 +15937,7 @@ function useServiceProviderInviteService() {
|
|
|
15767
15937
|
const invite = await load(id);
|
|
15768
15938
|
await assertInvitedParty(actor.id, invite);
|
|
15769
15939
|
if (invite.status === "awaiting-approval" /* AWAITING_APPROVAL */) {
|
|
15770
|
-
throw new
|
|
15940
|
+
throw new import_node_server_utils34.NotFoundError("Invitation not found.");
|
|
15771
15941
|
}
|
|
15772
15942
|
const { orgName, siteName } = await inviteContext(invite);
|
|
15773
15943
|
return {
|
|
@@ -15805,7 +15975,7 @@ function useVerificationService() {
|
|
|
15805
15975
|
from: MAILER_FROM_EMAIL,
|
|
15806
15976
|
password: MAILER_PASSWORD
|
|
15807
15977
|
};
|
|
15808
|
-
const mailer = new
|
|
15978
|
+
const mailer = new import_node_server_utils35.useMailer(MailerConfig);
|
|
15809
15979
|
const {
|
|
15810
15980
|
add,
|
|
15811
15981
|
getById: _getById,
|
|
@@ -15843,11 +16013,11 @@ function useVerificationService() {
|
|
|
15843
16013
|
value.type = type;
|
|
15844
16014
|
const res = await add(value);
|
|
15845
16015
|
const dir = __dirname;
|
|
15846
|
-
const filePath = (0,
|
|
16016
|
+
const filePath = (0, import_node_server_utils35.getDirectory)(dir, `./public/handlebars/${type}`);
|
|
15847
16017
|
const isMember = type === "member-invite";
|
|
15848
16018
|
const subject = isMember ? "Member Invite" : "User Invite";
|
|
15849
16019
|
const link = `${APP_MAIN}/verify/${isMember ? "membership" : "invitation"}/${res}`;
|
|
15850
|
-
const emailContent = (0,
|
|
16020
|
+
const emailContent = (0, import_node_server_utils35.compileHandlebar)({
|
|
15851
16021
|
context: {
|
|
15852
16022
|
email: userName,
|
|
15853
16023
|
validity: VERIFICATION_USER_INVITE_DURATION,
|
|
@@ -15861,7 +16031,7 @@ function useVerificationService() {
|
|
|
15861
16031
|
html: emailContent,
|
|
15862
16032
|
sender: "iService365"
|
|
15863
16033
|
}).catch((error) => {
|
|
15864
|
-
|
|
16034
|
+
import_node_server_utils35.logger.log({
|
|
15865
16035
|
level: "error",
|
|
15866
16036
|
message: `Error sending user ${type} email: ${error}`
|
|
15867
16037
|
});
|
|
@@ -15905,7 +16075,7 @@ function useVerificationService() {
|
|
|
15905
16075
|
const createdId = await add(value);
|
|
15906
16076
|
verificationIds.push(createdId.toString());
|
|
15907
16077
|
const link = `${APP_MAIN}/verify/invitation/${createdId}`;
|
|
15908
|
-
const emailContent = (0,
|
|
16078
|
+
const emailContent = (0, import_node_server_utils35.compileHandlebar)({
|
|
15909
16079
|
context: {
|
|
15910
16080
|
email,
|
|
15911
16081
|
validity: VERIFICATION_USER_INVITE_DURATION,
|
|
@@ -15918,7 +16088,7 @@ function useVerificationService() {
|
|
|
15918
16088
|
hasPestControl: app === "pest_control_services",
|
|
15919
16089
|
hasPoolMaintenance: app === "pool_maintenance_services"
|
|
15920
16090
|
},
|
|
15921
|
-
filePath: (0,
|
|
16091
|
+
filePath: (0, import_node_server_utils35.getDirectory)(__dirname, "./public/handlebars/user-invite")
|
|
15922
16092
|
});
|
|
15923
16093
|
await mailer.sendMail({
|
|
15924
16094
|
to: email,
|
|
@@ -15947,7 +16117,7 @@ function useVerificationService() {
|
|
|
15947
16117
|
});
|
|
15948
16118
|
if (existing) {
|
|
15949
16119
|
if (existing.status === "complete") {
|
|
15950
|
-
throw new
|
|
16120
|
+
throw new import_node_server_utils35.BadRequestError(
|
|
15951
16121
|
`User already completed member invite for app: ${metadata.app}`
|
|
15952
16122
|
);
|
|
15953
16123
|
}
|
|
@@ -15962,13 +16132,13 @@ function useVerificationService() {
|
|
|
15962
16132
|
};
|
|
15963
16133
|
const res = await add(value);
|
|
15964
16134
|
const link = `${APP_MAIN}/verify/membership/${res}`;
|
|
15965
|
-
const emailContent = (0,
|
|
16135
|
+
const emailContent = (0, import_node_server_utils35.compileHandlebar)({
|
|
15966
16136
|
context: {
|
|
15967
16137
|
email,
|
|
15968
16138
|
validity: VERIFICATION_USER_INVITE_DURATION,
|
|
15969
16139
|
link
|
|
15970
16140
|
},
|
|
15971
|
-
filePath: (0,
|
|
16141
|
+
filePath: (0, import_node_server_utils35.getDirectory)(__dirname, "./public/handlebars/member-invite")
|
|
15972
16142
|
});
|
|
15973
16143
|
await mailer.sendMail({
|
|
15974
16144
|
to: email,
|
|
@@ -16014,8 +16184,8 @@ function useVerificationService() {
|
|
|
16014
16184
|
});
|
|
16015
16185
|
if (error) {
|
|
16016
16186
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
16017
|
-
|
|
16018
|
-
throw new
|
|
16187
|
+
import_node_server_utils35.logger.log({ level: "error", message: messages });
|
|
16188
|
+
throw new import_node_server_utils35.BadRequestError(`Invalid input: ${error.message}`);
|
|
16019
16189
|
}
|
|
16020
16190
|
let subject = "Service Provider Invite" /* _SERVICE_PROVIDER_INVITE */;
|
|
16021
16191
|
let type = "service-provider-invite" /* SERVICE_PROVIDER_INVITE */;
|
|
@@ -16038,10 +16208,10 @@ function useVerificationService() {
|
|
|
16038
16208
|
const org = await getOrgById(orgId);
|
|
16039
16209
|
const actor = await resolveInviteActor(invitedBy);
|
|
16040
16210
|
if (!actor.id) {
|
|
16041
|
-
throw new
|
|
16211
|
+
throw new import_node_server_utils35.UnauthorizedError("Sign in to continue.");
|
|
16042
16212
|
}
|
|
16043
|
-
if (!actor
|
|
16044
|
-
throw new
|
|
16213
|
+
if (!staffMayBypass(actor) && !actor.orgIds.includes(orgId)) {
|
|
16214
|
+
throw new import_node_server_utils35.UnauthorizedError(
|
|
16045
16215
|
"You can only invite service providers to your own organisation's sites."
|
|
16046
16216
|
);
|
|
16047
16217
|
}
|
|
@@ -16060,7 +16230,7 @@ function useVerificationService() {
|
|
|
16060
16230
|
inviterIsPropertyManagement: actor.propertyManagementOrgIds.includes(orgId)
|
|
16061
16231
|
});
|
|
16062
16232
|
if (!decision.ok) {
|
|
16063
|
-
throw new
|
|
16233
|
+
throw new import_node_server_utils35.BadRequestError(decision.reason);
|
|
16064
16234
|
}
|
|
16065
16235
|
value.type = decision.type;
|
|
16066
16236
|
subject = decision.subject;
|
|
@@ -16121,8 +16291,8 @@ function useVerificationService() {
|
|
|
16121
16291
|
});
|
|
16122
16292
|
if (error) {
|
|
16123
16293
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
16124
|
-
|
|
16125
|
-
throw new
|
|
16294
|
+
import_node_server_utils35.logger.log({ level: "error", message: messages });
|
|
16295
|
+
throw new import_node_server_utils35.BadRequestError(`Invalid input: ${error.message}`);
|
|
16126
16296
|
}
|
|
16127
16297
|
const subject = "Service Provider Invite" /* _SERVICE_PROVIDER_INVITE */;
|
|
16128
16298
|
const type = "service-provider-invite" /* SERVICE_PROVIDER_INVITE */;
|
|
@@ -16142,12 +16312,12 @@ function useVerificationService() {
|
|
|
16142
16312
|
};
|
|
16143
16313
|
try {
|
|
16144
16314
|
const id = await _add(value);
|
|
16145
|
-
const filePath = (0,
|
|
16315
|
+
const filePath = (0, import_node_server_utils35.getDirectory)(
|
|
16146
16316
|
__dirname,
|
|
16147
16317
|
`./public/handlebars/${value.type}`
|
|
16148
16318
|
);
|
|
16149
16319
|
const link = `${APP_MAIN}/verify/${value.type}/${id}`;
|
|
16150
|
-
const emailContent = (0,
|
|
16320
|
+
const emailContent = (0, import_node_server_utils35.compileHandlebar)({
|
|
16151
16321
|
context: {
|
|
16152
16322
|
email,
|
|
16153
16323
|
app,
|
|
@@ -16180,12 +16350,12 @@ function useVerificationService() {
|
|
|
16180
16350
|
try {
|
|
16181
16351
|
const user = await getUserByEmail(email);
|
|
16182
16352
|
if (!user) {
|
|
16183
|
-
throw new
|
|
16353
|
+
throw new import_node_server_utils35.NotFoundError("Email not found");
|
|
16184
16354
|
}
|
|
16185
16355
|
const res = await add(value);
|
|
16186
16356
|
const dir = __dirname;
|
|
16187
|
-
const filePath = (0,
|
|
16188
|
-
const emailContent = (0,
|
|
16357
|
+
const filePath = (0, import_node_server_utils35.getDirectory)(dir, "./public/handlebars/forget-password");
|
|
16358
|
+
const emailContent = (0, import_node_server_utils35.compileHandlebar)({
|
|
16189
16359
|
context: {
|
|
16190
16360
|
userName: user?.name,
|
|
16191
16361
|
validity: VERIFICATION_FORGET_PASSWORD_DURATION,
|
|
@@ -16199,21 +16369,21 @@ function useVerificationService() {
|
|
|
16199
16369
|
sender: "iService365",
|
|
16200
16370
|
html: emailContent
|
|
16201
16371
|
}).catch((error) => {
|
|
16202
|
-
|
|
16372
|
+
import_node_server_utils35.logger.log({
|
|
16203
16373
|
level: "error",
|
|
16204
16374
|
message: `Error sending forget password email: ${error}`
|
|
16205
16375
|
});
|
|
16206
16376
|
});
|
|
16207
16377
|
return "Successfully created a link to reset password. Please check your email.";
|
|
16208
16378
|
} catch (error) {
|
|
16209
|
-
throw new
|
|
16379
|
+
throw new import_node_server_utils35.InternalServerError("Failed to create forget password link.");
|
|
16210
16380
|
}
|
|
16211
16381
|
}
|
|
16212
16382
|
async function getById(id) {
|
|
16213
16383
|
try {
|
|
16214
16384
|
const _id = await _getById(id);
|
|
16215
16385
|
if (!_id) {
|
|
16216
|
-
throw new
|
|
16386
|
+
throw new import_node_server_utils35.NotFoundError("Verification not found.");
|
|
16217
16387
|
}
|
|
16218
16388
|
return _id;
|
|
16219
16389
|
} catch (error) {
|
|
@@ -16222,48 +16392,48 @@ function useVerificationService() {
|
|
|
16222
16392
|
}
|
|
16223
16393
|
function errorByType(type, status) {
|
|
16224
16394
|
if ((type === "user-invite" || type === "member-invite" || type === "service-provider-invite" || type === "service-provider-create-org") && status === "expired") {
|
|
16225
|
-
throw new
|
|
16395
|
+
throw new import_node_server_utils35.BadRequestError(
|
|
16226
16396
|
"Invitation has already expired, please contact admin to resend the invitation."
|
|
16227
16397
|
);
|
|
16228
16398
|
}
|
|
16229
16399
|
if (type === "user-sign-up" && status === "expired") {
|
|
16230
|
-
throw new
|
|
16400
|
+
throw new import_node_server_utils35.BadRequestError(
|
|
16231
16401
|
"Sign up verification has expired, please sign up again to get a new verification link."
|
|
16232
16402
|
);
|
|
16233
16403
|
}
|
|
16234
16404
|
if ((type === "user-invite" || type === "member-invite" || type === "service-provider-invite" || type === "service-provider-create-org") && status === "complete") {
|
|
16235
|
-
throw new
|
|
16405
|
+
throw new import_node_server_utils35.BadRequestError(
|
|
16236
16406
|
"User already registered, please login to continue."
|
|
16237
16407
|
);
|
|
16238
16408
|
}
|
|
16239
16409
|
if (type === "forget-password" && status === "complete") {
|
|
16240
|
-
throw new
|
|
16410
|
+
throw new import_node_server_utils35.BadRequestError(
|
|
16241
16411
|
"Forget password verification has already been used, please request a new one."
|
|
16242
16412
|
);
|
|
16243
16413
|
}
|
|
16244
16414
|
if (type === "forget-password" && status === "expired") {
|
|
16245
|
-
throw new
|
|
16415
|
+
throw new import_node_server_utils35.BadRequestError(
|
|
16246
16416
|
"Forget password verification has expired, please request a new one."
|
|
16247
16417
|
);
|
|
16248
16418
|
}
|
|
16249
|
-
throw new
|
|
16419
|
+
throw new import_node_server_utils35.BadRequestError("Invalid verification.");
|
|
16250
16420
|
}
|
|
16251
16421
|
async function verify(id) {
|
|
16252
|
-
const session =
|
|
16422
|
+
const session = import_node_server_utils35.useAtlas.getClient()?.startSession();
|
|
16253
16423
|
session?.startTransaction();
|
|
16254
16424
|
try {
|
|
16255
16425
|
const _id = await _getById(id);
|
|
16256
16426
|
if (!_id) {
|
|
16257
|
-
throw new
|
|
16427
|
+
throw new import_node_server_utils35.NotFoundError("Verification not found.");
|
|
16258
16428
|
}
|
|
16259
16429
|
if (_id.status === "expired") {
|
|
16260
16430
|
errorByType(_id.type, "expired");
|
|
16261
16431
|
}
|
|
16262
16432
|
if (_id.status === "cancelled") {
|
|
16263
|
-
throw new
|
|
16433
|
+
throw new import_node_server_utils35.BadRequestError("Verification already cancelled.");
|
|
16264
16434
|
}
|
|
16265
16435
|
if (_id.status === "complete") {
|
|
16266
|
-
throw new
|
|
16436
|
+
throw new import_node_server_utils35.BadRequestError("Verification already completed.");
|
|
16267
16437
|
}
|
|
16268
16438
|
const expiration = new Date(_id.expireAt).getTime();
|
|
16269
16439
|
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
@@ -16274,7 +16444,7 @@ function useVerificationService() {
|
|
|
16274
16444
|
return _id;
|
|
16275
16445
|
} catch (error) {
|
|
16276
16446
|
await session?.abortTransaction();
|
|
16277
|
-
|
|
16447
|
+
import_node_server_utils35.logger.log({
|
|
16278
16448
|
level: "info",
|
|
16279
16449
|
message: `Error verifying user invitation: ${error}`
|
|
16280
16450
|
});
|
|
@@ -16287,7 +16457,7 @@ function useVerificationService() {
|
|
|
16287
16457
|
try {
|
|
16288
16458
|
await updateStatusById(id, "cancelled");
|
|
16289
16459
|
} catch (error) {
|
|
16290
|
-
throw new
|
|
16460
|
+
throw new import_node_server_utils35.InternalServerError(
|
|
16291
16461
|
`Error cancelling user invitation: ${error}`
|
|
16292
16462
|
);
|
|
16293
16463
|
}
|
|
@@ -16307,7 +16477,7 @@ function useVerificationService() {
|
|
|
16307
16477
|
try {
|
|
16308
16478
|
const user = await getUserByEmail(email);
|
|
16309
16479
|
if (user) {
|
|
16310
|
-
throw new
|
|
16480
|
+
throw new import_node_server_utils35.BadRequestError(
|
|
16311
16481
|
`Email ${email} is already registered, please login to continue.`
|
|
16312
16482
|
);
|
|
16313
16483
|
}
|
|
@@ -16321,8 +16491,8 @@ function useVerificationService() {
|
|
|
16321
16491
|
};
|
|
16322
16492
|
const res = await add(value);
|
|
16323
16493
|
const dir = __dirname;
|
|
16324
|
-
const filePath = (0,
|
|
16325
|
-
const emailContent = (0,
|
|
16494
|
+
const filePath = (0, import_node_server_utils35.getDirectory)(dir, "./public/handlebars/sign-up");
|
|
16495
|
+
const emailContent = (0, import_node_server_utils35.compileHandlebar)({
|
|
16326
16496
|
context: {
|
|
16327
16497
|
email,
|
|
16328
16498
|
validity: "5 minutes",
|
|
@@ -16336,7 +16506,7 @@ function useVerificationService() {
|
|
|
16336
16506
|
html: emailContent,
|
|
16337
16507
|
sender: "iService365"
|
|
16338
16508
|
}).catch((error) => {
|
|
16339
|
-
|
|
16509
|
+
import_node_server_utils35.logger.log({
|
|
16340
16510
|
level: "error",
|
|
16341
16511
|
message: `Error sending user invite email: ${error}`
|
|
16342
16512
|
});
|
|
@@ -16357,7 +16527,7 @@ function useVerificationService() {
|
|
|
16357
16527
|
}
|
|
16358
16528
|
return "Successfully checked for expired invitations.";
|
|
16359
16529
|
} catch (error) {
|
|
16360
|
-
|
|
16530
|
+
import_node_server_utils35.logger.log({
|
|
16361
16531
|
level: "info",
|
|
16362
16532
|
message: `Error checking expired user invitation: ${error}`
|
|
16363
16533
|
});
|
|
@@ -16381,13 +16551,13 @@ function useVerificationService() {
|
|
|
16381
16551
|
}
|
|
16382
16552
|
|
|
16383
16553
|
// src/services/user.service.ts
|
|
16384
|
-
var
|
|
16554
|
+
var import_node_server_utils39 = require("@7365admin1/node-server-utils");
|
|
16385
16555
|
|
|
16386
16556
|
// src/repositories/role.repo.ts
|
|
16387
|
-
var
|
|
16557
|
+
var import_node_server_utils37 = require("@7365admin1/node-server-utils");
|
|
16388
16558
|
|
|
16389
16559
|
// src/models/role.model.ts
|
|
16390
|
-
var
|
|
16560
|
+
var import_node_server_utils36 = require("@7365admin1/node-server-utils");
|
|
16391
16561
|
var import_mongodb32 = require("mongodb");
|
|
16392
16562
|
var PLATFORM_STAFF_ROLE_TYPE = "admin";
|
|
16393
16563
|
var MRole = class {
|
|
@@ -16396,28 +16566,28 @@ var MRole = class {
|
|
|
16396
16566
|
try {
|
|
16397
16567
|
value._id = new import_mongodb32.ObjectId(value._id);
|
|
16398
16568
|
} catch (error) {
|
|
16399
|
-
throw new
|
|
16569
|
+
throw new import_node_server_utils36.BadRequestError("Invalid role ID format.");
|
|
16400
16570
|
}
|
|
16401
16571
|
}
|
|
16402
16572
|
if (typeof value.org === "string" && value.org.length === 24) {
|
|
16403
16573
|
try {
|
|
16404
16574
|
value.org = new import_mongodb32.ObjectId(value.org);
|
|
16405
16575
|
} catch (error) {
|
|
16406
|
-
throw new
|
|
16576
|
+
throw new import_node_server_utils36.BadRequestError("Invalid org ID format.");
|
|
16407
16577
|
}
|
|
16408
16578
|
}
|
|
16409
16579
|
if (typeof value.site === "string" && value.site.length === 24) {
|
|
16410
16580
|
try {
|
|
16411
16581
|
value.site = new import_mongodb32.ObjectId(value.site);
|
|
16412
16582
|
} catch (error) {
|
|
16413
|
-
throw new
|
|
16583
|
+
throw new import_node_server_utils36.BadRequestError("Invalid site ID format.");
|
|
16414
16584
|
}
|
|
16415
16585
|
}
|
|
16416
16586
|
if (value.createdBy) {
|
|
16417
16587
|
try {
|
|
16418
16588
|
value.createdBy = new import_mongodb32.ObjectId(value.createdBy);
|
|
16419
16589
|
} catch (error) {
|
|
16420
|
-
throw new
|
|
16590
|
+
throw new import_node_server_utils36.BadRequestError("Invalid created by ID format.");
|
|
16421
16591
|
}
|
|
16422
16592
|
}
|
|
16423
16593
|
this._id = value._id ?? new import_mongodb32.ObjectId();
|
|
@@ -16440,9 +16610,9 @@ var MRole = class {
|
|
|
16440
16610
|
// src/repositories/role.repo.ts
|
|
16441
16611
|
var import_mongodb33 = require("mongodb");
|
|
16442
16612
|
function useRoleRepo() {
|
|
16443
|
-
const db2 =
|
|
16613
|
+
const db2 = import_node_server_utils37.useAtlas.getDb();
|
|
16444
16614
|
if (!db2) {
|
|
16445
|
-
throw new
|
|
16615
|
+
throw new import_node_server_utils37.InternalServerError("Unable to connect to server.");
|
|
16446
16616
|
}
|
|
16447
16617
|
const namespace_collection = "roles";
|
|
16448
16618
|
const collection = db2.collection(namespace_collection);
|
|
@@ -16454,14 +16624,14 @@ function useRoleRepo() {
|
|
|
16454
16624
|
{ key: { status: 1 } }
|
|
16455
16625
|
]);
|
|
16456
16626
|
} catch (error) {
|
|
16457
|
-
throw new
|
|
16627
|
+
throw new import_node_server_utils37.InternalServerError("Failed to create index on role.");
|
|
16458
16628
|
}
|
|
16459
16629
|
}
|
|
16460
16630
|
async function createTextIndex() {
|
|
16461
16631
|
try {
|
|
16462
16632
|
await collection.createIndex({ name: "text" });
|
|
16463
16633
|
} catch (error) {
|
|
16464
|
-
throw new
|
|
16634
|
+
throw new import_node_server_utils37.InternalServerError("Failed to create text index on role.");
|
|
16465
16635
|
}
|
|
16466
16636
|
}
|
|
16467
16637
|
async function createUniqueIndex() {
|
|
@@ -16471,62 +16641,62 @@ function useRoleRepo() {
|
|
|
16471
16641
|
{ unique: true }
|
|
16472
16642
|
);
|
|
16473
16643
|
} catch (error) {
|
|
16474
|
-
throw new
|
|
16644
|
+
throw new import_node_server_utils37.InternalServerError("Failed to create unique index on role.");
|
|
16475
16645
|
}
|
|
16476
16646
|
}
|
|
16477
|
-
const { delNamespace, setCache, getCache } = (0,
|
|
16478
|
-
const { delNamespace: _delDashboardNameSpace } = (0,
|
|
16647
|
+
const { delNamespace, setCache, getCache } = (0, import_node_server_utils37.useCache)(namespace_collection);
|
|
16648
|
+
const { delNamespace: _delDashboardNameSpace } = (0, import_node_server_utils37.useCache)("dashboard");
|
|
16479
16649
|
async function addRole(value, session) {
|
|
16480
16650
|
value = new MRole(value);
|
|
16481
16651
|
try {
|
|
16482
16652
|
const res = await collection.insertOne(value, { session });
|
|
16483
16653
|
delNamespace().then(() => {
|
|
16484
|
-
|
|
16654
|
+
import_node_server_utils37.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
16485
16655
|
}).catch((err) => {
|
|
16486
|
-
|
|
16656
|
+
import_node_server_utils37.logger.error(
|
|
16487
16657
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
16488
16658
|
err
|
|
16489
16659
|
);
|
|
16490
16660
|
});
|
|
16491
16661
|
return res.insertedId;
|
|
16492
16662
|
} catch (error) {
|
|
16493
|
-
|
|
16663
|
+
import_node_server_utils37.logger.log({ level: "error", message: `${error}` });
|
|
16494
16664
|
const isDuplicated = error.message.includes("duplicate");
|
|
16495
16665
|
if (isDuplicated) {
|
|
16496
|
-
throw new
|
|
16666
|
+
throw new import_node_server_utils37.BadRequestError("Role already exists.");
|
|
16497
16667
|
}
|
|
16498
|
-
throw new
|
|
16668
|
+
throw new import_node_server_utils37.InternalServerError("Failed to create role.");
|
|
16499
16669
|
}
|
|
16500
16670
|
}
|
|
16501
16671
|
async function getRoleByUserId(value) {
|
|
16502
16672
|
try {
|
|
16503
16673
|
value = new import_mongodb33.ObjectId(value);
|
|
16504
16674
|
} catch (error) {
|
|
16505
|
-
throw new
|
|
16675
|
+
throw new import_node_server_utils37.BadRequestError("Invalid user ID format.");
|
|
16506
16676
|
}
|
|
16507
16677
|
try {
|
|
16508
|
-
const cacheKey = (0,
|
|
16678
|
+
const cacheKey = (0, import_node_server_utils37.makeCacheKey)(namespace_collection, { user: value });
|
|
16509
16679
|
const cachedData = await getCache(cacheKey);
|
|
16510
16680
|
if (cachedData) {
|
|
16511
|
-
|
|
16681
|
+
import_node_server_utils37.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
16512
16682
|
return cachedData;
|
|
16513
16683
|
}
|
|
16514
16684
|
const data = await collection.findOne({ user: value });
|
|
16515
16685
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
16516
|
-
|
|
16686
|
+
import_node_server_utils37.logger.info(`Cache set for key: ${cacheKey}`);
|
|
16517
16687
|
}).catch((err) => {
|
|
16518
|
-
|
|
16688
|
+
import_node_server_utils37.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
16519
16689
|
});
|
|
16520
16690
|
return data;
|
|
16521
16691
|
} catch (error) {
|
|
16522
|
-
throw new
|
|
16692
|
+
throw new import_node_server_utils37.InternalServerError("Failed to retrieve role by user ID.");
|
|
16523
16693
|
}
|
|
16524
16694
|
}
|
|
16525
16695
|
async function getOwnerRolesByTypeOrg(type, org) {
|
|
16526
16696
|
try {
|
|
16527
16697
|
org = new import_mongodb33.ObjectId(org);
|
|
16528
16698
|
} catch (error) {
|
|
16529
|
-
throw new
|
|
16699
|
+
throw new import_node_server_utils37.BadRequestError("Invalid organization ID format.");
|
|
16530
16700
|
}
|
|
16531
16701
|
const cacheOptions = {
|
|
16532
16702
|
org: org.toString(),
|
|
@@ -16534,69 +16704,69 @@ function useRoleRepo() {
|
|
|
16534
16704
|
type,
|
|
16535
16705
|
status: "active"
|
|
16536
16706
|
};
|
|
16537
|
-
const cacheKey = (0,
|
|
16707
|
+
const cacheKey = (0, import_node_server_utils37.makeCacheKey)(namespace_collection, cacheOptions);
|
|
16538
16708
|
const cachedData = await getCache(cacheKey);
|
|
16539
16709
|
if (cachedData) {
|
|
16540
|
-
|
|
16710
|
+
import_node_server_utils37.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
16541
16711
|
return cachedData;
|
|
16542
16712
|
}
|
|
16543
16713
|
try {
|
|
16544
16714
|
const data = await collection.find({ org, permissions: "*", type, status: "active" }).toArray();
|
|
16545
16715
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
16546
|
-
|
|
16716
|
+
import_node_server_utils37.logger.info(`Cache set for key: ${cacheKey}`);
|
|
16547
16717
|
}).catch((err) => {
|
|
16548
|
-
|
|
16718
|
+
import_node_server_utils37.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
16549
16719
|
});
|
|
16550
16720
|
return data;
|
|
16551
16721
|
} catch (error) {
|
|
16552
|
-
throw new
|
|
16722
|
+
throw new import_node_server_utils37.InternalServerError("Failed to retrieve role by user ID.");
|
|
16553
16723
|
}
|
|
16554
16724
|
}
|
|
16555
16725
|
async function getRoleById(_id) {
|
|
16556
16726
|
try {
|
|
16557
16727
|
_id = new import_mongodb33.ObjectId(_id);
|
|
16558
16728
|
} catch (error) {
|
|
16559
|
-
throw new
|
|
16729
|
+
throw new import_node_server_utils37.BadRequestError("Invalid role ID format.");
|
|
16560
16730
|
}
|
|
16561
16731
|
try {
|
|
16562
|
-
const cacheKey = (0,
|
|
16732
|
+
const cacheKey = (0, import_node_server_utils37.makeCacheKey)(namespace_collection, { _id });
|
|
16563
16733
|
const cachedData = await getCache(cacheKey);
|
|
16564
16734
|
if (cachedData) {
|
|
16565
|
-
|
|
16735
|
+
import_node_server_utils37.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
16566
16736
|
return cachedData;
|
|
16567
16737
|
}
|
|
16568
16738
|
const data = await collection.findOne({ _id });
|
|
16569
16739
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
16570
|
-
|
|
16740
|
+
import_node_server_utils37.logger.info(`Cache set for key: ${cacheKey}`);
|
|
16571
16741
|
}).catch((err) => {
|
|
16572
|
-
|
|
16742
|
+
import_node_server_utils37.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
16573
16743
|
});
|
|
16574
16744
|
return data;
|
|
16575
16745
|
} catch (error) {
|
|
16576
|
-
throw new
|
|
16746
|
+
throw new import_node_server_utils37.InternalServerError("Failed to retrieve role by ID.");
|
|
16577
16747
|
}
|
|
16578
16748
|
}
|
|
16579
16749
|
async function getRoleByName(name, type) {
|
|
16580
16750
|
if (!name) {
|
|
16581
|
-
throw new
|
|
16751
|
+
throw new import_node_server_utils37.BadRequestError("Role name is required.");
|
|
16582
16752
|
}
|
|
16583
16753
|
const query2 = type ? { name, type } : { name };
|
|
16584
16754
|
try {
|
|
16585
|
-
const cacheKey = (0,
|
|
16755
|
+
const cacheKey = (0, import_node_server_utils37.makeCacheKey)(namespace_collection, query2);
|
|
16586
16756
|
const cachedData = await getCache(cacheKey);
|
|
16587
16757
|
if (cachedData) {
|
|
16588
|
-
|
|
16758
|
+
import_node_server_utils37.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
16589
16759
|
return cachedData;
|
|
16590
16760
|
}
|
|
16591
16761
|
const data = await collection.findOne(query2);
|
|
16592
16762
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
16593
|
-
|
|
16763
|
+
import_node_server_utils37.logger.info(`Cache set for key: ${cacheKey}`);
|
|
16594
16764
|
}).catch((err) => {
|
|
16595
|
-
|
|
16765
|
+
import_node_server_utils37.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
16596
16766
|
});
|
|
16597
16767
|
return data;
|
|
16598
16768
|
} catch (error) {
|
|
16599
|
-
throw new
|
|
16769
|
+
throw new import_node_server_utils37.InternalServerError("Failed to retrieve role by name.");
|
|
16600
16770
|
}
|
|
16601
16771
|
}
|
|
16602
16772
|
async function getRoles({
|
|
@@ -16613,14 +16783,14 @@ function useRoleRepo() {
|
|
|
16613
16783
|
try {
|
|
16614
16784
|
org = new import_mongodb33.ObjectId(org);
|
|
16615
16785
|
} catch (error) {
|
|
16616
|
-
throw new
|
|
16786
|
+
throw new import_node_server_utils37.BadRequestError("Invalid organization ID format.");
|
|
16617
16787
|
}
|
|
16618
16788
|
}
|
|
16619
16789
|
if (site && typeof site === "string" && site.length === 24) {
|
|
16620
16790
|
try {
|
|
16621
16791
|
site = new import_mongodb33.ObjectId(site);
|
|
16622
16792
|
} catch (error) {
|
|
16623
|
-
throw new
|
|
16793
|
+
throw new import_node_server_utils37.BadRequestError("Invalid site ID format.");
|
|
16624
16794
|
}
|
|
16625
16795
|
}
|
|
16626
16796
|
const query2 = { status: "active", org };
|
|
@@ -16639,10 +16809,10 @@ function useRoleRepo() {
|
|
|
16639
16809
|
query2.type = type;
|
|
16640
16810
|
cacheOptions.type = type;
|
|
16641
16811
|
}
|
|
16642
|
-
const cacheKey = (0,
|
|
16812
|
+
const cacheKey = (0, import_node_server_utils37.makeCacheKey)(namespace_collection, cacheOptions);
|
|
16643
16813
|
const cachedData = await getCache(cacheKey);
|
|
16644
16814
|
if (cachedData) {
|
|
16645
|
-
|
|
16815
|
+
import_node_server_utils37.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
16646
16816
|
return cachedData;
|
|
16647
16817
|
}
|
|
16648
16818
|
try {
|
|
@@ -16653,15 +16823,15 @@ function useRoleRepo() {
|
|
|
16653
16823
|
{ $limit: limit }
|
|
16654
16824
|
]).toArray();
|
|
16655
16825
|
const length = await collection.countDocuments(query2);
|
|
16656
|
-
const data = (0,
|
|
16826
|
+
const data = (0, import_node_server_utils37.paginate)(items, page, limit, length);
|
|
16657
16827
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
16658
|
-
|
|
16828
|
+
import_node_server_utils37.logger.info(`Cache set for key: ${cacheKey}`);
|
|
16659
16829
|
}).catch((err) => {
|
|
16660
|
-
|
|
16830
|
+
import_node_server_utils37.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
16661
16831
|
});
|
|
16662
16832
|
return data;
|
|
16663
16833
|
} catch (error) {
|
|
16664
|
-
|
|
16834
|
+
import_node_server_utils37.logger.log({ level: "error", message: `${error}` });
|
|
16665
16835
|
throw error;
|
|
16666
16836
|
}
|
|
16667
16837
|
}
|
|
@@ -16671,12 +16841,12 @@ function useRoleRepo() {
|
|
|
16671
16841
|
org = new import_mongodb33.ObjectId(org);
|
|
16672
16842
|
}
|
|
16673
16843
|
} catch (error) {
|
|
16674
|
-
throw new
|
|
16844
|
+
throw new import_node_server_utils37.BadRequestError("Invalid organization ID format.");
|
|
16675
16845
|
}
|
|
16676
16846
|
try {
|
|
16677
16847
|
return await collection.find({ status: "active", type, org }).sort({ name: 1 }).toArray();
|
|
16678
16848
|
} catch (error) {
|
|
16679
|
-
throw new
|
|
16849
|
+
throw new import_node_server_utils37.InternalServerError("Failed to retrieve replacement roles.");
|
|
16680
16850
|
}
|
|
16681
16851
|
}
|
|
16682
16852
|
async function assertNotSeededOwnerRole(_id) {
|
|
@@ -16685,19 +16855,19 @@ function useRoleRepo() {
|
|
|
16685
16855
|
{ projection: { type: 1, default: 1 } }
|
|
16686
16856
|
);
|
|
16687
16857
|
if (role?.type === PLATFORM_STAFF_ROLE_TYPE && role?.default === true) {
|
|
16688
|
-
throw new
|
|
16858
|
+
throw new import_node_server_utils37.BadRequestError(
|
|
16689
16859
|
"The Seven365 platform owner role cannot be edited or deleted."
|
|
16690
16860
|
);
|
|
16691
16861
|
}
|
|
16692
16862
|
}
|
|
16693
16863
|
async function updateRole(_id, value, session) {
|
|
16694
16864
|
if (!_id) {
|
|
16695
|
-
throw new
|
|
16865
|
+
throw new import_node_server_utils37.BadRequestError("Role ID is required.");
|
|
16696
16866
|
}
|
|
16697
16867
|
try {
|
|
16698
16868
|
_id = new import_mongodb33.ObjectId(_id);
|
|
16699
16869
|
} catch (error) {
|
|
16700
|
-
throw new
|
|
16870
|
+
throw new import_node_server_utils37.BadRequestError("Invalid role ID format.");
|
|
16701
16871
|
}
|
|
16702
16872
|
await assertNotSeededOwnerRole(_id);
|
|
16703
16873
|
if (!value.name) {
|
|
@@ -16710,9 +16880,9 @@ function useRoleRepo() {
|
|
|
16710
16880
|
try {
|
|
16711
16881
|
await collection.updateOne({ _id }, { $set: value }, { session });
|
|
16712
16882
|
delNamespace().then(() => {
|
|
16713
|
-
|
|
16883
|
+
import_node_server_utils37.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
16714
16884
|
}).catch((err) => {
|
|
16715
|
-
|
|
16885
|
+
import_node_server_utils37.logger.error(
|
|
16716
16886
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
16717
16887
|
err
|
|
16718
16888
|
);
|
|
@@ -16721,29 +16891,29 @@ function useRoleRepo() {
|
|
|
16721
16891
|
} catch (error) {
|
|
16722
16892
|
const isDuplicated = error.message.includes("duplicate");
|
|
16723
16893
|
if (isDuplicated) {
|
|
16724
|
-
throw new
|
|
16894
|
+
throw new import_node_server_utils37.BadRequestError("Role name already exists.");
|
|
16725
16895
|
}
|
|
16726
|
-
throw new
|
|
16896
|
+
throw new import_node_server_utils37.InternalServerError("Failed to update role.");
|
|
16727
16897
|
}
|
|
16728
16898
|
} else {
|
|
16729
|
-
throw new
|
|
16899
|
+
throw new import_node_server_utils37.BadRequestError("No fields to update.");
|
|
16730
16900
|
}
|
|
16731
16901
|
}
|
|
16732
16902
|
async function updatePermissionsById(_id, permissions, session) {
|
|
16733
16903
|
if (!_id) {
|
|
16734
|
-
throw new
|
|
16904
|
+
throw new import_node_server_utils37.BadRequestError("Role ID is required.");
|
|
16735
16905
|
}
|
|
16736
16906
|
try {
|
|
16737
16907
|
_id = new import_mongodb33.ObjectId(_id);
|
|
16738
16908
|
} catch (error) {
|
|
16739
|
-
throw new
|
|
16909
|
+
throw new import_node_server_utils37.BadRequestError("Invalid role ID format.");
|
|
16740
16910
|
}
|
|
16741
16911
|
await assertNotSeededOwnerRole(_id);
|
|
16742
16912
|
if (!permissions) {
|
|
16743
|
-
throw new
|
|
16913
|
+
throw new import_node_server_utils37.BadRequestError("Permissions are required.");
|
|
16744
16914
|
}
|
|
16745
16915
|
if (permissions.length === 0) {
|
|
16746
|
-
throw new
|
|
16916
|
+
throw new import_node_server_utils37.BadRequestError("Permissions cannot be empty.");
|
|
16747
16917
|
}
|
|
16748
16918
|
try {
|
|
16749
16919
|
await collection.updateOne(
|
|
@@ -16752,23 +16922,23 @@ function useRoleRepo() {
|
|
|
16752
16922
|
{ session }
|
|
16753
16923
|
);
|
|
16754
16924
|
delNamespace().then(() => {
|
|
16755
|
-
|
|
16925
|
+
import_node_server_utils37.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
16756
16926
|
}).catch((err) => {
|
|
16757
|
-
|
|
16927
|
+
import_node_server_utils37.logger.error(
|
|
16758
16928
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
16759
16929
|
err
|
|
16760
16930
|
);
|
|
16761
16931
|
});
|
|
16762
16932
|
return "Successfully updated role permissions.";
|
|
16763
16933
|
} catch (error) {
|
|
16764
|
-
throw new
|
|
16934
|
+
throw new import_node_server_utils37.InternalServerError("Failed to update role permissions.");
|
|
16765
16935
|
}
|
|
16766
16936
|
}
|
|
16767
16937
|
async function deleteRole(_id, session) {
|
|
16768
16938
|
try {
|
|
16769
16939
|
_id = new import_mongodb33.ObjectId(_id);
|
|
16770
16940
|
} catch (error) {
|
|
16771
|
-
throw new
|
|
16941
|
+
throw new import_node_server_utils37.BadRequestError("Invalid role ID format.");
|
|
16772
16942
|
}
|
|
16773
16943
|
await assertNotSeededOwnerRole(_id);
|
|
16774
16944
|
try {
|
|
@@ -16783,24 +16953,24 @@ function useRoleRepo() {
|
|
|
16783
16953
|
{ session }
|
|
16784
16954
|
);
|
|
16785
16955
|
if (res.modifiedCount === 0) {
|
|
16786
|
-
throw new
|
|
16956
|
+
throw new import_node_server_utils37.InternalServerError("Unable to update role status.");
|
|
16787
16957
|
}
|
|
16788
16958
|
delNamespace().then(() => {
|
|
16789
|
-
|
|
16959
|
+
import_node_server_utils37.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
16790
16960
|
}).catch((err) => {
|
|
16791
|
-
|
|
16961
|
+
import_node_server_utils37.logger.error(
|
|
16792
16962
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
16793
16963
|
err
|
|
16794
16964
|
);
|
|
16795
16965
|
});
|
|
16796
16966
|
_delDashboardNameSpace().then(() => {
|
|
16797
|
-
|
|
16967
|
+
import_node_server_utils37.logger.info(`Cache cleared for namespace: dashboard`);
|
|
16798
16968
|
}).catch((err) => {
|
|
16799
|
-
|
|
16969
|
+
import_node_server_utils37.logger.error(`Failed to clear cache for namespace: dashboard`, err);
|
|
16800
16970
|
});
|
|
16801
16971
|
return "Successfully deleted role permission.";
|
|
16802
16972
|
} catch (error) {
|
|
16803
|
-
throw new
|
|
16973
|
+
throw new import_node_server_utils37.InternalServerError("Failed to delete role.");
|
|
16804
16974
|
}
|
|
16805
16975
|
}
|
|
16806
16976
|
return {
|
|
@@ -16821,7 +16991,7 @@ function useRoleRepo() {
|
|
|
16821
16991
|
}
|
|
16822
16992
|
|
|
16823
16993
|
// src/repositories/file.repo.ts
|
|
16824
|
-
var
|
|
16994
|
+
var import_node_server_utils38 = require("@7365admin1/node-server-utils");
|
|
16825
16995
|
|
|
16826
16996
|
// src/models/file.model.ts
|
|
16827
16997
|
var MFile = class {
|
|
@@ -16840,13 +17010,13 @@ var MFile = class {
|
|
|
16840
17010
|
// src/repositories/file.repo.ts
|
|
16841
17011
|
var import_mongodb34 = require("mongodb");
|
|
16842
17012
|
function useFileRepo() {
|
|
16843
|
-
const db2 =
|
|
17013
|
+
const db2 = import_node_server_utils38.useAtlas.getDb();
|
|
16844
17014
|
if (!db2) {
|
|
16845
|
-
throw new
|
|
17015
|
+
throw new import_node_server_utils38.InternalServerError("Unable to connect to server.");
|
|
16846
17016
|
}
|
|
16847
17017
|
const namespace_collection = "files";
|
|
16848
17018
|
const collection = db2.collection(namespace_collection);
|
|
16849
|
-
const { delNamespace, getCache, setCache } = (0,
|
|
17019
|
+
const { delNamespace, getCache, setCache } = (0, import_node_server_utils38.useCache)(namespace_collection);
|
|
16850
17020
|
async function createIndex() {
|
|
16851
17021
|
try {
|
|
16852
17022
|
await collection.createIndexes([
|
|
@@ -16854,7 +17024,7 @@ function useFileRepo() {
|
|
|
16854
17024
|
{ key: { status: 1 } }
|
|
16855
17025
|
]);
|
|
16856
17026
|
} catch (error) {
|
|
16857
|
-
throw new
|
|
17027
|
+
throw new import_node_server_utils38.InternalServerError("Failed to create index on feedback.");
|
|
16858
17028
|
}
|
|
16859
17029
|
}
|
|
16860
17030
|
async function createFile(value, session) {
|
|
@@ -16862,65 +17032,65 @@ function useFileRepo() {
|
|
|
16862
17032
|
value = new MFile(value);
|
|
16863
17033
|
const res = await collection.insertOne(value, { session });
|
|
16864
17034
|
delNamespace().then(() => {
|
|
16865
|
-
|
|
17035
|
+
import_node_server_utils38.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
16866
17036
|
}).catch((err) => {
|
|
16867
|
-
|
|
17037
|
+
import_node_server_utils38.logger.error(
|
|
16868
17038
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
16869
17039
|
err
|
|
16870
17040
|
);
|
|
16871
17041
|
});
|
|
16872
17042
|
return res.insertedId.toString();
|
|
16873
17043
|
} catch (error) {
|
|
16874
|
-
throw new
|
|
17044
|
+
throw new import_node_server_utils38.InternalServerError("Failed to create file.");
|
|
16875
17045
|
}
|
|
16876
17046
|
}
|
|
16877
17047
|
async function deleteFileById(_id, session) {
|
|
16878
17048
|
try {
|
|
16879
17049
|
_id = new import_mongodb34.ObjectId(_id);
|
|
16880
17050
|
} catch (error) {
|
|
16881
|
-
throw new
|
|
17051
|
+
throw new import_node_server_utils38.BadRequestError("Invalid file ID format.");
|
|
16882
17052
|
}
|
|
16883
17053
|
try {
|
|
16884
17054
|
await collection.deleteOne({ _id }, { session });
|
|
16885
17055
|
delNamespace().then(() => {
|
|
16886
|
-
|
|
17056
|
+
import_node_server_utils38.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
16887
17057
|
}).catch((err) => {
|
|
16888
|
-
|
|
17058
|
+
import_node_server_utils38.logger.error(
|
|
16889
17059
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
16890
17060
|
err
|
|
16891
17061
|
);
|
|
16892
17062
|
});
|
|
16893
17063
|
return "File deleted successfully.";
|
|
16894
17064
|
} catch (error) {
|
|
16895
|
-
throw new
|
|
17065
|
+
throw new import_node_server_utils38.InternalServerError("Failed to delete file.");
|
|
16896
17066
|
}
|
|
16897
17067
|
}
|
|
16898
17068
|
async function getAllDraftedFiles() {
|
|
16899
|
-
const cacheKey = (0,
|
|
17069
|
+
const cacheKey = (0, import_node_server_utils38.makeCacheKey)(namespace_collection, {
|
|
16900
17070
|
status: ["draft", null]
|
|
16901
17071
|
});
|
|
16902
17072
|
const cachedData = await getCache(cacheKey);
|
|
16903
17073
|
if (cachedData) {
|
|
16904
|
-
|
|
17074
|
+
import_node_server_utils38.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
16905
17075
|
return cachedData;
|
|
16906
17076
|
}
|
|
16907
17077
|
try {
|
|
16908
17078
|
const data = await collection.find({ $and: [{ status: "draft" }, { status: null }] }).toArray();
|
|
16909
17079
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
16910
|
-
|
|
17080
|
+
import_node_server_utils38.logger.info(`Cache set for key: ${cacheKey}`);
|
|
16911
17081
|
}).catch((err) => {
|
|
16912
|
-
|
|
17082
|
+
import_node_server_utils38.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
16913
17083
|
});
|
|
16914
17084
|
return data;
|
|
16915
17085
|
} catch (error) {
|
|
16916
|
-
throw new
|
|
17086
|
+
throw new import_node_server_utils38.InternalServerError("Failed to get drafted files.");
|
|
16917
17087
|
}
|
|
16918
17088
|
}
|
|
16919
17089
|
async function updateStatusById(_id, value, session) {
|
|
16920
17090
|
try {
|
|
16921
17091
|
_id = new import_mongodb34.ObjectId(_id);
|
|
16922
17092
|
} catch (error) {
|
|
16923
|
-
throw new
|
|
17093
|
+
throw new import_node_server_utils38.BadRequestError("Invalid file ID format.");
|
|
16924
17094
|
}
|
|
16925
17095
|
try {
|
|
16926
17096
|
const res = await collection.updateOne(
|
|
@@ -16929,29 +17099,29 @@ function useFileRepo() {
|
|
|
16929
17099
|
{ session }
|
|
16930
17100
|
);
|
|
16931
17101
|
delNamespace().then(() => {
|
|
16932
|
-
|
|
17102
|
+
import_node_server_utils38.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
16933
17103
|
}).catch((err) => {
|
|
16934
|
-
|
|
17104
|
+
import_node_server_utils38.logger.error(
|
|
16935
17105
|
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
16936
17106
|
err
|
|
16937
17107
|
);
|
|
16938
17108
|
});
|
|
16939
17109
|
return res;
|
|
16940
17110
|
} catch (error) {
|
|
16941
|
-
throw new
|
|
17111
|
+
throw new import_node_server_utils38.InternalServerError("Failed to update file.");
|
|
16942
17112
|
}
|
|
16943
17113
|
}
|
|
16944
17114
|
async function getFileById(_id) {
|
|
16945
17115
|
try {
|
|
16946
17116
|
_id = new import_mongodb34.ObjectId(_id);
|
|
16947
17117
|
} catch (error) {
|
|
16948
|
-
throw new
|
|
17118
|
+
throw new import_node_server_utils38.BadRequestError("Invalid ID.");
|
|
16949
17119
|
}
|
|
16950
|
-
const cacheKey = (0,
|
|
17120
|
+
const cacheKey = (0, import_node_server_utils38.makeCacheKey)(namespace_collection, { _id: String(_id) });
|
|
16951
17121
|
try {
|
|
16952
17122
|
const cached = await getCache(cacheKey);
|
|
16953
17123
|
if (cached) {
|
|
16954
|
-
|
|
17124
|
+
import_node_server_utils38.logger.log({
|
|
16955
17125
|
level: "info",
|
|
16956
17126
|
message: `Cache hit for getById file: ${cacheKey}`
|
|
16957
17127
|
});
|
|
@@ -16961,22 +17131,22 @@ function useFileRepo() {
|
|
|
16961
17131
|
_id
|
|
16962
17132
|
});
|
|
16963
17133
|
setCache(cacheKey, result, 300).then(() => {
|
|
16964
|
-
|
|
17134
|
+
import_node_server_utils38.logger.log({
|
|
16965
17135
|
level: "info",
|
|
16966
17136
|
message: `Cache set for file by id: ${cacheKey}`
|
|
16967
17137
|
});
|
|
16968
17138
|
}).catch((err) => {
|
|
16969
|
-
|
|
17139
|
+
import_node_server_utils38.logger.log({
|
|
16970
17140
|
level: "error",
|
|
16971
17141
|
message: `Failed to set cache for file by id: ${err.message}`
|
|
16972
17142
|
});
|
|
16973
17143
|
});
|
|
16974
17144
|
return result;
|
|
16975
17145
|
} catch (error) {
|
|
16976
|
-
if (error instanceof
|
|
17146
|
+
if (error instanceof import_node_server_utils38.AppError) {
|
|
16977
17147
|
throw error;
|
|
16978
17148
|
} else {
|
|
16979
|
-
throw new
|
|
17149
|
+
throw new import_node_server_utils38.InternalServerError("Failed to get file by id.");
|
|
16980
17150
|
}
|
|
16981
17151
|
}
|
|
16982
17152
|
}
|
|
@@ -17017,7 +17187,7 @@ function useUserService() {
|
|
|
17017
17187
|
role = result._id?.toString();
|
|
17018
17188
|
}
|
|
17019
17189
|
} catch (error) {
|
|
17020
|
-
|
|
17190
|
+
import_node_server_utils39.logger.error(error.message);
|
|
17021
17191
|
}
|
|
17022
17192
|
if (!role) {
|
|
17023
17193
|
try {
|
|
@@ -17029,15 +17199,15 @@ function useUserService() {
|
|
|
17029
17199
|
});
|
|
17030
17200
|
role = result.toString();
|
|
17031
17201
|
} catch (error) {
|
|
17032
|
-
|
|
17202
|
+
import_node_server_utils39.logger.error(error.message);
|
|
17033
17203
|
}
|
|
17034
17204
|
if (!role) {
|
|
17035
|
-
|
|
17205
|
+
import_node_server_utils39.logger.error("Failed to create default role.");
|
|
17036
17206
|
}
|
|
17037
17207
|
}
|
|
17038
17208
|
let user = "";
|
|
17039
17209
|
if (!DEFAULT_USER_EMAIL) {
|
|
17040
|
-
|
|
17210
|
+
import_node_server_utils39.logger.error("Default user email is not set.");
|
|
17041
17211
|
}
|
|
17042
17212
|
try {
|
|
17043
17213
|
const result = await getUserByEmail(DEFAULT_USER_EMAIL);
|
|
@@ -17045,11 +17215,11 @@ function useUserService() {
|
|
|
17045
17215
|
user = result._id?.toString();
|
|
17046
17216
|
}
|
|
17047
17217
|
} catch (error) {
|
|
17048
|
-
|
|
17218
|
+
import_node_server_utils39.logger.error(error.message);
|
|
17049
17219
|
}
|
|
17050
17220
|
if (!user) {
|
|
17051
17221
|
try {
|
|
17052
|
-
const password = await (0,
|
|
17222
|
+
const password = await (0, import_node_server_utils39.hashPassword)(DEFAULT_USER_PASSWORD);
|
|
17053
17223
|
const userId = await addUser({
|
|
17054
17224
|
email: DEFAULT_USER_EMAIL,
|
|
17055
17225
|
password,
|
|
@@ -17057,10 +17227,10 @@ function useUserService() {
|
|
|
17057
17227
|
});
|
|
17058
17228
|
user = userId.toString();
|
|
17059
17229
|
} catch (error) {
|
|
17060
|
-
|
|
17230
|
+
import_node_server_utils39.logger.error(error.message);
|
|
17061
17231
|
}
|
|
17062
17232
|
if (!user) {
|
|
17063
|
-
|
|
17233
|
+
import_node_server_utils39.logger.error("Failed to create default user.");
|
|
17064
17234
|
}
|
|
17065
17235
|
}
|
|
17066
17236
|
try {
|
|
@@ -17071,7 +17241,7 @@ function useUserService() {
|
|
|
17071
17241
|
type: "admin"
|
|
17072
17242
|
});
|
|
17073
17243
|
} catch (error) {
|
|
17074
|
-
|
|
17244
|
+
import_node_server_utils39.logger.error(error.message);
|
|
17075
17245
|
}
|
|
17076
17246
|
}
|
|
17077
17247
|
async function createUserBySignUp({
|
|
@@ -17079,28 +17249,28 @@ function useUserService() {
|
|
|
17079
17249
|
name = "",
|
|
17080
17250
|
password = ""
|
|
17081
17251
|
} = {}) {
|
|
17082
|
-
const session =
|
|
17252
|
+
const session = import_node_server_utils39.useAtlas.getClient()?.startSession();
|
|
17083
17253
|
session?.startTransaction();
|
|
17084
17254
|
try {
|
|
17085
17255
|
const signUp = await getVerificationById(id);
|
|
17086
17256
|
if (!signUp) {
|
|
17087
|
-
throw new
|
|
17257
|
+
throw new import_node_server_utils39.BadRequestError("Invalid sign up link.");
|
|
17088
17258
|
}
|
|
17089
17259
|
if (signUp.status === "complete") {
|
|
17090
|
-
throw new
|
|
17260
|
+
throw new import_node_server_utils39.BadRequestError(
|
|
17091
17261
|
"You have already an account created using this link."
|
|
17092
17262
|
);
|
|
17093
17263
|
}
|
|
17094
17264
|
const expired = new Date(signUp.expireAt) < /* @__PURE__ */ new Date();
|
|
17095
17265
|
if (signUp.status === "expired" || expired) {
|
|
17096
|
-
throw new
|
|
17266
|
+
throw new import_node_server_utils39.BadRequestError("Sign up link expired.");
|
|
17097
17267
|
}
|
|
17098
17268
|
const email = signUp.email;
|
|
17099
17269
|
const _user = await getUserByEmail(signUp.email);
|
|
17100
17270
|
if (_user) {
|
|
17101
|
-
throw new
|
|
17271
|
+
throw new import_node_server_utils39.BadRequestError(`User already exists: ${email}.`);
|
|
17102
17272
|
}
|
|
17103
|
-
const hashedPassword = await (0,
|
|
17273
|
+
const hashedPassword = await (0, import_node_server_utils39.hashPassword)(password);
|
|
17104
17274
|
let org = null;
|
|
17105
17275
|
if (signUp.metadata?.org) {
|
|
17106
17276
|
org = await getOrgById(signUp.metadata.org);
|
|
@@ -17149,30 +17319,30 @@ function useUserService() {
|
|
|
17149
17319
|
throw error;
|
|
17150
17320
|
}
|
|
17151
17321
|
if (newPassword !== passwordConfirmation) {
|
|
17152
|
-
throw new
|
|
17322
|
+
throw new import_node_server_utils39.BadRequestError("Passwords do not match.");
|
|
17153
17323
|
}
|
|
17154
17324
|
let hashedPassword;
|
|
17155
|
-
const session =
|
|
17325
|
+
const session = import_node_server_utils39.useAtlas.getClient()?.startSession();
|
|
17156
17326
|
session?.startTransaction();
|
|
17157
17327
|
try {
|
|
17158
|
-
hashedPassword = await (0,
|
|
17328
|
+
hashedPassword = await (0, import_node_server_utils39.hashPassword)(newPassword);
|
|
17159
17329
|
} catch (error) {
|
|
17160
|
-
throw new
|
|
17330
|
+
throw new import_node_server_utils39.InternalServerError(`Error hashing password: ${error}`);
|
|
17161
17331
|
}
|
|
17162
17332
|
try {
|
|
17163
17333
|
const otpDoc = await getVerificationById(id);
|
|
17164
17334
|
if (!otpDoc) {
|
|
17165
|
-
throw new
|
|
17335
|
+
throw new import_node_server_utils39.NotFoundError("You are using an invalid reset link.");
|
|
17166
17336
|
}
|
|
17167
17337
|
if (otpDoc.status === "complete") {
|
|
17168
|
-
throw new
|
|
17338
|
+
throw new import_node_server_utils39.BadRequestError("This link has already been invalidated.");
|
|
17169
17339
|
}
|
|
17170
17340
|
const user = await getUserByEmail(otpDoc.email);
|
|
17171
17341
|
if (!user) {
|
|
17172
|
-
throw new
|
|
17342
|
+
throw new import_node_server_utils39.NotFoundError("User not found.");
|
|
17173
17343
|
}
|
|
17174
17344
|
if (!user._id) {
|
|
17175
|
-
throw new
|
|
17345
|
+
throw new import_node_server_utils39.InternalServerError("Invalid user ID.");
|
|
17176
17346
|
}
|
|
17177
17347
|
await updateStatusById(id, "complete", session);
|
|
17178
17348
|
await _resetPassword(
|
|
@@ -17192,7 +17362,7 @@ function useUserService() {
|
|
|
17192
17362
|
session?.endSession();
|
|
17193
17363
|
}
|
|
17194
17364
|
}
|
|
17195
|
-
const s3 = new
|
|
17365
|
+
const s3 = new import_node_server_utils39.useS3({
|
|
17196
17366
|
accessKeyId: SPACES_ACCESS_KEY,
|
|
17197
17367
|
secretAccessKey: SPACES_SECRET_KEY,
|
|
17198
17368
|
endpoint: SPACES_ENDPOINT,
|
|
@@ -17205,7 +17375,7 @@ function useUserService() {
|
|
|
17205
17375
|
user,
|
|
17206
17376
|
previousProfile
|
|
17207
17377
|
}) {
|
|
17208
|
-
const session =
|
|
17378
|
+
const session = import_node_server_utils39.useAtlas.getClient()?.startSession();
|
|
17209
17379
|
session?.startTransaction();
|
|
17210
17380
|
const _file = {
|
|
17211
17381
|
name: file.originalname,
|
|
@@ -17238,18 +17408,18 @@ function useUserService() {
|
|
|
17238
17408
|
async function updatePasswordById(id, currentPassword, newPassword, passwordConfirmation) {
|
|
17239
17409
|
let hashedPassword;
|
|
17240
17410
|
const user = await getUserById(id);
|
|
17241
|
-
const isPasswordValid = await (0,
|
|
17411
|
+
const isPasswordValid = await (0, import_node_server_utils39.comparePassword)(
|
|
17242
17412
|
currentPassword,
|
|
17243
17413
|
user.password
|
|
17244
17414
|
);
|
|
17245
17415
|
if (!isPasswordValid)
|
|
17246
|
-
throw new
|
|
17416
|
+
throw new import_node_server_utils39.BadRequestError("Invalid current password.");
|
|
17247
17417
|
if (newPassword !== passwordConfirmation)
|
|
17248
|
-
throw new
|
|
17418
|
+
throw new import_node_server_utils39.BadRequestError("Passwords do not match.");
|
|
17249
17419
|
try {
|
|
17250
|
-
hashedPassword = await (0,
|
|
17420
|
+
hashedPassword = await (0, import_node_server_utils39.hashPassword)(newPassword);
|
|
17251
17421
|
if (!hashedPassword)
|
|
17252
|
-
throw new
|
|
17422
|
+
throw new import_node_server_utils39.InternalServerError("Error hashing password.");
|
|
17253
17423
|
return await updatePassword({ _id: id, password: hashedPassword });
|
|
17254
17424
|
} catch (error) {
|
|
17255
17425
|
throw error;
|
|
@@ -17287,8 +17457,8 @@ function useAuthController() {
|
|
|
17287
17457
|
});
|
|
17288
17458
|
if (error) {
|
|
17289
17459
|
const messages = error.details.map((d) => d.message);
|
|
17290
|
-
|
|
17291
|
-
next(new
|
|
17460
|
+
import_node_server_utils40.logger.log({ level: "error", message: messages.join(", ") });
|
|
17461
|
+
next(new import_node_server_utils40.BadRequestError(messages.join(", ")));
|
|
17292
17462
|
return;
|
|
17293
17463
|
}
|
|
17294
17464
|
const session = await _login(value);
|
|
@@ -17300,7 +17470,7 @@ function useAuthController() {
|
|
|
17300
17470
|
res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json(session);
|
|
17301
17471
|
return;
|
|
17302
17472
|
} catch (error) {
|
|
17303
|
-
|
|
17473
|
+
import_node_server_utils40.logger.log({ level: "error", message: error.message });
|
|
17304
17474
|
next(error);
|
|
17305
17475
|
return;
|
|
17306
17476
|
}
|
|
@@ -17311,8 +17481,8 @@ function useAuthController() {
|
|
|
17311
17481
|
});
|
|
17312
17482
|
const { error, value } = validation.validate(req.body);
|
|
17313
17483
|
if (error) {
|
|
17314
|
-
|
|
17315
|
-
next(new
|
|
17484
|
+
import_node_server_utils40.logger.log({ level: "error", message: error.message });
|
|
17485
|
+
next(new import_node_server_utils40.BadRequestError(error.message));
|
|
17316
17486
|
return;
|
|
17317
17487
|
}
|
|
17318
17488
|
try {
|
|
@@ -17320,7 +17490,7 @@ function useAuthController() {
|
|
|
17320
17490
|
res.json(session);
|
|
17321
17491
|
return;
|
|
17322
17492
|
} catch (error2) {
|
|
17323
|
-
|
|
17493
|
+
import_node_server_utils40.logger.log({ level: "error", message: error2.message });
|
|
17324
17494
|
next(error2);
|
|
17325
17495
|
return;
|
|
17326
17496
|
}
|
|
@@ -17328,7 +17498,7 @@ function useAuthController() {
|
|
|
17328
17498
|
async function logout(req, res, next) {
|
|
17329
17499
|
const sid = getSessionIdFromRequest(req);
|
|
17330
17500
|
if (!sid) {
|
|
17331
|
-
next(new
|
|
17501
|
+
next(new import_node_server_utils40.BadRequestError("Session ID is required"));
|
|
17332
17502
|
return;
|
|
17333
17503
|
}
|
|
17334
17504
|
const refreshToken2 = typeof req.body?.refreshToken === "string" ? req.body.refreshToken : void 0;
|
|
@@ -17337,7 +17507,7 @@ function useAuthController() {
|
|
|
17337
17507
|
res.json({ message: "Logged out successfully" });
|
|
17338
17508
|
return;
|
|
17339
17509
|
} catch (error) {
|
|
17340
|
-
|
|
17510
|
+
import_node_server_utils40.logger.log({ level: "error", message: error.message });
|
|
17341
17511
|
next(error);
|
|
17342
17512
|
return;
|
|
17343
17513
|
}
|
|
@@ -17352,8 +17522,8 @@ function useAuthController() {
|
|
|
17352
17522
|
});
|
|
17353
17523
|
if (error) {
|
|
17354
17524
|
const messages = error.details.map((d) => d.message);
|
|
17355
|
-
|
|
17356
|
-
next(new
|
|
17525
|
+
import_node_server_utils40.logger.log({ level: "error", message: messages.join(", ") });
|
|
17526
|
+
next(new import_node_server_utils40.BadRequestError(messages.join(", ")));
|
|
17357
17527
|
return;
|
|
17358
17528
|
}
|
|
17359
17529
|
const email = value.email;
|
|
@@ -17368,7 +17538,7 @@ function useAuthController() {
|
|
|
17368
17538
|
res.json({ message });
|
|
17369
17539
|
return;
|
|
17370
17540
|
} catch (error2) {
|
|
17371
|
-
|
|
17541
|
+
import_node_server_utils40.logger.log({ level: "error", message: error2.message });
|
|
17372
17542
|
next(error2);
|
|
17373
17543
|
return;
|
|
17374
17544
|
}
|
|
@@ -17382,8 +17552,8 @@ function useAuthController() {
|
|
|
17382
17552
|
const payload = { ...req.body };
|
|
17383
17553
|
const { error } = validation.validate(payload);
|
|
17384
17554
|
if (error) {
|
|
17385
|
-
|
|
17386
|
-
next(new
|
|
17555
|
+
import_node_server_utils40.logger.log({ level: "error", message: error.message });
|
|
17556
|
+
next(new import_node_server_utils40.BadRequestError(error.message));
|
|
17387
17557
|
return;
|
|
17388
17558
|
}
|
|
17389
17559
|
const otp = req.body.otp;
|
|
@@ -17398,7 +17568,7 @@ function useAuthController() {
|
|
|
17398
17568
|
res.json({ message });
|
|
17399
17569
|
return;
|
|
17400
17570
|
} catch (error2) {
|
|
17401
|
-
|
|
17571
|
+
import_node_server_utils40.logger.log({ level: "error", message: error2.message });
|
|
17402
17572
|
next(error2);
|
|
17403
17573
|
return;
|
|
17404
17574
|
}
|
|
@@ -17413,8 +17583,8 @@ function useAuthController() {
|
|
|
17413
17583
|
const { error } = validation.validate(payload);
|
|
17414
17584
|
if (error) {
|
|
17415
17585
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
17416
|
-
|
|
17417
|
-
next(new
|
|
17586
|
+
import_node_server_utils40.logger.log({ level: "error", message: messages });
|
|
17587
|
+
next(new import_node_server_utils40.BadRequestError(messages));
|
|
17418
17588
|
return;
|
|
17419
17589
|
}
|
|
17420
17590
|
const password = req.body.password;
|
|
@@ -17423,7 +17593,7 @@ function useAuthController() {
|
|
|
17423
17593
|
res.json({ message });
|
|
17424
17594
|
return;
|
|
17425
17595
|
} catch (error2) {
|
|
17426
|
-
|
|
17596
|
+
import_node_server_utils40.logger.log({ level: "error", message: error2.message });
|
|
17427
17597
|
next(error2);
|
|
17428
17598
|
return;
|
|
17429
17599
|
}
|
|
@@ -17443,10 +17613,10 @@ var import_joi18 = __toESM(require("joi"));
|
|
|
17443
17613
|
var import_node_server_utils43 = require("@7365admin1/node-server-utils");
|
|
17444
17614
|
|
|
17445
17615
|
// src/repositories/person.repo.ts
|
|
17446
|
-
var
|
|
17616
|
+
var import_node_server_utils42 = require("@7365admin1/node-server-utils");
|
|
17447
17617
|
|
|
17448
17618
|
// src/models/person.model.ts
|
|
17449
|
-
var
|
|
17619
|
+
var import_node_server_utils41 = require("@7365admin1/node-server-utils");
|
|
17450
17620
|
var import_joi17 = __toESM(require("joi"));
|
|
17451
17621
|
var import_mongodb35 = require("mongodb");
|
|
17452
17622
|
var PersonTypes = /* @__PURE__ */ ((PersonTypes3) => {
|
|
@@ -17574,7 +17744,7 @@ var schemaUpdatePerson = import_joi17.default.object({
|
|
|
17574
17744
|
function MPerson(value) {
|
|
17575
17745
|
const { error } = schemaPerson.validate(value);
|
|
17576
17746
|
if (error) {
|
|
17577
|
-
throw new
|
|
17747
|
+
throw new import_node_server_utils41.BadRequestError(error.details[0].message);
|
|
17578
17748
|
}
|
|
17579
17749
|
if (value._id && typeof value._id === "string") {
|
|
17580
17750
|
try {
|
|
@@ -17603,7 +17773,7 @@ function MPerson(value) {
|
|
|
17603
17773
|
try {
|
|
17604
17774
|
file.id = new import_mongodb35.ObjectId(file.id);
|
|
17605
17775
|
} catch {
|
|
17606
|
-
throw new
|
|
17776
|
+
throw new import_node_server_utils41.BadRequestError("Invalid file id format");
|
|
17607
17777
|
}
|
|
17608
17778
|
}
|
|
17609
17779
|
return file;
|
|
@@ -17620,28 +17790,28 @@ function MPerson(value) {
|
|
|
17620
17790
|
try {
|
|
17621
17791
|
value.acceptedTerms = new import_mongodb35.ObjectId(value.acceptedTerms);
|
|
17622
17792
|
} catch {
|
|
17623
|
-
throw new
|
|
17793
|
+
throw new import_node_server_utils41.BadRequestError("Invalid accepted terms ID.");
|
|
17624
17794
|
}
|
|
17625
17795
|
}
|
|
17626
17796
|
if (value.block && typeof value.block === "string") {
|
|
17627
17797
|
try {
|
|
17628
17798
|
value.block = new import_mongodb35.ObjectId(value.block);
|
|
17629
17799
|
} catch {
|
|
17630
|
-
throw new
|
|
17800
|
+
throw new import_node_server_utils41.BadRequestError("Invalid block ID.");
|
|
17631
17801
|
}
|
|
17632
17802
|
}
|
|
17633
17803
|
if (value.level && typeof value.level === "string") {
|
|
17634
17804
|
try {
|
|
17635
17805
|
value.level = new import_mongodb35.ObjectId(value.level);
|
|
17636
17806
|
} catch {
|
|
17637
|
-
throw new
|
|
17807
|
+
throw new import_node_server_utils41.BadRequestError("Invalid level ID.");
|
|
17638
17808
|
}
|
|
17639
17809
|
}
|
|
17640
17810
|
if (value.unit && typeof value.unit === "string") {
|
|
17641
17811
|
try {
|
|
17642
17812
|
value.unit = new import_mongodb35.ObjectId(value.unit);
|
|
17643
17813
|
} catch {
|
|
17644
|
-
throw new
|
|
17814
|
+
throw new import_node_server_utils41.BadRequestError("Invalid unit ID.");
|
|
17645
17815
|
}
|
|
17646
17816
|
}
|
|
17647
17817
|
return {
|
|
@@ -17723,13 +17893,13 @@ var makeContainsRegex = (input) => {
|
|
|
17723
17893
|
// src/repositories/person.repo.ts
|
|
17724
17894
|
var site_people_namespace_collection = "site.people";
|
|
17725
17895
|
function usePersonRepo() {
|
|
17726
|
-
const db2 =
|
|
17896
|
+
const db2 = import_node_server_utils42.useAtlas.getDb();
|
|
17727
17897
|
if (!db2) {
|
|
17728
|
-
throw new
|
|
17898
|
+
throw new import_node_server_utils42.InternalServerError("Unable to connect to server.");
|
|
17729
17899
|
}
|
|
17730
17900
|
const collection = db2.collection(site_people_namespace_collection);
|
|
17731
17901
|
const vehiclesCollection = db2.collection("vehicles");
|
|
17732
|
-
const { delNamespace, getCache, setCache } = (0,
|
|
17902
|
+
const { delNamespace, getCache, setCache } = (0, import_node_server_utils42.useCache)(
|
|
17733
17903
|
site_people_namespace_collection
|
|
17734
17904
|
);
|
|
17735
17905
|
async function withoutDeletedPlates(people) {
|
|
@@ -17778,7 +17948,7 @@ function usePersonRepo() {
|
|
|
17778
17948
|
{ key: { unit: 1, status: 1 } }
|
|
17779
17949
|
]);
|
|
17780
17950
|
} catch (error) {
|
|
17781
|
-
throw new
|
|
17951
|
+
throw new import_node_server_utils42.InternalServerError("Failed to create index on site people.");
|
|
17782
17952
|
}
|
|
17783
17953
|
}
|
|
17784
17954
|
async function createTextIndex() {
|
|
@@ -17791,7 +17961,7 @@ function usePersonRepo() {
|
|
|
17791
17961
|
contact: "text"
|
|
17792
17962
|
});
|
|
17793
17963
|
} catch (error) {
|
|
17794
|
-
throw new
|
|
17964
|
+
throw new import_node_server_utils42.InternalServerError(
|
|
17795
17965
|
"Failed to create text index on site people."
|
|
17796
17966
|
);
|
|
17797
17967
|
}
|
|
@@ -17801,11 +17971,11 @@ function usePersonRepo() {
|
|
|
17801
17971
|
value = MPerson(value);
|
|
17802
17972
|
const res = await collection.insertOne(value, { session });
|
|
17803
17973
|
delNamespace().then(() => {
|
|
17804
|
-
|
|
17974
|
+
import_node_server_utils42.logger.info(
|
|
17805
17975
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
17806
17976
|
);
|
|
17807
17977
|
}).catch((err) => {
|
|
17808
|
-
|
|
17978
|
+
import_node_server_utils42.logger.error(
|
|
17809
17979
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
17810
17980
|
err
|
|
17811
17981
|
);
|
|
@@ -17814,7 +17984,7 @@ function usePersonRepo() {
|
|
|
17814
17984
|
} catch (error) {
|
|
17815
17985
|
const isDuplicated = error.message.includes("duplicate");
|
|
17816
17986
|
if (isDuplicated) {
|
|
17817
|
-
throw new
|
|
17987
|
+
throw new import_node_server_utils42.BadRequestError("Person already exists.");
|
|
17818
17988
|
}
|
|
17819
17989
|
throw error;
|
|
17820
17990
|
}
|
|
@@ -17942,7 +18112,7 @@ function usePersonRepo() {
|
|
|
17942
18112
|
collection.aggregate([{ $match: query2 }, { $count: "total" }], { session }).toArray()
|
|
17943
18113
|
]);
|
|
17944
18114
|
const totalCount = countResult[0]?.total || 0;
|
|
17945
|
-
const data = (0,
|
|
18115
|
+
const data = (0, import_node_server_utils42.paginate)(
|
|
17946
18116
|
await withoutDeletedPlates(items),
|
|
17947
18117
|
page,
|
|
17948
18118
|
limit,
|
|
@@ -17957,7 +18127,7 @@ function usePersonRepo() {
|
|
|
17957
18127
|
try {
|
|
17958
18128
|
_id = new import_mongodb37.ObjectId(_id);
|
|
17959
18129
|
} catch (error) {
|
|
17960
|
-
throw new
|
|
18130
|
+
throw new import_node_server_utils42.BadRequestError("Invalid person transaction ID format.");
|
|
17961
18131
|
}
|
|
17962
18132
|
value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
17963
18133
|
if (value.updatedBy) {
|
|
@@ -17973,11 +18143,11 @@ function usePersonRepo() {
|
|
|
17973
18143
|
{ session }
|
|
17974
18144
|
);
|
|
17975
18145
|
delNamespace().then(() => {
|
|
17976
|
-
|
|
18146
|
+
import_node_server_utils42.logger.info(
|
|
17977
18147
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
17978
18148
|
);
|
|
17979
18149
|
}).catch((err) => {
|
|
17980
|
-
|
|
18150
|
+
import_node_server_utils42.logger.error(
|
|
17981
18151
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
17982
18152
|
err
|
|
17983
18153
|
);
|
|
@@ -17991,7 +18161,7 @@ function usePersonRepo() {
|
|
|
17991
18161
|
try {
|
|
17992
18162
|
_id = new import_mongodb37.ObjectId(_id);
|
|
17993
18163
|
} catch (error) {
|
|
17994
|
-
throw new
|
|
18164
|
+
throw new import_node_server_utils42.BadRequestError("Invalid customer ID format.");
|
|
17995
18165
|
}
|
|
17996
18166
|
try {
|
|
17997
18167
|
const updateValue = {
|
|
@@ -18001,14 +18171,14 @@ function usePersonRepo() {
|
|
|
18001
18171
|
};
|
|
18002
18172
|
const res = await collection.updateOne({ _id }, { $set: updateValue });
|
|
18003
18173
|
if (res.modifiedCount === 0) {
|
|
18004
|
-
throw new
|
|
18174
|
+
throw new import_node_server_utils42.InternalServerError("Unable to delete visitor transaction.");
|
|
18005
18175
|
}
|
|
18006
18176
|
delNamespace().then(() => {
|
|
18007
|
-
|
|
18177
|
+
import_node_server_utils42.logger.info(
|
|
18008
18178
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
18009
18179
|
);
|
|
18010
18180
|
}).catch((err) => {
|
|
18011
|
-
|
|
18181
|
+
import_node_server_utils42.logger.error(
|
|
18012
18182
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
18013
18183
|
err
|
|
18014
18184
|
);
|
|
@@ -18022,15 +18192,15 @@ function usePersonRepo() {
|
|
|
18022
18192
|
try {
|
|
18023
18193
|
_id = new import_mongodb37.ObjectId(_id);
|
|
18024
18194
|
} catch (error) {
|
|
18025
|
-
throw new
|
|
18195
|
+
throw new import_node_server_utils42.BadRequestError("Invalid person ID.");
|
|
18026
18196
|
}
|
|
18027
|
-
const cacheKey = (0,
|
|
18197
|
+
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(site_people_namespace_collection, {
|
|
18028
18198
|
_id: String(_id)
|
|
18029
18199
|
});
|
|
18030
18200
|
try {
|
|
18031
18201
|
const cached = await getCache(cacheKey);
|
|
18032
18202
|
if (cached) {
|
|
18033
|
-
|
|
18203
|
+
import_node_server_utils42.logger.log({
|
|
18034
18204
|
level: "info",
|
|
18035
18205
|
message: `Cache hit for getById person: ${cacheKey}`
|
|
18036
18206
|
});
|
|
@@ -18040,34 +18210,34 @@ function usePersonRepo() {
|
|
|
18040
18210
|
_id
|
|
18041
18211
|
});
|
|
18042
18212
|
setCache(cacheKey, result, 300).then(() => {
|
|
18043
|
-
|
|
18213
|
+
import_node_server_utils42.logger.log({
|
|
18044
18214
|
level: "info",
|
|
18045
18215
|
message: `Cache set for person by id: ${cacheKey}`
|
|
18046
18216
|
});
|
|
18047
18217
|
}).catch((err) => {
|
|
18048
|
-
|
|
18218
|
+
import_node_server_utils42.logger.log({
|
|
18049
18219
|
level: "error",
|
|
18050
18220
|
message: `Failed to set cache for person by id: ${err.message}`
|
|
18051
18221
|
});
|
|
18052
18222
|
});
|
|
18053
18223
|
return result;
|
|
18054
18224
|
} catch (error) {
|
|
18055
|
-
if (error instanceof
|
|
18225
|
+
if (error instanceof import_node_server_utils42.AppError) {
|
|
18056
18226
|
throw error;
|
|
18057
18227
|
} else {
|
|
18058
|
-
throw new
|
|
18228
|
+
throw new import_node_server_utils42.InternalServerError("Failed to get person by id.");
|
|
18059
18229
|
}
|
|
18060
18230
|
}
|
|
18061
18231
|
}
|
|
18062
18232
|
async function getPersonByPlateNumber(plateNumber) {
|
|
18063
|
-
const cacheKey = (0,
|
|
18233
|
+
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(site_people_namespace_collection, {
|
|
18064
18234
|
plateNumber,
|
|
18065
18235
|
key: "get-person-plate-number"
|
|
18066
18236
|
});
|
|
18067
18237
|
try {
|
|
18068
18238
|
const cacheData = await getCache(cacheKey);
|
|
18069
18239
|
if (cacheData) {
|
|
18070
|
-
|
|
18240
|
+
import_node_server_utils42.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
18071
18241
|
return await withoutDeletedPlatesOne(cacheData);
|
|
18072
18242
|
}
|
|
18073
18243
|
const data = await collection.findOne(
|
|
@@ -18075,13 +18245,13 @@ function usePersonRepo() {
|
|
|
18075
18245
|
{ sort: { _id: -1 } }
|
|
18076
18246
|
);
|
|
18077
18247
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
18078
|
-
|
|
18248
|
+
import_node_server_utils42.logger.info(`Cache set for key: ${cacheKey}`);
|
|
18079
18249
|
}).catch((err) => {
|
|
18080
|
-
|
|
18250
|
+
import_node_server_utils42.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
18081
18251
|
});
|
|
18082
18252
|
return await withoutDeletedPlatesOne(data);
|
|
18083
18253
|
} catch (error) {
|
|
18084
|
-
throw new
|
|
18254
|
+
throw new import_node_server_utils42.InternalServerError(
|
|
18085
18255
|
"Failed to fetch individual by plate number."
|
|
18086
18256
|
);
|
|
18087
18257
|
}
|
|
@@ -18093,11 +18263,11 @@ function usePersonRepo() {
|
|
|
18093
18263
|
status: "approved"
|
|
18094
18264
|
};
|
|
18095
18265
|
if (excludePersonId) {
|
|
18096
|
-
query2._id = { $ne: (0,
|
|
18266
|
+
query2._id = { $ne: (0, import_node_server_utils42.toObjectId)(excludePersonId) };
|
|
18097
18267
|
}
|
|
18098
18268
|
return await collection.findOne(query2);
|
|
18099
18269
|
} catch (error) {
|
|
18100
|
-
throw new
|
|
18270
|
+
throw new import_node_server_utils42.InternalServerError(
|
|
18101
18271
|
"Failed to fetch approved person by plate number."
|
|
18102
18272
|
);
|
|
18103
18273
|
}
|
|
@@ -18105,47 +18275,47 @@ function usePersonRepo() {
|
|
|
18105
18275
|
async function getByNRIC(value) {
|
|
18106
18276
|
try {
|
|
18107
18277
|
if (!value || value.trim() === "") {
|
|
18108
|
-
|
|
18278
|
+
import_node_server_utils42.logger.warn("getByNRIC called with an empty or invalid NRIC value.");
|
|
18109
18279
|
return null;
|
|
18110
18280
|
}
|
|
18111
|
-
const cacheKey = (0,
|
|
18281
|
+
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(site_people_namespace_collection, {
|
|
18112
18282
|
nric: value
|
|
18113
18283
|
});
|
|
18114
18284
|
const cachedData = await getCache(cacheKey);
|
|
18115
18285
|
if (cachedData) {
|
|
18116
|
-
|
|
18286
|
+
import_node_server_utils42.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
18117
18287
|
return await withoutDeletedPlatesOne(cachedData);
|
|
18118
18288
|
}
|
|
18119
18289
|
const data = await collection.findOne({ nric: value });
|
|
18120
18290
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
18121
|
-
|
|
18291
|
+
import_node_server_utils42.logger.info(`Cache set for key: ${cacheKey}`);
|
|
18122
18292
|
}).catch((err) => {
|
|
18123
|
-
|
|
18293
|
+
import_node_server_utils42.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
18124
18294
|
});
|
|
18125
18295
|
return await withoutDeletedPlatesOne(data);
|
|
18126
18296
|
} catch (error) {
|
|
18127
|
-
throw new
|
|
18297
|
+
throw new import_node_server_utils42.InternalServerError("Failed to retrieve person by NRIC.");
|
|
18128
18298
|
}
|
|
18129
18299
|
}
|
|
18130
18300
|
async function getPersonByPhoneNumber(value) {
|
|
18131
18301
|
try {
|
|
18132
|
-
const cacheKey = (0,
|
|
18302
|
+
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(site_people_namespace_collection, {
|
|
18133
18303
|
contact: value
|
|
18134
18304
|
});
|
|
18135
18305
|
const cachedData = await getCache(cacheKey);
|
|
18136
18306
|
if (cachedData) {
|
|
18137
|
-
|
|
18307
|
+
import_node_server_utils42.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
18138
18308
|
return await withoutDeletedPlatesOne(cachedData);
|
|
18139
18309
|
}
|
|
18140
18310
|
const data = await collection.findOne({ contact: value });
|
|
18141
18311
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
18142
|
-
|
|
18312
|
+
import_node_server_utils42.logger.info(`Cache set for key: ${cacheKey}`);
|
|
18143
18313
|
}).catch((err) => {
|
|
18144
|
-
|
|
18314
|
+
import_node_server_utils42.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
18145
18315
|
});
|
|
18146
18316
|
return await withoutDeletedPlatesOne(data);
|
|
18147
18317
|
} catch (error) {
|
|
18148
|
-
throw new
|
|
18318
|
+
throw new import_node_server_utils42.InternalServerError(
|
|
18149
18319
|
"Failed to retrieve person by Phone Number."
|
|
18150
18320
|
);
|
|
18151
18321
|
}
|
|
@@ -18157,7 +18327,7 @@ function usePersonRepo() {
|
|
|
18157
18327
|
}, session) {
|
|
18158
18328
|
try {
|
|
18159
18329
|
if (!unit || !import_mongodb37.ObjectId.isValid(unit)) {
|
|
18160
|
-
throw new
|
|
18330
|
+
throw new import_node_server_utils42.BadRequestError("Invalid unit ID.");
|
|
18161
18331
|
}
|
|
18162
18332
|
const query2 = {
|
|
18163
18333
|
unit: new import_mongodb37.ObjectId(unit),
|
|
@@ -18202,14 +18372,14 @@ function usePersonRepo() {
|
|
|
18202
18372
|
]).toArray();
|
|
18203
18373
|
return await withoutDeletedPlates(data);
|
|
18204
18374
|
} catch (error) {
|
|
18205
|
-
throw new
|
|
18375
|
+
throw new import_node_server_utils42.InternalServerError(
|
|
18206
18376
|
"Failed to fetch people type residents by unit."
|
|
18207
18377
|
);
|
|
18208
18378
|
}
|
|
18209
18379
|
}
|
|
18210
18380
|
async function getCompany(search, orgs) {
|
|
18211
18381
|
try {
|
|
18212
|
-
const cacheKey = (0,
|
|
18382
|
+
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(site_people_namespace_collection, {
|
|
18213
18383
|
company: search
|
|
18214
18384
|
});
|
|
18215
18385
|
const baseQuery = {
|
|
@@ -18279,18 +18449,18 @@ function usePersonRepo() {
|
|
|
18279
18449
|
]).toArray();
|
|
18280
18450
|
return data;
|
|
18281
18451
|
} catch (error) {
|
|
18282
|
-
throw new
|
|
18452
|
+
throw new import_node_server_utils42.InternalServerError("Failed to fetch visitor by company.");
|
|
18283
18453
|
}
|
|
18284
18454
|
}
|
|
18285
18455
|
async function getPeopleByPlateNumber(plateNumber) {
|
|
18286
|
-
const cacheKey = (0,
|
|
18456
|
+
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(site_people_namespace_collection, {
|
|
18287
18457
|
plateNumber,
|
|
18288
18458
|
key: "get-people-plate-number"
|
|
18289
18459
|
});
|
|
18290
18460
|
try {
|
|
18291
18461
|
const cacheData = await getCache(cacheKey);
|
|
18292
18462
|
if (cacheData) {
|
|
18293
|
-
|
|
18463
|
+
import_node_server_utils42.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
18294
18464
|
return await withoutDeletedPlates(cacheData);
|
|
18295
18465
|
}
|
|
18296
18466
|
const data = await collection.find(
|
|
@@ -18298,13 +18468,13 @@ function usePersonRepo() {
|
|
|
18298
18468
|
{ sort: { _id: -1 } }
|
|
18299
18469
|
).toArray();
|
|
18300
18470
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
18301
|
-
|
|
18471
|
+
import_node_server_utils42.logger.info(`Cache set for key: ${cacheKey}`);
|
|
18302
18472
|
}).catch((err) => {
|
|
18303
|
-
|
|
18473
|
+
import_node_server_utils42.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
18304
18474
|
});
|
|
18305
18475
|
return await withoutDeletedPlates(data);
|
|
18306
18476
|
} catch (error) {
|
|
18307
|
-
throw new
|
|
18477
|
+
throw new import_node_server_utils42.InternalServerError("Failed to fetch people by plate number.");
|
|
18308
18478
|
}
|
|
18309
18479
|
}
|
|
18310
18480
|
async function getPeopleByNRIC({
|
|
@@ -18329,13 +18499,13 @@ function usePersonRepo() {
|
|
|
18329
18499
|
sort: JSON.stringify(sort)
|
|
18330
18500
|
};
|
|
18331
18501
|
try {
|
|
18332
|
-
const cacheKey = (0,
|
|
18502
|
+
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(
|
|
18333
18503
|
site_people_namespace_collection,
|
|
18334
18504
|
cacheOptions
|
|
18335
18505
|
);
|
|
18336
18506
|
const cachedData = await getCache(cacheKey);
|
|
18337
18507
|
if (cachedData) {
|
|
18338
|
-
|
|
18508
|
+
import_node_server_utils42.logger.info(`Cache hit for key: ${cacheKey}`);
|
|
18339
18509
|
const cachedPage = cachedData;
|
|
18340
18510
|
return {
|
|
18341
18511
|
...cachedPage,
|
|
@@ -18344,26 +18514,26 @@ function usePersonRepo() {
|
|
|
18344
18514
|
}
|
|
18345
18515
|
const items = await collection.find(query2).sort(sort).skip(page * limit).limit(limit).toArray();
|
|
18346
18516
|
const length = await collection.countDocuments(query2);
|
|
18347
|
-
const data = (0,
|
|
18517
|
+
const data = (0, import_node_server_utils42.paginate)(
|
|
18348
18518
|
await withoutDeletedPlates(items),
|
|
18349
18519
|
page,
|
|
18350
18520
|
limit,
|
|
18351
18521
|
length
|
|
18352
18522
|
);
|
|
18353
18523
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
18354
|
-
|
|
18524
|
+
import_node_server_utils42.logger.info(`Cache set for key: ${cacheKey}`);
|
|
18355
18525
|
}).catch((err) => {
|
|
18356
|
-
|
|
18526
|
+
import_node_server_utils42.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
18357
18527
|
});
|
|
18358
18528
|
return data;
|
|
18359
18529
|
} catch (error) {
|
|
18360
|
-
throw new
|
|
18530
|
+
throw new import_node_server_utils42.InternalServerError("Failed to retrieve person by NRIC.");
|
|
18361
18531
|
}
|
|
18362
18532
|
}
|
|
18363
18533
|
async function pushVehicleById(id, plate, session) {
|
|
18364
18534
|
const { plateNumber, recNo } = plate;
|
|
18365
18535
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18366
|
-
const _id = (0,
|
|
18536
|
+
const _id = (0, import_node_server_utils42.toObjectId)(id);
|
|
18367
18537
|
try {
|
|
18368
18538
|
const updateExisting = await collection.updateOne(
|
|
18369
18539
|
{
|
|
@@ -18396,15 +18566,15 @@ function usePersonRepo() {
|
|
|
18396
18566
|
);
|
|
18397
18567
|
}
|
|
18398
18568
|
} catch (error) {
|
|
18399
|
-
throw new
|
|
18569
|
+
throw new import_node_server_utils42.InternalServerError("Failed to push vehicle plates by nric.");
|
|
18400
18570
|
}
|
|
18401
18571
|
}
|
|
18402
18572
|
async function pullVehicleByRecNo(recNo, scope, session) {
|
|
18403
18573
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
18404
|
-
const owner = scope?.peopleId ? (0,
|
|
18405
|
-
const site = scope?.site ? (0,
|
|
18574
|
+
const owner = scope?.peopleId ? (0, import_node_server_utils42.toObjectId)(scope.peopleId) : null;
|
|
18575
|
+
const site = scope?.site ? (0, import_node_server_utils42.toObjectId)(scope.site) : null;
|
|
18406
18576
|
if (!owner && !site) {
|
|
18407
|
-
throw new
|
|
18577
|
+
throw new import_node_server_utils42.BadRequestError(
|
|
18408
18578
|
"Cannot remove a vehicle plate without a person or a site."
|
|
18409
18579
|
);
|
|
18410
18580
|
}
|
|
@@ -18445,24 +18615,24 @@ function usePersonRepo() {
|
|
|
18445
18615
|
{ session }
|
|
18446
18616
|
);
|
|
18447
18617
|
} catch (error) {
|
|
18448
|
-
|
|
18618
|
+
import_node_server_utils42.logger.log({
|
|
18449
18619
|
level: "error",
|
|
18450
18620
|
message: `pullVehicleByRecNo failed on ${matchKey} for ${owner ? "person" : "site"} ${String(owner ?? site)}: ${error?.message ?? error}`
|
|
18451
18621
|
});
|
|
18452
|
-
throw new
|
|
18622
|
+
throw new import_node_server_utils42.InternalServerError(
|
|
18453
18623
|
"Could not take the plate off the resident's record."
|
|
18454
18624
|
);
|
|
18455
18625
|
}
|
|
18456
18626
|
}
|
|
18457
18627
|
async function getByUserId(userId) {
|
|
18458
|
-
const user = (0,
|
|
18459
|
-
const cacheKey = (0,
|
|
18628
|
+
const user = (0, import_node_server_utils42.toObjectId)(userId);
|
|
18629
|
+
const cacheKey = (0, import_node_server_utils42.makeCacheKey)(site_people_namespace_collection, {
|
|
18460
18630
|
user: userId
|
|
18461
18631
|
});
|
|
18462
18632
|
try {
|
|
18463
18633
|
const cached = await getCache(cacheKey);
|
|
18464
18634
|
if (cached) {
|
|
18465
|
-
|
|
18635
|
+
import_node_server_utils42.logger.log({
|
|
18466
18636
|
level: "info",
|
|
18467
18637
|
message: `Cache hit for getByUserId person: ${cacheKey}`
|
|
18468
18638
|
});
|
|
@@ -18472,22 +18642,22 @@ function usePersonRepo() {
|
|
|
18472
18642
|
user
|
|
18473
18643
|
});
|
|
18474
18644
|
setCache(cacheKey, result, 15 * 60).then(() => {
|
|
18475
|
-
|
|
18645
|
+
import_node_server_utils42.logger.log({
|
|
18476
18646
|
level: "info",
|
|
18477
18647
|
message: `Cache set for person by user: ${cacheKey}`
|
|
18478
18648
|
});
|
|
18479
18649
|
}).catch((err) => {
|
|
18480
|
-
|
|
18650
|
+
import_node_server_utils42.logger.log({
|
|
18481
18651
|
level: "error",
|
|
18482
18652
|
message: `Failed to set cache for person by user: ${err.message}`
|
|
18483
18653
|
});
|
|
18484
18654
|
});
|
|
18485
18655
|
return result;
|
|
18486
18656
|
} catch (error) {
|
|
18487
|
-
if (error instanceof
|
|
18657
|
+
if (error instanceof import_node_server_utils42.AppError) {
|
|
18488
18658
|
throw error;
|
|
18489
18659
|
} else {
|
|
18490
|
-
throw new
|
|
18660
|
+
throw new import_node_server_utils42.InternalServerError("Failed to get person by user.");
|
|
18491
18661
|
}
|
|
18492
18662
|
}
|
|
18493
18663
|
}
|
|
@@ -18496,7 +18666,7 @@ function usePersonRepo() {
|
|
|
18496
18666
|
try {
|
|
18497
18667
|
_id = new import_mongodb37.ObjectId(_id);
|
|
18498
18668
|
} catch (error) {
|
|
18499
|
-
throw new
|
|
18669
|
+
throw new import_node_server_utils42.BadRequestError("Invalid ID format.");
|
|
18500
18670
|
}
|
|
18501
18671
|
try {
|
|
18502
18672
|
const res = await collection.updateOne(
|
|
@@ -18505,14 +18675,14 @@ function usePersonRepo() {
|
|
|
18505
18675
|
{ session }
|
|
18506
18676
|
);
|
|
18507
18677
|
if (res.modifiedCount === 0) {
|
|
18508
|
-
throw new
|
|
18678
|
+
throw new import_node_server_utils42.InternalServerError(`Unable to ${value.status} person.`);
|
|
18509
18679
|
}
|
|
18510
18680
|
delNamespace().then(() => {
|
|
18511
|
-
|
|
18681
|
+
import_node_server_utils42.logger.info(
|
|
18512
18682
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
18513
18683
|
);
|
|
18514
18684
|
}).catch((err) => {
|
|
18515
|
-
|
|
18685
|
+
import_node_server_utils42.logger.error(
|
|
18516
18686
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
18517
18687
|
err
|
|
18518
18688
|
);
|
|
@@ -18528,7 +18698,7 @@ function usePersonRepo() {
|
|
|
18528
18698
|
const data = await collection.find(query2, { session }).limit(10).toArray();
|
|
18529
18699
|
return data;
|
|
18530
18700
|
} catch (error) {
|
|
18531
|
-
throw new
|
|
18701
|
+
throw new import_node_server_utils42.InternalServerError("Failed to find persons" + error);
|
|
18532
18702
|
}
|
|
18533
18703
|
}
|
|
18534
18704
|
async function addFromVisitor(value, session) {
|
|
@@ -18563,7 +18733,7 @@ function usePersonRepo() {
|
|
|
18563
18733
|
_id = new import_mongodb37.ObjectId(personId);
|
|
18564
18734
|
acceptedTerms = new import_mongodb37.ObjectId(termsId);
|
|
18565
18735
|
} catch {
|
|
18566
|
-
throw new
|
|
18736
|
+
throw new import_node_server_utils42.BadRequestError("Invalid ID format.");
|
|
18567
18737
|
}
|
|
18568
18738
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
18569
18739
|
try {
|
|
@@ -18572,7 +18742,7 @@ function usePersonRepo() {
|
|
|
18572
18742
|
{ $set: { acceptedTerms, acceptedTermsAt: now, updatedAt: now } }
|
|
18573
18743
|
);
|
|
18574
18744
|
} catch (error) {
|
|
18575
|
-
throw new
|
|
18745
|
+
throw new import_node_server_utils42.InternalServerError("Failed to record terms acceptance.");
|
|
18576
18746
|
}
|
|
18577
18747
|
}
|
|
18578
18748
|
async function getAcceptedTerms(personId) {
|
|
@@ -18580,7 +18750,7 @@ function usePersonRepo() {
|
|
|
18580
18750
|
try {
|
|
18581
18751
|
_id = new import_mongodb37.ObjectId(personId);
|
|
18582
18752
|
} catch {
|
|
18583
|
-
throw new
|
|
18753
|
+
throw new import_node_server_utils42.BadRequestError("Invalid person ID format.");
|
|
18584
18754
|
}
|
|
18585
18755
|
try {
|
|
18586
18756
|
return await collection.findOne(
|
|
@@ -18588,11 +18758,11 @@ function usePersonRepo() {
|
|
|
18588
18758
|
{ projection: { acceptedTerms: 1, acceptedTermsAt: 1, _id: 0 } }
|
|
18589
18759
|
);
|
|
18590
18760
|
} catch (error) {
|
|
18591
|
-
throw new
|
|
18761
|
+
throw new import_node_server_utils42.InternalServerError("Failed to read terms acceptance.");
|
|
18592
18762
|
}
|
|
18593
18763
|
}
|
|
18594
18764
|
async function updatePlateNumberByUserId(userId, plateNumber, session) {
|
|
18595
|
-
const user = (0,
|
|
18765
|
+
const user = (0, import_node_server_utils42.toObjectId)(userId);
|
|
18596
18766
|
try {
|
|
18597
18767
|
const result = await collection.updateOne(
|
|
18598
18768
|
{ user },
|
|
@@ -18606,25 +18776,25 @@ function usePersonRepo() {
|
|
|
18606
18776
|
{ session }
|
|
18607
18777
|
);
|
|
18608
18778
|
if (result.matchedCount === 0) {
|
|
18609
|
-
throw new
|
|
18779
|
+
throw new import_node_server_utils42.BadRequestError("Person not found for this user.");
|
|
18610
18780
|
}
|
|
18611
18781
|
try {
|
|
18612
18782
|
await delNamespace();
|
|
18613
|
-
|
|
18783
|
+
import_node_server_utils42.logger.info(
|
|
18614
18784
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
18615
18785
|
);
|
|
18616
18786
|
} catch (err) {
|
|
18617
|
-
|
|
18787
|
+
import_node_server_utils42.logger.error(
|
|
18618
18788
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
18619
18789
|
err
|
|
18620
18790
|
);
|
|
18621
18791
|
}
|
|
18622
18792
|
return "Successfully updated plate number.";
|
|
18623
18793
|
} catch (error) {
|
|
18624
|
-
if (error instanceof
|
|
18794
|
+
if (error instanceof import_node_server_utils42.BadRequestError) {
|
|
18625
18795
|
throw error;
|
|
18626
18796
|
}
|
|
18627
|
-
throw new
|
|
18797
|
+
throw new import_node_server_utils42.InternalServerError("Failed to update plate number.");
|
|
18628
18798
|
}
|
|
18629
18799
|
}
|
|
18630
18800
|
return {
|
|
@@ -18655,161 +18825,6 @@ function usePersonRepo() {
|
|
|
18655
18825
|
};
|
|
18656
18826
|
}
|
|
18657
18827
|
|
|
18658
|
-
// src/utils/console-authz.util.ts
|
|
18659
|
-
var import_node_server_utils42 = require("@7365admin1/node-server-utils");
|
|
18660
|
-
|
|
18661
|
-
// src/utils/console-permission.util.ts
|
|
18662
|
-
var CONSOLE_PERMISSIONS = Object.freeze({
|
|
18663
|
-
organizations: Object.freeze([
|
|
18664
|
-
"see-all-organizations",
|
|
18665
|
-
"see-organization-details"
|
|
18666
|
-
]),
|
|
18667
|
-
"promo-codes": Object.freeze([
|
|
18668
|
-
"create-promo-code",
|
|
18669
|
-
"see-promo-code-details",
|
|
18670
|
-
"edit-promo-code-details",
|
|
18671
|
-
"change-promo-code-status",
|
|
18672
|
-
"delete-promo-code"
|
|
18673
|
-
]),
|
|
18674
|
-
users: Object.freeze(["see-all-users", "see-user-details"]),
|
|
18675
|
-
invitations: Object.freeze([
|
|
18676
|
-
"create-invitation",
|
|
18677
|
-
"view-invitations",
|
|
18678
|
-
"cancel-invitation"
|
|
18679
|
-
]),
|
|
18680
|
-
subscriptions: Object.freeze([
|
|
18681
|
-
"see-all-subscriptions",
|
|
18682
|
-
"see-subscription-details",
|
|
18683
|
-
"manage-subscription"
|
|
18684
|
-
]),
|
|
18685
|
-
"sp-approvals": Object.freeze([
|
|
18686
|
-
"see-all-sp-approvals",
|
|
18687
|
-
"approve-sp",
|
|
18688
|
-
"reject-sp",
|
|
18689
|
-
"delete-sp-approval"
|
|
18690
|
-
]),
|
|
18691
|
-
"marketplace-vendors": Object.freeze([
|
|
18692
|
-
"see-all-marketplace-vendors",
|
|
18693
|
-
"see-marketplace-vendor-details"
|
|
18694
|
-
]),
|
|
18695
|
-
"platform-terms": Object.freeze([
|
|
18696
|
-
"see-platform-terms",
|
|
18697
|
-
"edit-platform-terms"
|
|
18698
|
-
]),
|
|
18699
|
-
"activity-history": Object.freeze(["see-activity-history"]),
|
|
18700
|
-
members: Object.freeze([
|
|
18701
|
-
"view-members",
|
|
18702
|
-
"assign-member-role",
|
|
18703
|
-
"suspend-member",
|
|
18704
|
-
"activate-member",
|
|
18705
|
-
"delete-member"
|
|
18706
|
-
]),
|
|
18707
|
-
"roles-and-permissions": Object.freeze([
|
|
18708
|
-
"add-role",
|
|
18709
|
-
"see-all-roles",
|
|
18710
|
-
"see-role-details",
|
|
18711
|
-
"update-role",
|
|
18712
|
-
"delete-role"
|
|
18713
|
-
])
|
|
18714
|
-
});
|
|
18715
|
-
var RESOURCE_SPELLINGS = Object.freeze({
|
|
18716
|
-
"roles-and-permissions": Object.freeze([
|
|
18717
|
-
"roles-and-permissions",
|
|
18718
|
-
"roles"
|
|
18719
|
-
]),
|
|
18720
|
-
roles: Object.freeze(["roles", "roles-and-permissions"])
|
|
18721
|
-
});
|
|
18722
|
-
function consoleSpellings(resource, action) {
|
|
18723
|
-
const resources = RESOURCE_SPELLINGS[resource] ?? [resource];
|
|
18724
|
-
return resources.map((name) => `${name}:${action}`);
|
|
18725
|
-
}
|
|
18726
|
-
function consoleRoleAllowsAll(held) {
|
|
18727
|
-
if (!Array.isArray(held) || held.length === 0)
|
|
18728
|
-
return true;
|
|
18729
|
-
return held.includes("*");
|
|
18730
|
-
}
|
|
18731
|
-
function consoleRoleAllows(held, resource, action) {
|
|
18732
|
-
if (consoleRoleAllowsAll(held))
|
|
18733
|
-
return true;
|
|
18734
|
-
const actions = CONSOLE_PERMISSIONS[resource];
|
|
18735
|
-
if (!actions?.length)
|
|
18736
|
-
return false;
|
|
18737
|
-
const wanted = action ? actions.includes(action) ? [action] : [] : actions;
|
|
18738
|
-
return wanted.some(
|
|
18739
|
-
(name) => consoleSpellings(resource, name).some(
|
|
18740
|
-
(spelling) => held.includes(spelling)
|
|
18741
|
-
)
|
|
18742
|
-
);
|
|
18743
|
-
}
|
|
18744
|
-
|
|
18745
|
-
// src/utils/console-authz.util.ts
|
|
18746
|
-
function callerId(req) {
|
|
18747
|
-
const user = req.user;
|
|
18748
|
-
return user?.user?.toString?.() || user?._id?.toString?.() || "";
|
|
18749
|
-
}
|
|
18750
|
-
async function requirePlatformStaff(req, grant) {
|
|
18751
|
-
const id = callerId(req);
|
|
18752
|
-
const role = id ? await resolveStaffRole(id) : null;
|
|
18753
|
-
if (!role) {
|
|
18754
|
-
throw new import_node_server_utils42.UnauthorizedError("Not authorized.");
|
|
18755
|
-
}
|
|
18756
|
-
if (grant && !consoleRoleAllows(role.permissions, grant.resource, grant.action)) {
|
|
18757
|
-
throw new import_node_server_utils42.UnauthorizedError("Not authorized.");
|
|
18758
|
-
}
|
|
18759
|
-
return id;
|
|
18760
|
-
}
|
|
18761
|
-
async function requireConsolePermission(req, resource, action) {
|
|
18762
|
-
return await requirePlatformStaff(req, { resource, action });
|
|
18763
|
-
}
|
|
18764
|
-
async function requireSelfOrPlatformStaff(req, userId, grant) {
|
|
18765
|
-
const id = callerId(req);
|
|
18766
|
-
const target = userId?.toString() ?? "";
|
|
18767
|
-
if (id && target && target === id)
|
|
18768
|
-
return id;
|
|
18769
|
-
return await requirePlatformStaff(req, grant);
|
|
18770
|
-
}
|
|
18771
|
-
async function requireOrgAccess(req, orgId) {
|
|
18772
|
-
return await requireOrgReach(req, orgId);
|
|
18773
|
-
}
|
|
18774
|
-
async function requirePlatformOwner(req, grant) {
|
|
18775
|
-
const id = callerId(req);
|
|
18776
|
-
if (!id || !await isPlatformOwner(id)) {
|
|
18777
|
-
throw new import_node_server_utils42.UnauthorizedError("Not authorized.");
|
|
18778
|
-
}
|
|
18779
|
-
if (grant)
|
|
18780
|
-
await requirePlatformStaff(req, grant);
|
|
18781
|
-
return id;
|
|
18782
|
-
}
|
|
18783
|
-
async function requireOrgReach(req, orgId) {
|
|
18784
|
-
const id = callerId(req);
|
|
18785
|
-
if (!id)
|
|
18786
|
-
throw new import_node_server_utils42.UnauthorizedError("Not authorized.");
|
|
18787
|
-
const org = orgId?.toString() ?? "";
|
|
18788
|
-
const actor = await resolveInviteActor(id);
|
|
18789
|
-
if (actor.isSuperAdmin)
|
|
18790
|
-
return id;
|
|
18791
|
-
if (org && actor.orgIds.includes(org))
|
|
18792
|
-
return id;
|
|
18793
|
-
if (org && await hasOrgInvitation(id, org))
|
|
18794
|
-
return id;
|
|
18795
|
-
if (org && await hasOrgOwnership(id, org))
|
|
18796
|
-
return id;
|
|
18797
|
-
throw new import_node_server_utils42.UnauthorizedError("Not authorized.");
|
|
18798
|
-
}
|
|
18799
|
-
async function requireInviteReach(req, org, app) {
|
|
18800
|
-
const apps = Array.isArray(app) ? app : [app];
|
|
18801
|
-
if (apps.some((a) => a === PLATFORM_STAFF_MEMBER_TYPE)) {
|
|
18802
|
-
await requirePlatformStaff(req);
|
|
18803
|
-
}
|
|
18804
|
-
if (org)
|
|
18805
|
-
await requireOrgReach(req, org);
|
|
18806
|
-
}
|
|
18807
|
-
async function requireUserFieldWrite(req, userId, field, grant) {
|
|
18808
|
-
if (field === "email")
|
|
18809
|
-
return await requirePlatformStaff(req, grant);
|
|
18810
|
-
return await requireSelfOrPlatformStaff(req, userId, grant);
|
|
18811
|
-
}
|
|
18812
|
-
|
|
18813
18828
|
// src/utils/user-response.util.ts
|
|
18814
18829
|
function publicIdentity(user) {
|
|
18815
18830
|
if (!user || typeof user !== "object")
|
|
@@ -26737,7 +26752,7 @@ async function requireSiteReach(req, site, permission) {
|
|
|
26737
26752
|
if (!siteId)
|
|
26738
26753
|
throw new import_node_server_utils56.UnauthorizedError("Not authorized.");
|
|
26739
26754
|
const actor = await resolveInviteActor(callerId(req));
|
|
26740
|
-
if (actor
|
|
26755
|
+
if (staffMayBypass(actor))
|
|
26741
26756
|
return;
|
|
26742
26757
|
if (permission) {
|
|
26743
26758
|
await useCameraViewService().authorizeSite({
|
|
@@ -26752,8 +26767,9 @@ async function requireSiteReach(req, site, permission) {
|
|
|
26752
26767
|
async function siteReachOf(req) {
|
|
26753
26768
|
const actor = await resolveInviteActor(callerId(req));
|
|
26754
26769
|
const reachable = /* @__PURE__ */ new Map();
|
|
26770
|
+
const bypass = staffMayBypass(actor);
|
|
26755
26771
|
function canReach(record) {
|
|
26756
|
-
if (
|
|
26772
|
+
if (bypass)
|
|
26757
26773
|
return Promise.resolve(true);
|
|
26758
26774
|
if (!record)
|
|
26759
26775
|
return Promise.resolve(false);
|
|
@@ -26774,7 +26790,7 @@ async function siteReachOf(req) {
|
|
|
26774
26790
|
return reachable.get(site);
|
|
26775
26791
|
}
|
|
26776
26792
|
async function only(records) {
|
|
26777
|
-
if (
|
|
26793
|
+
if (bypass)
|
|
26778
26794
|
return records;
|
|
26779
26795
|
const verdicts = await Promise.all(records.map((r) => canReach(r)));
|
|
26780
26796
|
return records.filter((_, i) => verdicts[i]);
|
|
@@ -26788,7 +26804,7 @@ async function requireSiteReachIfSignedIn(req, site) {
|
|
|
26788
26804
|
}
|
|
26789
26805
|
async function entitledSites(req) {
|
|
26790
26806
|
const actor = await resolveInviteActor(callerId(req));
|
|
26791
|
-
if (actor
|
|
26807
|
+
if (staffMayBypass(actor))
|
|
26792
26808
|
return null;
|
|
26793
26809
|
if (actor.memberships.length === 0)
|
|
26794
26810
|
return [];
|
|
@@ -37357,13 +37373,13 @@ var import_node_server_utils101 = require("@7365admin1/node-server-utils");
|
|
|
37357
37373
|
var import_joi50 = __toESM(require("joi"));
|
|
37358
37374
|
async function requireSiteWrite(req, siteId) {
|
|
37359
37375
|
const actor = await resolveInviteActor(callerId(req));
|
|
37360
|
-
if (actor
|
|
37376
|
+
if (staffMayBypass(actor))
|
|
37361
37377
|
return;
|
|
37362
37378
|
await useCameraViewService().entitleSite({ siteId, userId: actor.id });
|
|
37363
37379
|
}
|
|
37364
37380
|
async function requireSiteRead(req, siteId, site) {
|
|
37365
37381
|
const actor = await resolveInviteActor(callerId(req));
|
|
37366
|
-
if (actor
|
|
37382
|
+
if (staffMayBypass(actor))
|
|
37367
37383
|
return;
|
|
37368
37384
|
const owner = (site?.orgId ?? site?.org)?.toString?.() ?? "";
|
|
37369
37385
|
if (owner && actor.orgIds.includes(owner))
|
|
@@ -42188,7 +42204,7 @@ var import_node_server_utils118 = require("@7365admin1/node-server-utils");
|
|
|
42188
42204
|
async function requireEitherOrg(req, ...orgs) {
|
|
42189
42205
|
const wanted = orgs.map((org) => org?.toString?.() ?? "").filter((org) => Boolean(org));
|
|
42190
42206
|
const actor = await resolveInviteActor(callerId(req));
|
|
42191
|
-
if (actor
|
|
42207
|
+
if (staffMayBypass(actor))
|
|
42192
42208
|
return;
|
|
42193
42209
|
if (wanted.length === 0 || !wanted.some((org) => actor.orgIds.includes(org))) {
|
|
42194
42210
|
throw new import_node_server_utils118.UnauthorizedError("Not authorized.");
|
|
@@ -42284,7 +42300,7 @@ function useCustomerSiteController() {
|
|
|
42284
42300
|
try {
|
|
42285
42301
|
await requireOrgAccess(req, org);
|
|
42286
42302
|
const actor = await resolveInviteActor(callerId(req));
|
|
42287
|
-
const siteScope = actor
|
|
42303
|
+
const siteScope = staffMayBypass(actor) ? null : orgSiteScope({ memberships: actor.memberships, org });
|
|
42288
42304
|
const data = await _getAll({
|
|
42289
42305
|
search,
|
|
42290
42306
|
page,
|
|
@@ -42318,7 +42334,7 @@ function useCustomerSiteController() {
|
|
|
42318
42334
|
}
|
|
42319
42335
|
try {
|
|
42320
42336
|
const actor = await resolveInviteActor(callerId(req));
|
|
42321
|
-
if (!actor
|
|
42337
|
+
if (!staffMayBypass(actor)) {
|
|
42322
42338
|
await useCameraViewService().entitleSite({
|
|
42323
42339
|
siteId: site,
|
|
42324
42340
|
userId: actor.id
|
|
@@ -58254,7 +58270,7 @@ function usePersonController() {
|
|
|
58254
58270
|
} = usePersonService();
|
|
58255
58271
|
async function entitlePerson(req, _id) {
|
|
58256
58272
|
const actor = await resolveInviteActor(callerId(req));
|
|
58257
|
-
if (actor
|
|
58273
|
+
if (staffMayBypass(actor))
|
|
58258
58274
|
return actor;
|
|
58259
58275
|
const person = await _getById(_id);
|
|
58260
58276
|
if (!person)
|
|
@@ -64815,7 +64831,7 @@ function useDocumentManagementController() {
|
|
|
64815
64831
|
return;
|
|
64816
64832
|
}
|
|
64817
64833
|
const actor = await resolveInviteActor(callerId(req));
|
|
64818
|
-
if (actor
|
|
64834
|
+
if (staffMayBypass(actor))
|
|
64819
64835
|
return;
|
|
64820
64836
|
const org = doc?.org?.toString() ?? "";
|
|
64821
64837
|
if (!org || !actor.orgIds.includes(org)) {
|
|
@@ -68779,7 +68795,7 @@ var import_mongodb123 = require("mongodb");
|
|
|
68779
68795
|
var import_node_server_utils193 = require("@7365admin1/node-server-utils");
|
|
68780
68796
|
async function requireOwnUnit(req, site, unitId) {
|
|
68781
68797
|
const actor = await resolveInviteActor(callerId(req));
|
|
68782
|
-
if (actor
|
|
68798
|
+
if (staffMayBypass(actor))
|
|
68783
68799
|
return;
|
|
68784
68800
|
const unit = unitId?.toString?.() ?? "";
|
|
68785
68801
|
const siteId = site?.toString?.() ?? "";
|
|
@@ -77294,10 +77310,10 @@ function useOnlineFormController() {
|
|
|
77294
77310
|
const { actor } = await siteReachOf(req);
|
|
77295
77311
|
if (site) {
|
|
77296
77312
|
await requireSiteReach(req, site);
|
|
77297
|
-
} else if (!actor
|
|
77313
|
+
} else if (!staffMayBypass(actor)) {
|
|
77298
77314
|
throw new import_node_server_utils230.UnauthorizedError("Not authorized.");
|
|
77299
77315
|
}
|
|
77300
|
-
if (org && !actor
|
|
77316
|
+
if (org && !staffMayBypass(actor) && !actor.orgIds.includes(org)) {
|
|
77301
77317
|
throw new import_node_server_utils230.UnauthorizedError("Not authorized.");
|
|
77302
77318
|
}
|
|
77303
77319
|
const data = await _getAll({ search, page, limit, status, org, site });
|
|
@@ -77362,7 +77378,7 @@ function useOnlineFormController() {
|
|
|
77362
77378
|
}
|
|
77363
77379
|
if (payload.org) {
|
|
77364
77380
|
const { actor } = await siteReachOf(req);
|
|
77365
|
-
if (!actor
|
|
77381
|
+
if (!staffMayBypass(actor) && !actor.orgIds.includes(payload.org)) {
|
|
77366
77382
|
throw new import_node_server_utils230.UnauthorizedError("Not authorized.");
|
|
77367
77383
|
}
|
|
77368
77384
|
}
|
|
@@ -84784,7 +84800,7 @@ function useVerificationServiceV2() {
|
|
|
84784
84800
|
if (!actor.id) {
|
|
84785
84801
|
throw new import_node_server_utils262.UnauthorizedError("Sign in to continue.");
|
|
84786
84802
|
}
|
|
84787
|
-
if (!actor
|
|
84803
|
+
if (!staffMayBypass(actor) && !actor.orgIds.includes(orgId)) {
|
|
84788
84804
|
throw new import_node_server_utils262.UnauthorizedError(
|
|
84789
84805
|
"You can only invite service providers to your own organisation's sites."
|
|
84790
84806
|
);
|
|
@@ -92055,6 +92071,7 @@ function useNotificationPreferenceController() {
|
|
|
92055
92071
|
CONSOLE_AUDIT_LABELS,
|
|
92056
92072
|
CONSOLE_PERMISSIONS,
|
|
92057
92073
|
CONTRACTOR_TYPE_LABELS,
|
|
92074
|
+
CROSS_CLIENT_GRANT,
|
|
92058
92075
|
CURRENT_TIME_ENDPOINT,
|
|
92059
92076
|
CameraType,
|
|
92060
92077
|
ConsoleAuditAction,
|
|
@@ -92541,6 +92558,7 @@ function useNotificationPreferenceController() {
|
|
|
92541
92558
|
site_people_namespace_collection,
|
|
92542
92559
|
snapshotEndpoint,
|
|
92543
92560
|
snapshotRefusalReason,
|
|
92561
|
+
staffMayBypass,
|
|
92544
92562
|
stringifyHidJson,
|
|
92545
92563
|
stripFacialImageMetadata,
|
|
92546
92564
|
subscriptionPlanSchema,
|