@7365admin1/core 3.68.2 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @iservice365/core
2
2
 
3
+ ## 3.68.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 1d5050b: 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.
8
+
3
9
  ## 3.68.2
4
10
 
5
11
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,10 +1,8 @@
1
1
  import * as mongodb from 'mongodb';
2
2
  import { ObjectId, ClientSession, Db, Collection, Document, AggregateOptions } from 'mongodb';
3
3
  import Joi from 'joi';
4
- import { Request, Response, NextFunction } from 'express';
4
+ import { Request, Response, NextFunction, RequestHandler } from 'express';
5
5
  import * as bson from 'bson';
6
- import * as qs from 'qs';
7
- import * as express_serve_static_core from 'express-serve-static-core';
8
6
  import { z } from 'zod';
9
7
  import { Server } from 'socket.io';
10
8
 
@@ -971,24 +969,25 @@ type TMemberModulesDeps = {
971
969
  requireSelfOrPlatformStaff: typeof requireSelfOrPlatformStaff;
972
970
  gateData?: TModuleGateData;
973
971
  };
972
+ type MemberController = {
973
+ createMember: RequestHandler;
974
+ getByUserId: RequestHandler;
975
+ getByUserIdType: RequestHandler;
976
+ getModulesByUserIdType: RequestHandler;
977
+ getAll: RequestHandler;
978
+ getAllByUser: RequestHandler;
979
+ getOrgsByMembership: RequestHandler;
980
+ updateMemberStatus: RequestHandler;
981
+ updateRoleById: RequestHandler;
982
+ createMemberDirect: RequestHandler;
983
+ updateSiteById: RequestHandler;
984
+ getByUserIdTypeOrg: RequestHandler;
985
+ completeOnboarding: RequestHandler;
986
+ };
974
987
  declare function memberModulesHandlers({ requireSelfOrPlatformStaff, gateData, }: TMemberModulesDeps): {
975
988
  getModulesByUserIdType: (req: Request, res: Response, next: NextFunction) => Promise<void>;
976
989
  };
