@platform-x/hep-notification-client 1.1.21 → 1.2.0

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,7 @@
1
+ export declare class SecretKeyServices {
2
+ private ruleCache;
3
+ /**
4
+ * Fetches all the secret keys
5
+ */
6
+ getSecretKeys(): Promise<any>;
7
+ }
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SecretKeyServices = void 0;
16
+ const hep_secret_access_1 = require("hep-secret-access");
17
+ const config_1 = __importDefault(require("../../config"));
18
+ const constants_1 = require("../../platform-x/constants");
19
+ class SecretKeyServices {
20
+ constructor() {
21
+ this.ruleCache = new Map();
22
+ }
23
+ /**
24
+ * Fetches all the secret keys
25
+ */
26
+ getSecretKeys() {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ try {
29
+ // Initialize secret manager object
30
+ if (this.ruleCache.has('secret_data')) {
31
+ return this.ruleCache.get('secret_data');
32
+ }
33
+ const secretObject = (0, hep_secret_access_1.secretManager)();
34
+ // If secret mode is ENV – read one by one
35
+ // for local testing
36
+ if ((config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.SECRET_MODE) === 'env') {
37
+ const keyConfig = {};
38
+ for (const key of Object.values(constants_1.DynamicValues)) {
39
+ // Fetch individual value (existing read() method)
40
+ const value = yield secretObject.read(key);
41
+ keyConfig[key] = value;
42
+ }
43
+ this.ruleCache.set('secret_data', keyConfig);
44
+ return keyConfig;
45
+ }
46
+ // else – fetch all secrets from GSM
47
+ const data = yield secretObject.readAllSecrets();
48
+ this.ruleCache.set('secret_data', data);
49
+ return data;
50
+ }
51
+ catch (err) {
52
+ return {};
53
+ }
54
+ });
55
+ }
56
+ }
57
+ exports.SecretKeyServices = SecretKeyServices;
58
+ //# sourceMappingURL=secretKeyManager.services.js.map
@@ -7,7 +7,8 @@ export declare class TwilioService {
7
7
  * @param authToken - Twilio Auth Token
8
8
  * @param senderNumber - Twilio Sender Phone Number
9
9
  */
10
- constructor();
10
+ private constructor();
11
+ static TwilioClassObject(): Promise<TwilioService>;
11
12
  /**
12
13
  * Send an SMS using Twilio
13
14
  * @param to - Recipient's phone number
@@ -15,7 +15,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.TwilioService = void 0;
16
16
  const twilio_1 = __importDefault(require("twilio"));
17
17
  const logger_1 = require("../util/logger");
18
- const config_1 = __importDefault(require("../../config"));
18
+ const secretKeyManager_services_1 = require("./secretKeyManager.services");
19
+ const constants_1 = require("../../platform-x/constants");
19
20
  class TwilioService {
20
21
  /**
21
22
  * Constructor to initialize Twilio client and sender number
@@ -23,9 +24,15 @@ class TwilioService {
23
24
  * @param authToken - Twilio Auth Token
24
25
  * @param senderNumber - Twilio Sender Phone Number
25
26
  */
26
- constructor() {
27
- this.client = (0, twilio_1.default)(config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.TWILIO.ACCOUNT_SID, config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.TWILIO.AUTH_TOKEN);
28
- this.senderNumber = config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.TWILIO.SENDER_NUMBER;
27
+ constructor(twilioConfig) {
28
+ this.client = (0, twilio_1.default)(twilioConfig === null || twilioConfig === void 0 ? void 0 : twilioConfig[constants_1.DynamicValues === null || constants_1.DynamicValues === void 0 ? void 0 : constants_1.DynamicValues.TWILIO_ACCOUNT_SID], twilioConfig === null || twilioConfig === void 0 ? void 0 : twilioConfig[constants_1.DynamicValues === null || constants_1.DynamicValues === void 0 ? void 0 : constants_1.DynamicValues.TWILIO_AUTH_TOKEN]);
29
+ this.senderNumber = twilioConfig === null || twilioConfig === void 0 ? void 0 : twilioConfig[constants_1.DynamicValues === null || constants_1.DynamicValues === void 0 ? void 0 : constants_1.DynamicValues.TWILIO_SENDER_NUMBER];
30
+ }
31
+ static TwilioClassObject() {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ const secrets = yield new secretKeyManager_services_1.SecretKeyServices().getSecretKeys();
34
+ return new TwilioService(secrets);
35
+ });
29
36
  }
