@7365admin1/core 3.64.5-staging.307 → 3.64.5-staging.308

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.
@@ -0,0 +1,5 @@
1
+ ---
2
+ "@7365admin1/core": patch
3
+ ---
4
+
5
+ Re-inviting the same person to the same app, organisation and site now re-sends the pending invitation instead of adding a duplicate; invite request logs no longer record the invitee's e-mail address.
package/dist/index.d.ts CHANGED
@@ -1057,6 +1057,10 @@ declare class MVerification implements TVerification {
1057
1057
  constructor(value: TVerification);
1058
1058
  }
1059
1059
 
1060
+ type TKeyValuePair<K extends string | number | symbol = string, V = any> = {
1061
+ [key in K]: V;
1062
+ };
1063
+
1060
1064
  declare function useVerificationRepo(): {
1061
1065
  createIndex: () => Promise<void>;
1062
1066
  createTextIndex: () => Promise<void>;
@@ -1076,6 +1080,10 @@ declare function useVerificationRepo(): {
1076
1080
  }) => Promise<{}>;
1077
1081
  getByIdByType: (type: string) => Promise<TVerification[]>;
1078
1082
  updateStatusById: (_id: string | ObjectId, status: string, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
1083
+ reissuePendingById: (_id: string | ObjectId, { metadata, expireAt }: {
1084
+ metadata: TKeyValuePair;
1085
+ expireAt: string;
1086
+ }) => Promise<number>;
1079
1087
  getByStatus: (status: string) => Promise<TVerification[]>;
1080
1088
  findOne: (query: any) => Promise<mongodb.WithId<bson.Document> | null>;
1081
1089
  completePendingInvites: ({ email, orgId, siteId, app, session, }: {
@@ -1087,10 +1095,6 @@ declare function useVerificationRepo(): {
1087
1095
  }) => Promise<mongodb.UpdateResult<bson.Document>>;
1088
1096
  };
1089
1097
 
1090
- type TKeyValuePair<K extends string | number | symbol = string, V = any> = {
1091
- [key in K]: V;
1092
- };
1093
-
1094
1098
  declare function useVerificationService(): {
1095
1099
  createUserInvite: ({ email, metadata, }: {
1096
1100
  email: string;
package/dist/index.js CHANGED
@@ -11278,9 +11278,6 @@ var import_node_server_utils45 = require("@7365admin1/node-server-utils");
11278
11278
  // src/services/verification.service.ts
11279
11279
  var import_node_server_utils41 = require("@7365admin1/node-server-utils");
11280
11280
 
11281
- // src/repositories/verification.repo.ts
11282
- var import_node_server_utils19 = require("@7365admin1/node-server-utils");
11283
-
11284
11281
  // src/models/verification.model.ts
11285
11282
  var import_node_server_utils18 = require("@7365admin1/node-server-utils");
11286
11283
  var import_mongodb16 = require("mongodb");
@@ -11329,6 +11326,7 @@ var MVerification = class {
11329
11326
  };
11330
11327
 
11331
11328
  // src/repositories/verification.repo.ts
11329
+ var import_node_server_utils19 = require("@7365admin1/node-server-utils");
11332
11330
  var import_mongodb17 = require("mongodb");
11333
11331
  function useVerificationRepo() {
11334
11332
  const db2 = import_node_server_utils19.useAtlas.getDb();
@@ -11558,6 +11556,28 @@ function useVerificationRepo() {
11558
11556
  throw new import_node_server_utils19.InternalServerError("Error updating verification status.");
11559
11557
  }
11560
11558
  }
11559
+ async function reissuePendingById(_id, { metadata, expireAt }) {
11560
+ try {
11561
+ _id = new import_mongodb17.ObjectId(_id);
11562
+ } catch (error) {
11563
+ throw new import_node_server_utils19.BadRequestError("Invalid verification ID format.");
11564
+ }
11565
+ try {
11566
+ const result = await collection.updateOne(
11567
+ { _id, status: "pending" },
11568
+ { $set: { metadata, expireAt, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } }
11569
+ );
11570
+ delNamespace().catch(
11571
+ (err) => import_node_server_utils19.logger.error(`Failed to clear cache for namespace: ${namespace_collection3}`, err)
11572
+ );
11573
+ delCache((0, import_node_server_utils19.makeCacheKey)(namespace_collection3, { _id })).catch(
11574
+ (err) => import_node_server_utils19.logger.error(`Failed to delete cache for verification ${_id}`, err)
11575
+ );
11576
+ return result.modifiedCount;
11577
+ } catch (error) {
11578
+ throw new import_node_server_utils19.InternalServerError("Error re-sending the invitation.");
11579
+ }
11580
+ }
11561
11581
  async function getByStatus(status) {
11562
11582
  try {
11563
11583
  const data = await collection.find({ status }).toArray();
@@ -11627,6 +11647,7 @@ function useVerificationRepo() {
11627
11647
  getVerifications,
11628
11648
  getByIdByType,
11629
11649
  updateStatusById,
11650
+ reissuePendingById,
11630
11651
  getByStatus,
11631
11652
  findOne,
11632
11653
  completePendingInvites
@@ -17616,7 +17637,8 @@ function useVerificationService() {
17616
17637
  add,
17617
17638
  getById: _getById,
17618
17639
  updateStatusById: _updateStatusById,
17619
- getByStatus: _getByStatus
17640
+ getByStatus: _getByStatus,
17641
+ reissuePendingById
17620
17642
  } = useVerificationRepo();
17621
17643
  const { getUserByEmail } = useUserRepo();
17622
17644
  const { getById: getOrgById, getByEmail: getOrgByEmail } = useOrgRepo();
@@ -17691,13 +17713,6 @@ function useVerificationService() {
17691
17713
  }
17692
17714
  const verificationIds = [];
17693
17715
  for (const app of apps) {
17694
- await useVerificationRepo().findOne({
17695
- type,
17696
- email,
17697
- "metadata.app": app,
17698
- "metadata.org": metadata.org,
17699
- "metadata.siteId": metadata.siteId
17700
- });
17701
17716
  const value = {
17702
17717
  type,
17703
17718
  email,
@@ -17708,7 +17723,24 @@ function useVerificationService() {
17708
17723
  expireAt: new Date(Date.now() + 72 * 60 * 60 * 1e3).toISOString(),
17709
17724
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
17710
17725
  };
17711
- const createdId = await add(value);
17726
+ const stored = new MVerification({
17727
+ ...value,
17728
+ metadata: { ...value.metadata }
17729
+ }).metadata;
17730
+ const pending = await useVerificationRepo().findOne({
17731
+ type,
17732
+ // same address in any letter case, as `completePendingInvites` reads it
17733
+ email: new RegExp(`^${email.replace(/[.*+?^$()|[\]{}\\]/g, "\\$&")}$`, "i"),
17734
+ status: "pending",
17735
+ "metadata.app": app,
17736
+ "metadata.org": stored.org,
17737
+ "metadata.siteId": stored.siteId
17738
+ });
17739
+ const reissued = pending?._id && await reissuePendingById(pending._id, {
17740
+ metadata: stored,
17741
+ expireAt: value.expireAt
17742
+ });
17743
+ const createdId = reissued ? pending._id : await add(value);
17712
17744
  verificationIds.push(createdId.toString());
17713
17745
  const link = `${APP_MAIN}/verify/invitation/${createdId}`;
17714
17746
  const emailContent = (0, import_node_server_utils41.compileHandlebar)({
@@ -29973,6 +30005,7 @@ function useMemberController() {
29973
30005
  // src/controllers/verification.controller.ts
29974
30006
  var import_node_server_utils66 = require("@7365admin1/node-server-utils");
29975
30007
  var import_joi28 = __toESM(require("joi"));
30008
+ var withoutEmail = (payload) => JSON.stringify({ ...payload, email: payload?.email ? "[redacted]" : void 0 });
29976
30009
  function callerId2(req) {
29977
30010
  const user = req.user;
29978
30011
  return user?.user?.toString?.() || user?._id?.toString?.();
@@ -30039,7 +30072,7 @@ function useVerificationController() {
30039
30072
  const payload = { ...req.body };
30040
30073
  import_node_server_utils66.logger.log({
30041
30074
  level: "info",
30042
- message: `[invite/user] payload: ${JSON.stringify(payload)}`
30075
+ message: `[invite/user] payload: ${withoutEmail(payload)}`
30043
30076
  });
30044
30077
  const validation = import_joi28.default.object({
30045
30078
  email: import_joi28.default.string().email().required(),
@@ -30095,7 +30128,7 @@ function useVerificationController() {
30095
30128
  } catch (error2) {
30096
30129
  import_node_server_utils66.logger.log({
30097
30130
  level: "error",
30098
- message: `[invite/user] error for payload ${JSON.stringify(payload)}: ${error2.message}`
30131
+ message: `[invite/user] error for payload ${withoutEmail(payload)}: ${error2.message}`
30099
30132
  });
30100
30133
  next(error2);
30101
30134
  return;
@@ -30105,7 +30138,7 @@ function useVerificationController() {
30105
30138
  const payload = { ...req.body };
30106
30139
  import_node_server_utils66.logger.log({
30107
30140
  level: "info",
30108
- message: `[invite/member] payload: ${JSON.stringify(payload)}`
30141
+ message: `[invite/member] payload: ${withoutEmail(payload)}`
30109
30142
  });
30110
30143
  const validation = import_joi28.default.object({
30111
30144
  email: import_joi28.default.string().email().required(),
@@ -30157,7 +30190,7 @@ function useVerificationController() {
30157
30190
  } catch (error2) {
30158
30191
  import_node_server_utils66.logger.log({
30159
30192
  level: "error",
30160
- message: `[invite/member] error for payload ${JSON.stringify(payload)}: ${error2.message}`
30193
+ message: `[invite/member] error for payload ${withoutEmail(payload)}: ${error2.message}`
30161
30194
  });
30162
30195
  next(error2);
30163
30196
  return;
@@ -30167,7 +30200,7 @@ function useVerificationController() {
30167
30200
  const payload = req.body;
30168
30201
  import_node_server_utils66.logger.log({
30169
30202
  level: "info",
30170
- message: `[service-providers/invite] payload: ${JSON.stringify(payload)}`
30203
+ message: `[service-providers/invite] payload: ${withoutEmail(payload)}`
30171
30204
  });
30172
30205
  const validation = import_joi28.default.object({
30173
30206
  email: import_joi28.default.string().email().required(),
@@ -30224,7 +30257,7 @@ function useVerificationController() {
30224
30257
  } catch (error2) {
30225
30258
  import_node_server_utils66.logger.log({
30226
30259
  level: "error",
30227
- message: `[service-providers/invite] error for payload ${JSON.stringify(payload)}: ${error2.message}`
30260
+ message: `[service-providers/invite] error for payload ${withoutEmail(payload)}: ${error2.message}`
30228
30261
  });
30229
30262
  next(error2);
30230
30263
  return;