977
- declare function useMemberController(): {
978
- createMember: (req: Request, res: Response, next: NextFunction) => Promise<void>;
979
- getByUserId: (req: Request, res: Response, next: NextFunction) => Promise<void>;
980
- getByUserIdType: (req: Request, res: Response, next: NextFunction) => Promise<void>;
981
- getModulesByUserIdType: (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void>;
982
- getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
983
- getAllByUser: (req: Request, res: Response, next: NextFunction) => Promise<void>;
984
- getOrgsByMembership: (req: Request, res: Response, next: NextFunction) => Promise<void>;
985
- updateMemberStatus: (req: Request, res: Response, next: NextFunction) => Promise<void>;
986
- updateRoleById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
987
- createMemberDirect: (req: Request, res: Response, next: NextFunction) => Promise<void>;
988
- updateSiteById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
989
- getByUserIdTypeOrg: (req: Request, res: Response, next: NextFunction) => Promise<void>;
990
- completeOnboarding: (req: Request, res: Response, next: NextFunction) => Promise<void>;
991
- };
990
+ declare function useMemberController(): MemberController;
992
991
 
993
992
  declare function useMemberService(): {
994
993
  createMember: (id: string) => Promise<{
@@ -1057,6 +1056,10 @@ declare class MVerification implements TVerification {
1057
1056
  constructor(value: TVerification);
1058
1057
  }
1059
1058
 
1059
+ type TKeyValuePair<K extends string | number | symbol = string, V = any> = {
1060
+ [key in K]: V;
1061
+ };
1062
+
1060
1063
  declare function useVerificationRepo(): {
1061
1064
  createIndex: () => Promise<void>;
1062
1065
  createTextIndex: () => Promise<void>;
@@ -1076,6 +1079,10 @@ declare function useVerificationRepo(): {
1076
1079
  }) => Promise<{}>;
1077
1080
  getByIdByType: (type: string) => Promise<TVerification[]>;
1078
1081
  updateStatusById: (_id: string | ObjectId, status: string, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
1082
+ reissuePendingById: (_id: string | ObjectId, { metadata, expireAt }: {
1083
+ metadata: TKeyValuePair;
1084
+ expireAt: string;
1085
+ }) => Promise<number>;
1079
1086
  getByStatus: (status: string) => Promise<TVerification[]>;
1080
1087
  findOne: (query: any) => Promise<mongodb.WithId<bson.Document> | null>;
1081
1088
  completePendingInvites: ({ email, orgId, siteId, app, session, }: {
@@ -1087,10 +1094,6 @@ declare function useVerificationRepo(): {
1087
1094
  }) => Promise<mongodb.UpdateResult<bson.Document>>;
1088
1095
  };
1089
1096
 
1090
- type TKeyValuePair<K extends string | number | symbol = string, V = any> = {
1091
- [key in K]: V;
1092
- };
1093
-
1094
1097
  declare function useVerificationService(): {
1095
1098
  createUserInvite: ({ email, metadata, }: {
1096
1099
  email: string;
@@ -1560,22 +1563,23 @@ type TOrgOwnerRepairDeps = {
1560
1563
  declare function orgOwnerRepairHandlers({ requireConsolePermission, getOrgUncached, countOrgMembers, claim, release, holdsClaim, findUserByEmail, confirmOwnership, findOwnerRoleId, healDefaultRoles, createMemberDirect, recordConsoleAction, gateOn, }: TOrgOwnerRepairDeps): {
1561
1564
  repairOwnerMembership: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1562
1565
  };
1563
- declare function useOrgController(): {
1564
- add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1565
- addOnboardingOrg: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1566
- getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1567
- getOrgsByUserId: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1568
- getByName: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1569
- getById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1570
- getByEmail: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1571
- update: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1572
- getOrgsByEmail: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1573
- getAdminOrgForResident: (_req: Request, res: Response, next: NextFunction) => Promise<void>;
1574
- updateStatus: (req: Request, res: Response, next: NextFunction) => Promise<void>;
1575
- updateModules: (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void>;
1576
- previewOrgModules: (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void>;
1577
- repairOwnerMembership: (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void>;
1578
- };
1566
+ type OrgController = {
1567
+ add: RequestHandler;
1568
+ addOnboardingOrg: RequestHandler;
1569
+ getAll: RequestHandler;
1570
+ getOrgsByUserId: RequestHandler;
1571
+ getByName: RequestHandler;
1572
+ getById: RequestHandler;
1573
+ getByEmail: RequestHandler;
1574
+ update: RequestHandler;
1575
+ getOrgsByEmail: RequestHandler;
1576
+ getAdminOrgForResident: RequestHandler;
1577
+ updateStatus: RequestHandler;
1578
+ updateModules: RequestHandler;
1579
+ previewOrgModules: RequestHandler;
1580
+ repairOwnerMembership: RequestHandler;
1581
+ };
1582
+ declare function useOrgController(): OrgController;
1579
1583
 
1580
1584
  /**
1581
1585
  * V2 organization HTTP surface — new handlers; v1 `useOrgController` remains unchanged.
@@ -3163,19 +3167,20 @@ declare function siteModulesHandlers({ requireSiteWrite, _getSiteById, _getOrgBy
3163
3167
  updateSiteModules: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3164
3168
  previewSiteModules: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3165
3169
  };
3166
- declare function useSiteController(): {
3167
- createSite: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3168
- getSites: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3169
- getSiteById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3170
- updateSiteBlock: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3171
- deleteSite: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3172
- updateById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3173
- updateSiteModules: (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void>;
3174
- previewSiteModules: (req: Request<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>, next: NextFunction) => Promise<void>;
3175
- updateGuardPostsById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3176
- siteInformation: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3177
- getAllSitesForResidentCreation: (req: Request, res: Response, next: NextFunction) => Promise<void>;
3178
- };
3170
+ type SiteController = {
3171
+ createSite: RequestHandler;
3172
+ getSites: RequestHandler;
3173
+ getSiteById: RequestHandler;
3174
+ updateSiteBlock: RequestHandler;
3175
+ deleteSite: RequestHandler;
3176
+ updateById: RequestHandler;
3177
+ updateSiteModules: RequestHandler;
3178
+ previewSiteModules: RequestHandler;
3179
+ updateGuardPostsById: RequestHandler;
3180
+ siteInformation: RequestHandler;
3181
+ getAllSitesForResidentCreation: RequestHandler;
3182
+ };
3183
+ declare function useSiteController(): SiteController;
3179
3184
 
3180
3185
  type TChat = {
3181
3186
  _id?: ObjectId;
package/dist/index.js CHANGED
@@ -11268,9 +11268,6 @@ var import_node_server_utils45 = require("@7365admin1/node-server-utils");
11268
11268
  // src/services/verification.service.ts
11269
11269
  var import_node_server_utils41 = require("@7365admin1/node-server-utils");
11270
11270
 
11271
- // src/repositories/verification.repo.ts
11272
- var import_node_server_utils19 = require("@7365admin1/node-server-utils");
11273
-
11274
11271
  // src/models/verification.model.ts
11275
11272
  var import_node_server_utils18 = require("@7365admin1/node-server-utils");
11276
11273
  var import_mongodb16 = require("mongodb");
@@ -11319,6 +11316,7 @@ var MVerification = class {
11319
11316
  };
11320
11317
 
11321
11318
  // src/repositories/verification.repo.ts
11319
+ var import_node_server_utils19 = require("@7365admin1/node-server-utils");
11322
11320
  var import_mongodb17 = require("mongodb");
11323
11321
  function useVerificationRepo() {
11324
11322
  const db2 = import_node_server_utils19.useAtlas.getDb();
@@ -11548,6 +11546,28 @@ function useVerificationRepo() {
11548
11546
  throw new import_node_server_utils19.InternalServerError("Error updating verification status.");
11549
11547
  }
11550
11548
  }
11549
+ async function reissuePendingById(_id, { metadata, expireAt }) {
11550
+ try {
11551
+ _id = new import_mongodb17.ObjectId(_id);
11552
+ } catch (error) {
11553
+ throw new import_node_server_utils19.BadRequestError("Invalid verification ID format.");
11554
+ }
11555
+ try {
11556
+ const result = await collection.updateOne(
11557
+ { _id, status: "pending" },
11558
+ { $set: { metadata, expireAt, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } }
11559
+ );
11560
+ delNamespace().catch(
11561
+ (err) => import_node_server_utils19.logger.error(`Failed to clear cache for namespace: ${namespace_collection3}`, err)
11562
+ );
11563
+ delCache((0, import_node_server_utils19.makeCacheKey)(namespace_collection3, { _id })).catch(
11564
+ (err) => import_node_server_utils19.logger.error(`Failed to delete cache for verification ${_id}`, err)
11565
+ );
11566
+ return result.modifiedCount;
11567
+ } catch (error) {
11568
+ throw new import_node_server_utils19.InternalServerError("Error re-sending the invitation.");
11569
+ }
11570
+ }
11551
11571
  async function getByStatus(status) {
11552
11572
  try {
11553
11573
  const data = await collection.find({ status }).toArray();
@@ -11617,6 +11637,7 @@ function useVerificationRepo() {
11617
11637
  getVerifications,
11618
11638
  getByIdByType,
11619
11639
  updateStatusById,
11640
+ reissuePendingById,
11620
11641
  getByStatus,
11621
11642
  findOne,
11622
11643
  completePendingInvites
@@ -17606,7 +17627,8 @@ function useVerificationService() {
17606
17627
  add,
17607
17628
  getById: _getById,
17608
17629
  updateStatusById: _updateStatusById,
17609
- getByStatus: _getByStatus
17630
+ getByStatus: _getByStatus,
17631
+ reissuePendingById
17610
17632
  } = useVerificationRepo();
17611
17633
  const { getUserByEmail } = useUserRepo();
17612
17634
  const { getById: getOrgById, getByEmail: getOrgByEmail } = useOrgRepo();
@@ -17681,13 +17703,6 @@ function useVerificationService() {
17681
17703
  }
17682
17704
  const verificationIds = [];
17683
17705
  for (const app of apps) {
17684
- await useVerificationRepo().findOne({
17685
- type,
17686
- email,
17687
- "metadata.app": app,
17688
- "metadata.org": metadata.org,
17689
- "metadata.siteId": metadata.siteId
17690
- });
17691
17706
  const value = {
17692
17707
  type,
17693
17708
  email,
@@ -17698,7 +17713,24 @@ function useVerificationService() {
17698
17713
  expireAt: new Date(Date.now() + 72 * 60 * 60 * 1e3).toISOString(),
17699
17714
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
17700
17715
  };
17701
- const createdId = await add(value);
17716
+ const stored = new MVerification({
17717
+ ...value,
17718
+ metadata: { ...value.metadata }
17719
+ }).metadata;
17720
+ const pending = await useVerificationRepo().findOne({
17721
+ type,
17722
+ // same address in any letter case, as `completePendingInvites` reads it
17723
+ email: new RegExp(`^${email.replace(/[.*+?^$()|[\]{}\\]/g, "\\$&")}$`, "i"),
17724
+ status: "pending",
17725
+ "metadata.app": app,
17726
+ "metadata.org": stored.org,
17727
+ "metadata.siteId": stored.siteId
17728
+ });
17729
+ const reissued = pending?._id && await reissuePendingById(pending._id, {
17730
+ metadata: stored,
17731
+ expireAt: value.expireAt
17732
+ });
17733
+ const createdId = reissued ? pending._id : await add(value);
17702
17734
  verificationIds.push(createdId.toString());
17703
17735
  const link = `${APP_MAIN}/verify/invitation/${createdId}`;
17704
17736
  const emailContent = (0, import_node_server_utils41.compileHandlebar)({
@@ -29782,6 +29814,7 @@ function useMemberController() {
29782
29814
  // src/controllers/verification.controller.ts
29783
29815
  var import_node_server_utils66 = require("@7365admin1/node-server-utils");
29784
29816
  var import_joi28 = __toESM(require("joi"));
29817
+ var withoutEmail = (payload) => JSON.stringify({ ...payload, email: payload?.email ? "[redacted]" : void 0 });
29785
29818
  function callerId2(req) {
29786
29819
  const user = req.user;
29787
29820
  return user?.user?.toString?.() || user?._id?.toString?.();
@@ -29848,7 +29881,7 @@ function useVerificationController() {
29848
29881
  const payload = { ...req.body };
29849
29882
  import_node_server_utils66.logger.log({
29850
29883
  level: "info",
29851
- message: `[invite/user] payload: ${JSON.stringify(payload)}`
29884
+ message: `[invite/user] payload: ${withoutEmail(payload)}`
29852
29885
  });
29853
29886
  const validation = import_joi28.default.object({
29854
29887
  email: import_joi28.default.string().email().required(),
@@ -29904,7 +29937,7 @@ function useVerificationController() {
29904
29937
  } catch (error2) {
29905
29938
  import_node_server_utils66.logger.log({
29906
29939
  level: "error",
29907
- message: `[invite/user] error for payload ${JSON.stringify(payload)}: ${error2.message}`
29940
+ message: `[invite/user] error for payload ${withoutEmail(payload)}: ${error2.message}`
29908
29941
  });
29909
29942
  next(error2);
29910
29943
  return;
@@ -29914,7 +29947,7 @@ function useVerificationController() {
29914
29947
  const payload = { ...req.body };
29915
29948
  import_node_server_utils66.logger.log({
29916
29949
  level: "info",
29917
- message: `[invite/member] payload: ${JSON.stringify(payload)}`
29950
+ message: `[invite/member] payload: ${withoutEmail(payload)}`
29918
29951
  });
29919
29952
  const validation = import_joi28.default.object({
29920
29953
  email: import_joi28.default.string().email().required(),
@@ -29966,7 +29999,7 @@ function useVerificationController() {
29966
29999
  } catch (error2) {
29967
30000
  import_node_server_utils66.logger.log({
29968
30001
  level: "error",
29969
- message: `[invite/member] error for payload ${JSON.stringify(payload)}: ${error2.message}`
30002
+ message: `[invite/member] error for payload ${withoutEmail(payload)}: ${error2.message}`
29970
30003
  });
29971
30004
  next(error2);
29972
30005
  return;
@@ -29976,7 +30009,7 @@ function useVerificationController() {
29976
30009
  const payload = req.body;
29977
30010
  import_node_server_utils66.logger.log({
29978
30011
  level: "info",
29979
- message: `[service-providers/invite] payload: ${JSON.stringify(payload)}`
30012
+ message: `[service-providers/invite] payload: ${withoutEmail(payload)}`
29980
30013
  });
29981
30014
  const validation = import_joi28.default.object({
29982
30015
  email: import_joi28.default.string().email().required(),
@@ -30033,7 +30066,7 @@ function useVerificationController() {
30033
30066
  } catch (error2) {
30034
30067
  import_node_server_utils66.logger.log({
30035
30068
  level: "error",
30036
- message: `[service-providers/invite] error for payload ${JSON.stringify(payload)}: ${error2.message}`
30069
+ message: `[service-providers/invite] error for payload ${withoutEmail(payload)}: ${error2.message}`
30037
30070
  });
30038
30071
  next(error2);
30039
30072
  return;