@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.
- package/.changeset/user-invite-dedupe.md +5 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.js +51 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +59 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/e2e/user-invite-dedupe.e2e.test.mjs +138 -0
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
|
|
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: ${
|
|
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 ${
|
|
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: ${
|
|
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 ${
|
|
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: ${
|
|
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 ${
|
|
30260
|
+
message: `[service-providers/invite] error for payload ${withoutEmail(payload)}: ${error2.message}`
|
|
30228
30261
|
});
|
|
30229
30262
|
next(error2);
|
|
30230
30263
|
return;
|