30
37
  /**
31
38
  * Send an SMS using Twilio
@@ -25,5 +25,6 @@ declare const _default: {
25
25
  };
26
26
  MULTISITE_WITH_SOLR: string | boolean;
27
27
  CFF_MAIL_FROM: string;
28
+ SECRET_MODE: string;
28
29
  };
29
30
  export default _default;
@@ -35,5 +35,6 @@ exports.default = {
35
35
  },
36
36
  MULTISITE_WITH_SOLR: process.env.MULTISITE_WITH_SOLR || false,
37
37
  CFF_MAIL_FROM: process.env.CFF_MAIL_FROM || '',
38
+ SECRET_MODE: process.env.SECRET_MODE || 'gsm'
38
39
  };
39
40
  //# sourceMappingURL=index.js.map
@@ -9,3 +9,10 @@ export declare const TRACE_ID_HEADER_NAME = "Platform-X-Trace-Id";
9
9
  export declare const DEFAULT_APP_PORT = 8080;
10
10
  export declare const DEFAULT_APP_NAME = "api-gateway";
11
11
  export declare const DEFAULT_REALM_NAME = "platform-x";
12
+ export declare const DynamicValues: {
13
+ SENDGRID_API_KEY: string;
14
+ TWILIO_ACCOUNT_SID: string;
15
+ TWILIO_AUTH_TOKEN: string;
16
+ TWILIO_SENDER_NUMBER: string;
17
+ MONGO_PASS: string;
18
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_REALM_NAME = exports.DEFAULT_APP_NAME = exports.DEFAULT_APP_PORT = exports.TRACE_ID_HEADER_NAME = exports.HTTP_CONTENT_TYPE_JSON = exports.CREATE_USER_EMAIL_TEMPLATE = exports.DEFAULT_SOLR_ROWS = void 0;
3
+ exports.DynamicValues = exports.DEFAULT_REALM_NAME = exports.DEFAULT_APP_NAME = exports.DEFAULT_APP_PORT = exports.TRACE_ID_HEADER_NAME = exports.HTTP_CONTENT_TYPE_JSON = exports.CREATE_USER_EMAIL_TEMPLATE = exports.DEFAULT_SOLR_ROWS = void 0;
4
4
  exports.DEFAULT_SOLR_ROWS = 2147483647;
5
5
  exports.CREATE_USER_EMAIL_TEMPLATE = [{
6
6
  subject: 'Plat-x User Registration',
@@ -12,4 +12,11 @@ exports.TRACE_ID_HEADER_NAME = 'Platform-X-Trace-Id';
12
12
  exports.DEFAULT_APP_PORT = 8080;
13
13
  exports.DEFAULT_APP_NAME = 'api-gateway';
14
14
  exports.DEFAULT_REALM_NAME = 'platform-x';
15
+ exports.DynamicValues = {
16
+ SENDGRID_API_KEY: 'SENDGRID_API_KEY',
17
+ TWILIO_ACCOUNT_SID: 'TWILIO_ACCOUNT_SID',
18
+ TWILIO_AUTH_TOKEN: 'TWILIO_AUTH_TOKEN',
19
+ TWILIO_SENDER_NUMBER: 'TWILIO_SENDER_NUMBER',
20
+ MONGO_PASS: 'MONGO_PASS',
21
+ };
15
22
  //# sourceMappingURL=index.js.map
@@ -2,7 +2,7 @@ import mongoose from 'mongoose';
2
2
  declare const _default: {
3
3
  database: mongoose.Connection;
4
4
  mongoose: typeof mongoose;
5
- connect: () => void;
5
+ connect: () => Promise<void>;
6
6
  disconnect: () => void;
7
7
  };
8
8
  export default _default;
@@ -15,17 +15,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const mongoose_1 = __importDefault(require("mongoose"));
16
16
  const logger_1 = require("../../common/util/logger");
17
17
  const index_1 = __importDefault(require("../../config/index"));
18
+ const secretKeyManager_services_1 = require("../../common/service/secretKeyManager.services");
19
+ const constants_1 = require("../constants");
18
20
  let database = mongoose_1.default.connection;
19
21
  // Exit on error
20
22
  mongoose_1.default.connection.on('error', (err) => {
21
23
  logger_1.Logger.info(`MongoDB connection error: ${err}`, 'mongoose');
22
24
  process.exit(-1);
23
25
  });
24
- const connect = () => {
26
+ const connect = () => __awaiter(void 0, void 0, void 0, function* () {
25
27
  if (database.readyState) {
26
28
  return;
27
29
  }
28
- mongoose_1.default.connect(`mongodb://${index_1.default.MONGO.USER}:${index_1.default.MONGO.PASS}@${index_1.default.MONGO.HOST}:${index_1.default.MONGO.PORT}/${index_1.default.MONGO.DB_NAME}?directConnection=true&authMechanism=DEFAULT&authSource=${index_1.default.MONGO.DB_NAME}`);
30
+ const secrets = yield new secretKeyManager_services_1.SecretKeyServices().getSecretKeys();
31
+ console.log('>>>>>>>>>>>>>>>>>>>>>>>>>.', secrets);
32
+ mongoose_1.default.connect(`mongodb://${index_1.default.MONGO.USER}:${secrets === null || secrets === void 0 ? void 0 : secrets[constants_1.DynamicValues === null || constants_1.DynamicValues === void 0 ? void 0 : constants_1.DynamicValues.MONGO_PASS]}@${index_1.default.MONGO.HOST}:${index_1.default.MONGO.PORT}/${index_1.default.MONGO.DB_NAME}?directConnection=true&authMechanism=DEFAULT&authSource=${index_1.default.MONGO.DB_NAME}`);
29
33
  database = mongoose_1.default.connection;
30
34
  database.once('open', () => __awaiter(void 0, void 0, void 0, function* () {
31
35
  logger_1.Logger.info(`[Server] connected to MongoDB`, 'connect');
@@ -34,7 +38,7 @@ const connect = () => {
34
38
  logger_1.Logger.error(`[Server] error connecting to MongoDB`, 'connect', err);
35
39
  process.exit(-1);
36
40
  });
37
- };
41
+ });
38
42
  const disconnect = () => {
39
43
  if (!database) {
40
44
  return;
@@ -1,7 +1,7 @@
1
1
  declare const db: {
2
2
  database: import("mongoose").Connection;
3
3
  mongoose: typeof import("mongoose");
4
- connect: () => void;
4
+ connect: () => Promise<void>;
5
5
  disconnect: () => void;
6
6
  };
7
7
  export default db;
@@ -10,37 +10,25 @@ declare const dynamicModelName: (collectionName: string) => Promise<mongoose.Mod
10
10
  } & {}, {}, {}, {}, mongoose.Document<unknown, {}, {
11
11
  createdAt: NativeDate;
12
12
  updatedAt: NativeDate;
13
- } & {}, {}, {
14
- timestamps: true;
15
- minimize: false;
16
- strict: false;
17
- }> & {
13
+ } & {}> & Omit<{
18
14
  createdAt: NativeDate;
19
15
  updatedAt: NativeDate;
20
16
  } & {} & {
21
17
  _id: mongoose.Types.ObjectId;
22
- } & {
23
- __v: number;
24
- }, mongoose.Schema<any, mongoose.Model<any, any, any, any, any, any>, {}, {}, {}, {}, {
18
+ }, never>, mongoose.Schema<any, mongoose.Model<any, any, any, any, any, any>, {}, {}, {}, {}, mongoose.ResolveSchemaOptions<{
25
19
  timestamps: true;
26
20
  minimize: false;
27
21
  strict: false;
28
- }, {
22
+ }>, {
29
23
  createdAt: NativeDate;
30
24
  updatedAt: NativeDate;
31
25
  } & {}, mongoose.Document<unknown, {}, mongoose.FlatRecord<{
32
26
  createdAt: NativeDate;
33
27
  updatedAt: NativeDate;
34
- } & {}>, {}, mongoose.ResolveSchemaOptions<{
35
- timestamps: true;
36
- minimize: false;
37
- strict: false;
38
- }>> & mongoose.FlatRecord<{
28
+ } & {}>> & Omit<mongoose.FlatRecord<{
39
29
  createdAt: NativeDate;
40
30
  updatedAt: NativeDate;
41
31
  } & {}> & {
42
32
  _id: mongoose.Types.ObjectId;
43
- } & {
44
- __v: number;
45
- }>>>;
33
+ }, never>>>>;
46
34
  export default dynamicModelName;
@@ -63,6 +63,7 @@ const dompurify_1 = __importDefault(require("dompurify"));
63
63
  const jsdom_1 = require("jsdom");
64
64
  const logger_1 = require("../../common/util/logger");
65
65
  const path_1 = __importDefault(require("path"));
66
+ const secretKeyManager_services_1 = require("../../common/service/secretKeyManager.services");
66
67
  const window = new jsdom_1.JSDOM('').window;
67
68
  const DOMPurify = (0, dompurify_1.default)(window);
68
69
  // NOSONAR-NEXT-LINE
@@ -76,7 +77,8 @@ class EmailHandler {
76
77
  sendEmail(emailConfig) {
77
78
  return __awaiter(this, void 0, void 0, function* () {
78
79
  logger_1.Logger.info('EmailHandler: Reached sendEmail method', 'sendEmail');
79
- sgMail.setApiKey(config_1.default.SENDGRID_API_KEY);
80
+ const secrets = yield new secretKeyManager_services_1.SecretKeyServices().getSecretKeys();
81
+ sgMail.setApiKey(secrets === null || secrets === void 0 ? void 0 : secrets[constants_1.DynamicValues === null || constants_1.DynamicValues === void 0 ? void 0 : constants_1.DynamicValues.SENDGRID_API_KEY]);
80
82
  // Build personalization object
81
83
  const personalization = {
82
84
  to: [{ email: emailConfig.email }],
@@ -226,14 +228,14 @@ class EmailHandler {
226
228
  */
