@7365admin1/core 3.68.1 → 3.68.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -9073,6 +9073,9 @@ import { BadRequestError as BadRequestError12 } from "@7365admin1/node-server-ut
9073
9073
  import Joi7 from "joi";
9074
9074
  import { ObjectId as ObjectId12 } from "mongodb";
9075
9075
  var PLATFORM_STAFF_MEMBER_TYPE = "admin";
9076
+ function isDuplicateMemberError(error) {
9077
+ return error?.code === 11e3 || /E11000|duplicate key/i.test(error?.message ?? "");
9078
+ }
9076
9079
  var MEMBER_TYPES = [
9077
9080
  PLATFORM_STAFF_MEMBER_TYPE,
9078
9081
  "organization",
@@ -9226,8 +9229,7 @@ function useMemberRepo() {
9226
9229
  });
9227
9230
  return "Successfully added member.";
9228
9231
  } catch (error) {
9229
- const isDuplicated = error.message.includes("duplicate");
9230
- if (isDuplicated && error.message.includes("org_1_user_1"))
9232
+ if (isDuplicateMemberError(error))
9231
9233
  throw new BadRequestError13(
9232
9234
  "The user is already a member of this organization."
9233
9235
  );
@@ -10517,17 +10519,6 @@ import {
10517
10519
  useAtlas as useAtlas23
10518
10520
  } from "@7365admin1/node-server-utils";
10519
10521
 
10520
- // src/repositories/verification.repo.ts
10521
- import {
10522
- BadRequestError as BadRequestError17,
10523
- InternalServerError as InternalServerError8,
10524
- logger as logger8,
10525
- makeCacheKey as makeCacheKey6,
10526
- paginate as paginate6,
10527
- useAtlas as useAtlas11,
10528
- useCache as useCache8
10529
- } from "@7365admin1/node-server-utils";
10530
-
10531
10522
  // src/models/verification.model.ts
10532
10523
  import { BadRequestError as BadRequestError16 } from "@7365admin1/node-server-utils";
10533
10524
  import { ObjectId as ObjectId16 } from "mongodb";
@@ -10576,6 +10567,15 @@ var MVerification = class {
10576
10567
  };
10577
10568
 
10578
10569
  // src/repositories/verification.repo.ts
10570
+ import {
10571
+ BadRequestError as BadRequestError17,
10572
+ InternalServerError as InternalServerError8,
10573
+ logger as logger8,
10574
+ makeCacheKey as makeCacheKey6,
10575
+ paginate as paginate6,
10576
+ useAtlas as useAtlas11,
10577
+ useCache as useCache8
10578
+ } from "@7365admin1/node-server-utils";
10579
10579
  import { ObjectId as ObjectId17 } from "mongodb";
10580
10580
  function useVerificationRepo() {
10581
10581
  const db2 = useAtlas11.getDb();
@@ -10805,6 +10805,28 @@ function useVerificationRepo() {
10805
10805
  throw new InternalServerError8("Error updating verification status.");
10806
10806
  }
10807
10807
  }
10808
+ async function reissuePendingById(_id, { metadata, expireAt }) {
10809
+ try {
10810
+ _id = new ObjectId17(_id);
10811
+ } catch (error) {
10812
+ throw new BadRequestError17("Invalid verification ID format.");
10813
+ }
10814
+ try {
10815
+ const result = await collection.updateOne(
10816
+ { _id, status: "pending" },
10817
+ { $set: { metadata, expireAt, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } }
10818
+ );
10819
+ delNamespace().catch(
10820
+ (err) => logger8.error(`Failed to clear cache for namespace: ${namespace_collection3}`, err)
10821
+ );
10822
+ delCache(makeCacheKey6(namespace_collection3, { _id })).catch(
10823
+ (err) => logger8.error(`Failed to delete cache for verification ${_id}`, err)
10824
+ );
10825
+ return result.modifiedCount;
10826
+ } catch (error) {
10827
+ throw new InternalServerError8("Error re-sending the invitation.");
10828
+ }
10829
+ }
10808
10830
  async function getByStatus(status) {
10809
10831
  try {
10810
10832
  const data = await collection.find({ status }).toArray();
@@ -10874,6 +10896,7 @@ function useVerificationRepo() {
10874
10896
  getVerifications,
10875
10897
  getByIdByType,
10876
10898
  updateStatusById,
10899
+ reissuePendingById,
10877
10900
  getByStatus,
10878
10901
  findOne,
10879
10902
  completePendingInvites
@@ -16935,7 +16958,8 @@ function useVerificationService() {
16935
16958
  add,
16936
16959
  getById: _getById,
16937
16960
  updateStatusById: _updateStatusById,
16938
- getByStatus: _getByStatus
16961
+ getByStatus: _getByStatus,
16962
+ reissuePendingById
16939
16963
  } = useVerificationRepo();
16940
16964
  const { getUserByEmail } = useUserRepo();
16941
16965
  const { getById: getOrgById, getByEmail: getOrgByEmail } = useOrgRepo();
@@ -17010,13 +17034,6 @@ function useVerificationService() {
17010
17034
  }
17011
17035
  const verificationIds = [];
17012
17036
  for (const app of apps) {
17013
- await useVerificationRepo().findOne({
17014
- type,
17015
- email,
17016
- "metadata.app": app,
17017
- "metadata.org": metadata.org,
17018
- "metadata.siteId": metadata.siteId
17019
- });
17020
17037
  const value = {
17021
17038
  type,
17022
17039
  email,
@@ -17027,7 +17044,24 @@ function useVerificationService() {
17027
17044
  expireAt: new Date(Date.now() + 72 * 60 * 60 * 1e3).toISOString(),
17028
17045
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
17029
17046
  };
17030
- const createdId = await add(value);
17047
+ const stored = new MVerification({
17048
+ ...value,
17049
+ metadata: { ...value.metadata }
17050
+ }).metadata;
17051
+ const pending = await useVerificationRepo().findOne({
17052
+ type,
17053
+ // same address in any letter case, as `completePendingInvites` reads it
17054
+ email: new RegExp(`^${email.replace(/[.*+?^$()|[\]{}\\]/g, "\\$&")}$`, "i"),
17055
+ status: "pending",
17056
+ "metadata.app": app,
17057
+ "metadata.org": stored.org,
17058
+ "metadata.siteId": stored.siteId
17059
+ });
17060
+ const reissued = pending?._id && await reissuePendingById(pending._id, {
17061
+ metadata: stored,
17062
+ expireAt: value.expireAt
17063
+ });
17064
+ const createdId = reissued ? pending._id : await add(value);
17031
17065
  verificationIds.push(createdId.toString());
17032
17066
  const link = `${APP_MAIN}/verify/invitation/${createdId}`;
17033
17067
  const emailContent = compileHandlebar2({
@@ -29191,6 +29225,7 @@ function useMemberController() {
29191
29225
  // src/controllers/verification.controller.ts
29192
29226
  import { BadRequestError as BadRequestError51, logger as logger38 } from "@7365admin1/node-server-utils";
29193
29227
  import Joi28 from "joi";
29228
+ var withoutEmail = (payload) => JSON.stringify({ ...payload, email: payload?.email ? "[redacted]" : void 0 });
29194
29229
  function callerId2(req) {
29195
29230
  const user = req.user;
29196
29231
  return user?.user?.toString?.() || user?._id?.toString?.();
@@ -29257,7 +29292,7 @@ function useVerificationController() {
29257
29292
  const payload = { ...req.body };
29258
29293
  logger38.log({
29259
29294
  level: "info",
29260
- message: `[invite/user] payload: ${JSON.stringify(payload)}`
29295
+ message: `[invite/user] payload: ${withoutEmail(payload)}`
29261
29296
  });
29262
29297
  const validation = Joi28.object({
29263
29298
  email: Joi28.string().email().required(),
@@ -29313,7 +29348,7 @@ function useVerificationController() {
29313
29348
  } catch (error2) {
29314
29349
  logger38.log({
29315
29350
  level: "error",
29316
- message: `[invite/user] error for payload ${JSON.stringify(payload)}: ${error2.message}`
29351
+ message: `[invite/user] error for payload ${withoutEmail(payload)}: ${error2.message}`
29317
29352
  });
29318
29353
  next(error2);
29319
29354
  return;
@@ -29323,7 +29358,7 @@ function useVerificationController() {
29323
29358
  const payload = { ...req.body };
29324
29359
  logger38.log({
29325
29360
  level: "info",
29326
- message: `[invite/member] payload: ${JSON.stringify(payload)}`
29361
+ message: `[invite/member] payload: ${withoutEmail(payload)}`
29327
29362
  });
29328
29363
  const validation = Joi28.object({
29329
29364
  email: Joi28.string().email().required(),
@@ -29375,7 +29410,7 @@ function useVerificationController() {
29375
29410
  } catch (error2) {
29376
29411
  logger38.log({
29377
29412
  level: "error",
29378
- message: `[invite/member] error for payload ${JSON.stringify(payload)}: ${error2.message}`
29413
+ message: `[invite/member] error for payload ${withoutEmail(payload)}: ${error2.message}`
29379
29414
  });
29380
29415
  next(error2);
29381
29416
  return;
@@ -29385,7 +29420,7 @@ function useVerificationController() {
29385
29420
  const payload = req.body;
29386
29421
  logger38.log({
29387
29422
  level: "info",
29388
- message: `[service-providers/invite] payload: ${JSON.stringify(payload)}`
29423
+ message: `[service-providers/invite] payload: ${withoutEmail(payload)}`
29389
29424
  });
29390
29425
  const validation = Joi28.object({
29391
29426
  email: Joi28.string().email().required(),
@@ -29442,7 +29477,7 @@ function useVerificationController() {
29442
29477
  } catch (error2) {
29443
29478
  logger38.log({
29444
29479
  level: "error",
29445
- message: `[service-providers/invite] error for payload ${JSON.stringify(payload)}: ${error2.message}`
29480
+ message: `[service-providers/invite] error for payload ${withoutEmail(payload)}: ${error2.message}`
29446
29481
  });
29447
29482
  next(error2);
29448
29483
  return;
@@ -96921,6 +96956,7 @@ export {
96921
96956
  incidents_namespace_collection,
96922
96957
  invitationOffersRole,
96923
96958
  isCameraEntitled,
96959
+ isDuplicateMemberError,
96924
96960
  isDuplicateVersionError,
96925
96961
  isLikelySelfServiceEmail,
96926
96962
  isPatrolCctvCamera,