227
229
  sendEmailWithPersonalizations(emailConfig, isCFF) {
228
230
  return __awaiter(this, void 0, void 0, function* () {
229
- var _a, _b, _c, _d, _e, _f;
230
231
  logger_1.Logger.info(`EmailHandler: Reached sendEmailWithPersonalizations method with emailConfig: ${JSON.stringify(emailConfig)}`, 'sendEmailWithPersonalizations');
231
- logger_1.Logger.info(`SENDGRID CREDENTIALS-----------------> ${config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.SENDGRID_API_KEY} EMAIL_FROM-------> ${config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.EMAIL_FROM}`, 'triggerEmails');
232
+ logger_1.Logger.info(`EMAIL_FROM-------> ${config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.EMAIL_FROM}`, 'triggerEmails');
232
233
  const Mail = sgHelpers.classes.Mail;
233
234
  let email_from = isCFF ? config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.CFF_MAIL_FROM : config_1.default === null || config_1.default === void 0 ? void 0 : config_1.default.EMAIL_FROM;
234
235
  logger_1.Logger.info('sendEmailWithPersonalizations : Email From:', JSON.stringify(email_from));
235
236
  const Personalization = sgHelpers.classes.Personalization;
236
- sgMail.setApiKey(config_1.default.SENDGRID_API_KEY);
237
+ const secrets = yield new secretKeyManager_services_1.SecretKeyServices().getSecretKeys();
238
+ sgMail.setApiKey(secrets === null || secrets === void 0 ? void 0 : secrets[constants_1.DynamicValues === null || constants_1.DynamicValues === void 0 ? void 0 : constants_1.DynamicValues.SENDGRID_API_KEY]);
237
239
  const mail = new Mail();
238
240
  mail.setFrom(email_from);
239
241
  mail.setSubject(emailConfig.subject);
@@ -243,38 +245,28 @@ class EmailHandler {
243
245
  if ((emailConfig === null || emailConfig === void 0 ? void 0 : emailConfig.personalizations) &&
244
246
  (emailConfig === null || emailConfig === void 0 ? void 0 : emailConfig.personalizations.to.length)) {
245
247
  const { to, cc } = emailConfig === null || emailConfig === void 0 ? void 0 : emailConfig.personalizations;
246
- // First personalization with TO and CC
247
- const firstPersonalization = new Personalization();
248
- firstPersonalization.addTo(to[0].to);
249
- // Add CC emails to first personalization only (to avoid duplicate CC emails)
250
- if (cc && cc.length > 0) {
251
- cc.forEach((ccData) => {
252
- firstPersonalization.addCc(ccData.to);
253
- logger_1.Logger.info(`Adding CC email to personalized email: ${ccData.to}`, 'sendEmailWithPersonalizations');
254
- });
255
- }
256
- // Add TO substitutions for first recipient
257
- if ((_a = to[0]) === null || _a === void 0 ? void 0 : _a.substitutions) {
258
- for (const key in (_b = to[0]) === null || _b === void 0 ? void 0 : _b.substitutions) {
259
- if (key) {
260
- firstPersonalization === null || firstPersonalization === void 0 ? void 0 : firstPersonalization.addSubstitution(key, (_c = to[0]) === null || _c === void 0 ? void 0 : _c.substitutions[key]);
261
- }
262
- }
263
- }
264
- mail.addPersonalization(firstPersonalization);
265
- // Remaining personalizations with only TO (no CC to avoid duplicates)
266
- for (let i = 1; i < to.length; i++) {
248
+ // Create separate personalization for each TO recipient with their unique substitutions
249
+ to.forEach((toData, index) => {
267
250
  const personalization = new Personalization();
268
- personalization.addTo(to[i].to);
269
- if ((_d = to[i]) === null || _d === void 0 ? void 0 : _d.substitutions) {
270
- for (const key in (_e = to[i]) === null || _e === void 0 ? void 0 : _e.substitutions) {
251
+ personalization.addTo(toData.to);
252
+ // Add CC emails to EACH personalization (CC gets email for each TO recipient)
253
+ if (cc && cc.length > 0) {
254
+ cc.forEach((ccData) => {
255
+ personalization.addCc(ccData.to);
256
+ logger_1.Logger.info(`Adding CC email ${ccData.to} to personalization ${index + 1} for TO: ${toData.to}`, 'sendEmailWithPersonalizations');
257
+ });
258
+ }
259
+ // Add unique substitutions for each TO recipient
260
+ if (toData === null || toData === void 0 ? void 0 : toData.substitutions) {
261
+ for (const key in toData === null || toData === void 0 ? void 0 : toData.substitutions) {
271
262
  if (key) {
272
- personalization === null || personalization === void 0 ? void 0 : personalization.addSubstitution(key, (_f = to[i]) === null || _f === void 0 ? void 0 : _f.substitutions[key]);
263
+ personalization === null || personalization === void 0 ? void 0 : personalization.addSubstitution(key, toData === null || toData === void 0 ? void 0 : toData.substitutions[key]);
273
264
  }
274
265
  }
275
266
  }
276
267
  mail.addPersonalization(personalization);
277
- }
268
+ logger_1.Logger.info(`Personalization ${index + 1} created for TO: ${toData.to} with ${(cc === null || cc === void 0 ? void 0 : cc.length) || 0} CC recipients`, 'sendEmailWithPersonalizations');
269
+ });
278
270
  // Handle attachments
279
271
  if ((emailConfig === null || emailConfig === void 0 ? void 0 : emailConfig.attachments) && Array.isArray(emailConfig.attachments)) {
280
272
  emailConfig.attachments.forEach((attachment) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platform-x/hep-notification-client",
3
- "version": "1.1.21",
3
+ "version": "1.2.0",
4
4
  "description": "@platform-x/hep-notification-client",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -31,6 +31,7 @@
31
31
  "@types/node": "^15.12.2",
32
32
  "@types/twilio": "^3.19.2",
33
33
  "apollo-server-caching": "^3.3.0",
34
+ "axios": "0.21.4",
34
35
  "bunyan": "^1.8.15",
35
36
  "bunyan-format": "^0.2.1",
36
37
  "cls-hooked": "^4.2.2",
@@ -40,19 +41,19 @@
40
41
  "ejs": "^3.1.10",
41
42
  "express": "^4.17.1",
42
43
  "fs": "^0.0.1-security",
44
+ "hep-secret-access": "^1.3.4",
43
45
  "jsdom": "^26.1.0",
44
46
  "lodash": "4.17.21",
45
47
  "moment": "2.29.4",
46
48
  "moment-timezone": "0.5.34",
49
+ "mongodb": "5.9.2",
50
+ "mongoose": "7.0.3",
47
51
  "mysql2": "2.3.3",
48
52
  "node-html-parser": "5.1.0",
49
53
  "request-ip": "2.1.3",
50
54
  "solr-client": "0.10.0-rc6",
51
55
  "twilio": "^5.3.6",
52
- "uuid": "8.3.2",
53
- "mongodb": "5.9.2",
54
- "mongoose": "7.0.3",
55
- "axios": "0.21.4"
56
+ "uuid": "8.3.2"
56
57
  },
57
58
  "private": false,
58
59
  "publishConfig": {