@platform-x/hep-notification-client 1.3.0 → 1.3.2

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.
Files changed (151) hide show
  1. package/README.md +7 -7
  2. package/dist/jest-setup.js +28 -0
  3. package/dist/jest-setup.js.map +1 -0
  4. package/dist/src/common/controllers/common_controller.js +72 -0
  5. package/dist/src/common/controllers/common_controller.js.map +1 -0
  6. package/dist/src/common/controllers/index.js +29 -0
  7. package/dist/src/common/controllers/index.js.map +1 -0
  8. package/dist/src/common/middleware/commonMiddleware.js +141 -0
  9. package/dist/src/common/middleware/commonMiddleware.js.map +1 -0
  10. package/dist/src/common/service/requestService.js +79 -1
  11. package/dist/src/common/service/requestService.js.map +1 -0
  12. package/dist/src/common/service/twilioService.js +3 -11
  13. package/dist/src/common/service/twilioService.js.map +1 -0
  14. package/dist/src/common/util/commonUtil.js +119 -1
  15. package/dist/src/common/util/commonUtil.js.map +1 -0
  16. package/dist/src/common/util/constants.js +18 -0
  17. package/dist/src/common/util/constants.js.map +1 -0
  18. package/dist/src/common/util/errorHandler.js +4 -6
  19. package/dist/src/common/util/errorHandler.js.map +1 -0
  20. package/dist/src/common/util/httpCodes.js +26 -0
  21. package/dist/src/common/util/httpCodes.js.map +1 -0
  22. package/dist/src/common/util/logger.js +1 -1
  23. package/dist/src/common/util/logger.js.map +1 -0
  24. package/dist/src/common/util/requestTracer.js +18 -1
  25. package/dist/src/common/util/requestTracer.js.map +1 -0
  26. package/dist/src/common/util/solrConnector.js.map +1 -0
  27. package/dist/src/config/index.js +49 -4
  28. package/dist/src/config/index.js.map +1 -0
  29. package/dist/src/platform-x/app.js +35 -0
  30. package/dist/src/platform-x/app.js.map +1 -0
  31. package/dist/src/platform-x/constants/index.js +2 -14
  32. package/dist/src/platform-x/constants/index.js.map +1 -0
  33. package/dist/src/platform-x/constants/style.js +98 -98
  34. package/dist/src/platform-x/constants/style.js.map +1 -0
  35. package/dist/src/platform-x/controllers/cronController.js +399 -0
  36. package/dist/src/platform-x/controllers/cronController.js.map +1 -0
  37. package/dist/src/platform-x/controllers/fileUploadController.js +76 -0
  38. package/dist/src/platform-x/controllers/fileUploadController.js.map +1 -0
  39. package/dist/src/platform-x/controllers/graphRESTControllers.js +183 -0
  40. package/dist/src/platform-x/controllers/graphRESTControllers.js.map +1 -0
  41. package/dist/src/platform-x/controllers/index.js +30 -0
  42. package/dist/src/platform-x/controllers/index.js.map +1 -0
  43. package/dist/src/platform-x/controllers/siteDomainController.js +74 -0
  44. package/dist/src/platform-x/controllers/siteDomainController.js.map +1 -0
  45. package/dist/src/platform-x/dataSource/emailDataSource.js.map +1 -0
  46. package/dist/src/platform-x/database/connection.js +3 -6
  47. package/dist/src/platform-x/database/connection.js.map +1 -0
  48. package/dist/src/platform-x/database/dao/formBuilder.dao.js +1 -1
  49. package/dist/src/platform-x/database/dao/formBuilder.dao.js.map +1 -0
  50. package/dist/src/platform-x/database/dao/siteDomain.dao.js +73 -0
  51. package/dist/src/platform-x/database/dao/siteDomain.dao.js.map +1 -0
  52. package/dist/src/platform-x/database/index.js.map +1 -0
  53. package/dist/src/platform-x/{interface/interface.js → database/interfaces/site_domain.interface.js} +1 -1
  54. package/dist/src/platform-x/database/interfaces/site_domain.interface.js.map +1 -0
  55. package/dist/src/platform-x/database/models/formBuilder.model.js.map +1 -0
  56. package/dist/src/platform-x/database/models/site_domains.model.js +51 -0
  57. package/dist/src/platform-x/database/models/site_domains.model.js.map +1 -0
  58. package/dist/src/platform-x/routes/index.js +19 -0
  59. package/dist/src/platform-x/routes/index.js.map +1 -0
  60. package/dist/src/platform-x/services/cron.services.js +117 -0
  61. package/dist/src/platform-x/services/cron.services.js.map +1 -0
  62. package/dist/src/platform-x/util/emailHandler.js +53 -137
  63. package/dist/src/platform-x/util/emailHandler.js.map +1 -0
  64. package/dist/src/platform-x/util/emailTemplate.js +63 -60
  65. package/dist/src/platform-x/util/emailTemplate.js.map +1 -0
  66. package/dist/src/platform-x/util/solr-data-source/SolrHttpDataSource.js +2 -0
  67. package/dist/src/platform-x/util/solr-data-source/SolrHttpDataSource.js.map +1 -0
  68. package/dist/src/server.js +38 -0
  69. package/dist/src/server.js.map +1 -0
  70. package/dist/swagger.json +247 -0
  71. package/dist/test/controllers/common_controller.spec.js +79 -0
  72. package/dist/test/controllers/common_controller.spec.js.map +1 -0
  73. package/dist/test/middleware/commonMiddleware.spec.js +88 -0
  74. package/dist/test/middleware/commonMiddleware.spec.js.map +1 -0
  75. package/dist/test/platform-x/controllers/graphRESTControllers.spec.js +195 -0
  76. package/dist/test/platform-x/controllers/graphRESTControllers.spec.js.map +1 -0
  77. package/dist/test/platform-x/datasource/emailDataSource.spec.js +81 -0
  78. package/dist/test/platform-x/datasource/emailDataSource.spec.js.map +1 -0
  79. package/dist/test/platform-x/util/emailHandler.spec.js +474 -0
  80. package/dist/test/platform-x/util/emailHandler.spec.js.map +1 -0
  81. package/dist/test/platform-x/util/solr-data-source/SolrHttpDataSource.spec.js +80 -0
  82. package/dist/test/platform-x/util/solr-data-source/SolrHttpDataSource.spec.js.map +1 -0
  83. package/dist/test/services/requestService.spec.js +108 -0
  84. package/dist/test/services/requestService.spec.js.map +1 -0
  85. package/dist/test/services/requestServiceGet.spec.js +43 -0
  86. package/dist/test/services/requestServiceGet.spec.js.map +1 -0
  87. package/dist/test/src/common/service/twilioService.spec.js +65 -0
  88. package/dist/test/src/common/service/twilioService.spec.js.map +1 -0
  89. package/dist/test/util/commonUtil.spec.js +110 -0
  90. package/dist/test/util/commonUtil.spec.js.map +1 -0
  91. package/dist/test/util/logger.spec.js +51 -0
  92. package/dist/test/util/logger.spec.js.map +1 -0
  93. package/dist/test/util/requestTracer.spec.js +64 -0
  94. package/dist/test/util/requestTracer.spec.js.map +1 -0
  95. package/dist/test/util/solrconnector.spec.js +145 -0
  96. package/dist/test/util/solrconnector.spec.js.map +1 -0
  97. package/package.json +66 -62
  98. package/postman_collection/HEP_Environment.postman_environment.json +44 -44
  99. package/postman_collection/hep-notification.postman_collection.json +55 -55
  100. package/reports/output.jtl +1 -1
  101. package/reports/scripts/jmeter_sendgrid.js +34 -34
  102. package/reports/scripts/newman_sendgrid.js +40 -40
  103. package/reports/scripts/sendgrid.js +40 -40
  104. package/reports/scripts/trivy_sendgrid.js +40 -40
  105. package/src/common/service/requestService.ts +87 -0
  106. package/{dist/src/common/service/secretKeyManager.services.js → src/common/service/secretKeyManager.services.ts} +1 -2
  107. package/src/common/service/twilioService.ts +58 -0
  108. package/src/common/util/commonUtil.ts +39 -0
  109. package/src/common/util/errorHandler.ts +120 -0
  110. package/src/common/util/logger.ts +215 -0
  111. package/src/common/util/requestTracer.ts +10 -0
  112. package/src/common/util/solrConnector.ts +319 -0
  113. package/src/config/index.ts +35 -0
  114. package/src/index.ts +34 -0
  115. package/src/platform-x/constants/index.ts +20 -0
  116. package/src/platform-x/constants/style.ts +99 -0
  117. package/src/platform-x/dataSource/emailDataSource.ts +34 -0
  118. package/src/platform-x/database/connection.ts +47 -0
  119. package/src/platform-x/database/dao/formBuilder.dao.ts +33 -0
  120. package/src/platform-x/database/index.ts +7 -0
  121. package/src/platform-x/database/models/formBuilder.model.ts +23 -0
  122. package/src/platform-x/util/emailHandler.ts +580 -0
  123. package/src/platform-x/util/emailTemplate.ts +66 -0
  124. package/src/platform-x/util/solr-data-source/SolrHttpDataSource.ts +97 -0
  125. package/{dist → src}/templates/orderPlaced.ejs +172 -172
  126. package/{dist → src}/templates/orderPlaced.html +189 -189
  127. package/tsconfig.json +73 -0
  128. package/dist/src/common/service/requestService.d.ts +0 -26
  129. package/dist/src/common/service/secretKeyManager.services.d.ts +0 -0
  130. package/dist/src/common/service/twilioService.d.ts +0 -19
  131. package/dist/src/common/util/commonUtil.d.ts +0 -22
  132. package/dist/src/common/util/errorHandler.d.ts +0 -44
  133. package/dist/src/common/util/logger.d.ts +0 -68
  134. package/dist/src/common/util/requestTracer.d.ts +0 -2
  135. package/dist/src/common/util/secretKeyManager.d.ts +0 -7
  136. package/dist/src/common/util/secretKeyManager.js +0 -58
  137. package/dist/src/common/util/solrConnector.d.ts +0 -35
  138. package/dist/src/config/index.d.ts +0 -30
  139. package/dist/src/index.d.ts +0 -5
  140. package/dist/src/index.js +0 -20
  141. package/dist/src/platform-x/constants/index.d.ts +0 -18
  142. package/dist/src/platform-x/constants/style.d.ts +0 -1
  143. package/dist/src/platform-x/dataSource/emailDataSource.d.ts +0 -5
  144. package/dist/src/platform-x/database/connection.d.ts +0 -8
  145. package/dist/src/platform-x/database/dao/formBuilder.dao.d.ts +0 -9
  146. package/dist/src/platform-x/database/index.d.ts +0 -7
  147. package/dist/src/platform-x/database/models/formBuilder.model.d.ts +0 -34
  148. package/dist/src/platform-x/interface/interface.d.ts +0 -4
  149. package/dist/src/platform-x/util/emailHandler.d.ts +0 -62
  150. package/dist/src/platform-x/util/emailTemplate.d.ts +0 -4
  151. package/dist/src/platform-x/util/solr-data-source/SolrHttpDataSource.d.ts +0 -26
@@ -0,0 +1,319 @@
1
+ import { Logger } from './logger';
2
+ import config from '../../config/index';
3
+ import { SolrError, HTTP_STATUS_CODE } from './errorHandler';
4
+ import {
5
+ DEFAULT_SOLR_ROWS,
6
+ HTTP_CONTENT_TYPE_JSON,
7
+ } from '../../platform-x/constants';
8
+ import axios, { AxiosInstance } from 'axios';
9
+
10
+ // Solr constants
11
+ const SOLR_RESPONSE_FORMAT = 'json';
12
+ const SOLR_SELECT_ENDPOINT = '/select';
13
+ const SOLR_UPDATE_ENDPOINT = '/update';
14
+ const SOLR_DEFAULT_QUERY = '*:*';
15
+ const SOLR_QUERY_JOIN_OPERATOR = ' AND ';
16
+ const SOLR_PROTOCOL_HTTPS = 'https';
17
+ const SOLR_PROTOCOL_HTTP = 'http';
18
+
19
+ // Error constants
20
+ const SOLR_ERROR_NETWORK = 'Network error';
21
+ const SOLR_ERROR_EXECUTION = 'Solr execution error';
22
+ const SOLR_ERROR_CODE_ETIMEDOUT = 'ETIMEDOUT';
23
+ const SOLR_ERROR_CODE_ECONNRESET = 'ECONNRESET';
24
+ const SOLR_ERROR_CODE_ECONNABORTED = 'ECONNABORTED';
25
+ const SOLR_TIMEOUT_KEYWORD = 'timeout';
26
+ const HTTP_STATUS_OK = 200;
27
+ const HTTP_STATUS_REQUEST_TIMEOUT = 408;
28
+
29
+ interface SolrQuery {
30
+ query(query: string | object | null | undefined): any;
31
+ paginate(start?: number, rows?: number): any;
32
+ filterList(fields: object | string[] | null | undefined): any;
33
+ sort(fields: object | string[] | null | undefined): any;
34
+ filterQuery(fields: object | string[] | null | undefined): any;
35
+ facet(fields: object | string | null | undefined): any;
36
+ }
37
+
38
+ /**
39
+ * Prepares query value - handles both string and object types
40
+ * @param query - string, object, null, or undefined
41
+ * @returns formatted query string for Solr
42
+ */
43
+ const prepareQuery = (query: string | object | null | undefined): string => {
44
+ if (!query) return SOLR_DEFAULT_QUERY;
45
+ if (typeof query === 'string') return query;
46
+ if (typeof query === 'object' && !Array.isArray(query)) {
47
+ return Object.entries(query)
48
+ .map(([field, value]) => {
49
+ if (typeof value === 'string') {
50
+ if (value.includes('"') || value.includes("'") || value.includes('*') || value.includes('(') || value.includes('[')) {
51
+ return `${field}:${value}`;
52
+ }
53
+ return `${field}:"${value}"`;
54
+ }
55
+ return `${field}:${value}`;
56
+ })
57
+ .join(SOLR_QUERY_JOIN_OPERATOR);
58
+ }
59
+ return SOLR_DEFAULT_QUERY;
60
+ };
61
+
62
+ export class SolrClient {
63
+ private host: string = config?.SOLR?.HOST ?? '';
64
+ private port: number = Number(config?.SOLR?.PORT);
65
+ private core: string;
66
+ private path: string = config?.SOLR?.PATH ?? '/solr';
67
+ private httpClient: AxiosInstance;
68
+ private queryParams: any;
69
+ private secure: boolean = config?.SOLR?.SECURE;
70
+
71
+ constructor(core?: string) {
72
+ this.core = core ?? process.env?.SOLR_CORE ?? '';
73
+
74
+ const protocol = this.secure ? SOLR_PROTOCOL_HTTPS : SOLR_PROTOCOL_HTTP;
75
+ const baseURL = `${protocol}://${this.host}:${this.port}${this.path}`;
76
+
77
+ this.httpClient = axios.create({
78
+ baseURL,
79
+ headers: {
80
+ 'Content-Type': HTTP_CONTENT_TYPE_JSON,
81
+ 'Accept': HTTP_CONTENT_TYPE_JSON,
82
+ },
83
+ });
84
+ this.queryParams = { wt: SOLR_RESPONSE_FORMAT };
85
+ Logger.info('SolrClient initialized for Solr 9', 'SolrClient');
86
+ Logger.debug('SolrClient initialization payload', 'SolrClient', {
87
+ baseURL,
88
+ core: this.core,
89
+ });
90
+ }
91
+
92
+ public getQuery() {
93
+ return this.queryParams;
94
+ }
95
+
96
+ public createQuery(): SolrQuery {
97
+ this.queryParams = {
98
+ wt: SOLR_RESPONSE_FORMAT,
99
+ start: 0,
100
+ rows: DEFAULT_SOLR_ROWS,
101
+ };
102
+ return {
103
+ query: this.query.bind(this),
104
+ filterQuery: this.filterQuery.bind(this),
105
+ sort: this.sort.bind(this),
106
+ filterList: this.filterList.bind(this),
107
+ paginate: this.paginate.bind(this),
108
+ facet: this.facet.bind(this),
109
+ };
110
+ }
111
+
112
+ public async executeSearch(): Promise<any> {
113
+ return new Promise(async (resolve, reject) => {
114
+ try {
115
+ const response = await this._executeHttpRequest('executeSearch');
116
+ const responseData = response?.data?.grouped ?? response?.data?.response?.docs ?? [];
117
+ resolve(responseData);
118
+ } catch (error: any) {
119
+ reject(this._handleSearchError(error, 'executeSearch'));
120
+ }
121
+ });
122
+ }
123
+
124
+ /**
125
+ * solrSearch - fn to call solr search via Solr 9 HTTP API
126
+ * @param queryParams
127
+ * @param fields
128
+ * @param fieldType
129
+ * @param sortData
130
+ * @param filterQuery
131
+ * @returns
132
+ */
133
+ public async solrSearch(
134
+ queryParams: any,
135
+ fields?: any,
136
+ fieldType?: any,
137
+ sortData?: any,
138
+ filterQuery?: any
139
+ ): Promise<any> {
140
+ return new Promise(async (resolve, reject) => {
141
+ try {
142
+ Logger.info('Reached Solr Search', 'solrSearch');
143
+ Logger.debug('Reached Solr Search', 'solrSearch', { queryParams });
144
+ const q = qCommon(queryParams, fieldType);
145
+ const { start, rows } = paginationCommon(queryParams);
146
+ this.queryParams = {
147
+ q,
148
+ start,
149
+ rows,
150
+ wt: SOLR_RESPONSE_FORMAT,
151
+ };
152
+ if (filterQuery) {
153
+ this.queryParams.fq = `${filterQuery.filterKey}:${filterQuery.filterValue}`;
154
+ }
155
+ if (fields) {
156
+ const fieldsTemp = Array.isArray(fields) ? fields : Object.keys(fields);
157
+ this.queryParams.fl = fieldsTemp.join(',');
158
+ }
159
+ if (sortData) {
160
+ this.queryParams.sort = sortData;
161
+ }
162
+
163
+ const response = await this._executeHttpRequest('solrSearch');
164
+ const responseData = response?.data?.grouped ?? response?.data?.response?.docs ?? [];
165
+ resolve(responseData);
166
+ } catch (error: any) {
167
+ Logger.debug('Reached in solr connector.ts', 'solrSearch', this.queryParams);
168
+ reject(this._handleSearchError(error, 'solrSearch'));
169
+ }
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Function to delete document from solr via Solr 9 HTTP API
175
+ * @param query
176
+ * @returns
177
+ */
178
+ public async deleteByQuery(query: string | object): Promise<boolean> {
179
+ Logger.info('Reached Solr Search', 'solrSearch');
180
+ Logger.debug('Reached Solr Search', 'solrSearch', { queryParams: query });
181
+
182
+ const queryString = prepareQuery(query);
183
+ const endpoint = this.core
184
+ ? `/${this.core}${SOLR_UPDATE_ENDPOINT}?commit=true`
185
+ : `${SOLR_UPDATE_ENDPOINT}?commit=true`;
186
+
187
+ try {
188
+ const response = await this.httpClient.post(endpoint, {
189
+ delete: { query: queryString },
190
+ });
191
+ this._checkSolrResponse(response, 'deleteByQuery');
192
+ return true;
193
+ } catch (err: any) {
194
+ const solrError = this._handleSearchError(err, 'deleteByQuery');
195
+ throw solrError;
196
+ }
197
+ }
198
+
199
+ private async _executeHttpRequest(methodName: string): Promise<any> {
200
+ const endpoint = this.core
201
+ ? `/${this.core}${SOLR_SELECT_ENDPOINT}`
202
+ : SOLR_SELECT_ENDPOINT;
203
+ // http call to solr with query params
204
+ const response = await this.httpClient.get(endpoint, {
205
+ params: this.queryParams,
206
+ validateStatus: (status) => status < HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR,
207
+ });
208
+ // Check for errors in the response status and data
209
+ this._checkSolrResponse(response, methodName);
210
+ return response;
211
+ }
212
+
213
+ // Common error handling for all search methods
214
+ private _handleSearchError(error: any, methodName: string): SolrError {
215
+ // Enhanced timeout error detection
216
+ const isTimeout =
217
+ error?.message?.includes(SOLR_TIMEOUT_KEYWORD) ||
218
+ error?.code === SOLR_ERROR_CODE_ETIMEDOUT ||
219
+ error?.code === SOLR_ERROR_CODE_ECONNRESET ||
220
+ error?.code === SOLR_ERROR_CODE_ECONNABORTED;
221
+
222
+ const errorStatus =
223
+ error?.status ||
224
+ error?.statusCode ||
225
+ (isTimeout
226
+ ? HTTP_STATUS_REQUEST_TIMEOUT
227
+ : HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR);
228
+
229
+ const solrError = new SolrError(
230
+ error?.message || SOLR_ERROR_NETWORK,
231
+ errorStatus
232
+ );
233
+
234
+ Logger.error(`Error in ${methodName}`, methodName, {
235
+ error: error?.message,
236
+ errorCode: error?.code,
237
+ isTimeoutError: isTimeout,
238
+ statusCode: errorStatus,
239
+ });
240
+
241
+ if (isTimeout) {
242
+ Logger.error(`TIMEOUT DETECTED in ${methodName}`, methodName, {
243
+ errorMessage: error?.message,
244
+ errorCode: error?.code,
245
+ });
246
+ }
247
+
248
+ return solrError;
249
+ }
250
+
251
+ // Check the solr response for errors
252
+ private _checkSolrResponse(response: any, methodName: string): void {
253
+ if (
254
+ response?.status !== HTTP_STATUS_OK ||
255
+ response?.data?.error ||
256
+ (response?.data?.responseHeader &&
257
+ response?.data?.responseHeader?.status !== 0)
258
+ ) {
259
+ const errorMsg = response?.data?.error?.msg ?? SOLR_ERROR_EXECUTION;
260
+ const error = new SolrError(errorMsg, response?.status);
261
+ Logger.error(`Error in ${methodName}: ${errorMsg}`, methodName);
262
+ throw error;
263
+ }
264
+ }
265
+
266
+ private query(query: string | object | null | undefined) {
267
+ this.queryParams.q = prepareQuery(query);
268
+ }
269
+
270
+ private paginate(start?: number, rows?: number) {
271
+ this.queryParams.start = start ?? 0;
272
+ this.queryParams.rows = rows ?? DEFAULT_SOLR_ROWS;
273
+ }
274
+
275
+ private filterList(fields: object | string[] | null | undefined) {
276
+ if (fields) {
277
+ const fieldsArray = Array.isArray(fields) ? fields : Object.keys(fields);
278
+ this.queryParams.fl = fieldsArray.join(',');
279
+ }
280
+ }
281
+
282
+ private sort(fields: object | string[] | null | undefined) {
283
+ if (fields) {
284
+ this.queryParams.sort = fields;
285
+ }
286
+ }
287
+
288
+ private facet(fields: any | string | string[] | null | undefined) {
289
+ if (fields) {
290
+ this.queryParams.facet = true;
291
+ this.queryParams['facet.field'] = fields;
292
+ }
293
+ }
294
+
295
+ private filterQuery(fields: any[] | string[] | null | undefined) {
296
+ if (fields) {
297
+ this.queryParams.fq = fields;
298
+ }
299
+ }
300
+ }
301
+
302
+ const qCommon = (queryParams: any, fieldType: any): string => {
303
+ if (queryParams) {
304
+ if (typeof fieldType === 'string') return fieldType;
305
+ if (typeof fieldType === 'object') return prepareQuery(fieldType);
306
+ return SOLR_DEFAULT_QUERY;
307
+ }
308
+ return SOLR_DEFAULT_QUERY;
309
+ };
310
+
311
+ const paginationCommon = (queryParams: any) => {
312
+ let start = 0;
313
+ let rows = DEFAULT_SOLR_ROWS;
314
+ if (queryParams?.pagination) {
315
+ start = queryParams.pagination.start ?? 0;
316
+ rows = queryParams.pagination.rows ?? DEFAULT_SOLR_ROWS;
317
+ }
318
+ return { start, rows };
319
+ };
@@ -0,0 +1,35 @@
1
+ import dotenv from 'dotenv';
2
+ import { DEFAULT_APP_NAME } from '../platform-x/constants';
3
+
4
+ dotenv.config();
5
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
6
+
7
+ export default {
8
+ LOG_LEVELS: process.env.LOG_LEVELS?.split(',') || [],
9
+ APP_NAME: process.env.npm_package_name || DEFAULT_APP_NAME,
10
+ NODE_ENV: process.env.NODE_ENV,
11
+ SENDGRID_API_KEY: process.env.SENDGRID_API_KEY || '',
12
+ EMAIL_FROM: process.env.EMAIL_FROM || '',
13
+ SOLR: {
14
+ HOST: process.env.SOLR_HOST,
15
+ PORT: process.env.SOLR_PORT,
16
+ PATH: process.env.SOLR_PATH,
17
+ CORE: process.env.SOLR_CORE,
18
+ SECURE: Boolean(process.env.SOLR_SECURE),
19
+ },
20
+ TWILIO: {
21
+ ACCOUNT_SID: process.env.TWILIO_ACCOUNT_SID || '',
22
+ AUTH_TOKEN: process.env.TWILIO_AUTH_TOKEN || '',
23
+ SENDER_NUMBER: process.env.TWILIO_SENDER_NUMBER || '',
24
+ },
25
+ MONGO: {
26
+ HOST: process.env.MONGO_HOST,
27
+ PORT: process.env.MONGO_PORT,
28
+ DB_NAME: process.env.MONGO_DB,
29
+ USER: process.env.MONGO_USER,
30
+ PASS: process.env.MONGO_PASS,
31
+ },
32
+ MULTISITE_WITH_SOLR: process.env.MULTISITE_WITH_SOLR || false,
33
+ CFF_MAIL_FROM: process.env.CFF_MAIL_FROM || '',
34
+ SECRET_MODE: process.env.SECRET_MODE || 'gsm'
35
+ };
package/src/index.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { EmailHandler } from "./platform-x/util/emailHandler";
2
+ import { TwilioService } from "./common/service/twilioService";
3
+ import { SecretKeyServices } from "./common/service/secretKeyManager.services";
4
+
5
+ let injectedSecretService: any;
6
+ export const initNotificationSecrets = (secretServiceIns: any) =>{
7
+ injectedSecretService = secretServiceIns;
8
+ }
9
+ export const getIAMSecrets = () =>{
10
+ if (!injectedSecretService) {
11
+ throw new Error("IAM secrets not initialized");
12
+ }
13
+ return injectedSecretService.getSecretKeys(); // returns cached data
14
+ // return new SecretKeyServices().getSecretKeys(); // secret gateway
15
+ }
16
+
17
+
18
+
19
+ // For local testing purpose
20
+ // const emailTriggerRequest = {};
21
+ // const recipientsData = [
22
+ // {
23
+ // name: "any",
24
+ // email: "any"
25
+ // }
26
+ // ];
27
+ // const pushNotificationManager = new EmailHandler();
28
+ // pushNotificationManager.sendPersonalizeEmailRequest({
29
+ // replacement_variables: emailTriggerRequest,
30
+ // recipients: recipientsData,
31
+ // email_type: 'createuser'
32
+ // });
33
+
34
+ export { EmailHandler, TwilioService };
@@ -0,0 +1,20 @@
1
+ export const DEFAULT_SOLR_ROWS = 2147483647;
2
+ export const CREATE_USER_EMAIL_TEMPLATE = [{
3
+ subject: 'Plat-x User Registration',
4
+ hclplatformx_Body: "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap\" rel=\"stylesheet\">\r\n <title>Document</title>\r\n <style>\r\n body {\r\n font-family: 'Inter', sans-serif;\r\n }\r\n @media (max-width: 697px) {\r\n .rw-100 {\r\n width: 100% !important;\r\n padding: 20px !important\r\n }\r\n .padding29 {\r\n padding-left: 29px !important;\r\n padding-right: 29px !important;\r\n }\r\n .padding15 {\r\n padding-left: 15px !important;\r\n padding-right: 15px !important;\r\n }\r\n }\r\n </style>\r\n</head>\r\n<body style=\"margin: 0; padding: 0;\">\r\n <table class=\"rw-100\" style=\"width: 698px; margin: auto; padding: 32px;\">\r\n <thead>\r\n <tr>\r\n <th style=\"padding-bottom: 30px; text-align: left;\"><img src=\"https://platx-dspace-dev.fanuep.com/server/api/core/bitstreams/792c4406-ae39-4cfd-9627-d4af2d2033bd/content\" alt=\"X\" /></th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr>\r\n <td>\r\n <table style=\"text-align: center; width: 100%; background-color: #fbfaff; padding: 32px; border-radius: 18px;\">\r\n <tr>\r\n <td style=\"padding-bottom: 42px;\"><img src=\"https://platx-dspace-dev.fanuep.com/server/api/core/bitstreams/c1118d01-f887-4612-a1d4-19276ef7fe56/content\" style=\"max-width: 100%;\" alt=\"X\" /></td>\r\n </tr>\r\n <tr>\r\n <td style=\"font-size: 24px; font-weight: bold; color: #000;\">Hi, {{FIRST_NAME}}</td>\r\n </tr>\r\n <tr>\r\n <td style=\"font-size: 16px; font-weight: 500; color: #333; padding-top: 20px;\">We’re so happy to have you.</td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n <tr>\r\n <td>\r\n <table style=\"text-align: center; width: 100%;\">\r\n <tr>\r\n <td style=\"font-size: 24px; font-weight: bold; color: #000; padding: 30px 0\">Your team is waiting for you to join them</td>\r\n </tr>\r\n <tr>\r\n <td style=\"padding-bottom: 20px;\"><img src=\"{{PROFILE_IMAGE}}\" alt=\"X\" width=\"50px\" height=\"50px\" /></td>\r\n </tr>\r\n <tr>\r\n <td style=\"font-size: 14px; font-weight: 600; color: #2d2d39;\">{{CREATED_BY}} has invited you to collaborate on</td>\r\n </tr>\r\n <tr>\r\n <td style=\"padding: 10px 0; font-size: 12px; font-weight: bold; color: #5256b7;\">Platform X</td>\r\n </tr>\r\n <tr>\r\n <td style=\"font-size: 12px; font-weight: 400; color: #2d2d39; padding-bottom: 20px;\">Your Role: {{ROLE}}</td>\r\n </tr>\r\n <tr>\r\n <td style=\"padding-bottom: 20px;\">\r\n <a href=\"{{URL}}\" style=\"display: inline-block; padding: 12.4px 40px; border-radius: 4px; background-color: #2d2d39; color: #fff; font-size: 16px; text-decoration: none;\">Join the team</a>\r\n </td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n <tr>\r\n <td style=\"padding: 0 44px;\" class=\"padding29\">\r\n <table style=\"text-align: center; width: 100%; background-color: #fbfaff; padding: 10px\">\r\n <tr>\r\n <td style=\"font-size: 12px; font-weight: 400; color: #2d2d39;\">Your login information</td>\r\n </tr>\r\n <tr>\r\n <td style=\"font-size: 14px; font-weight: 400; color: #5256b7; padding: 10px 0;\">“Email : <span style=\"font-weight: 600;\"> {{USERNAME}}”</span></td>\r\n </tr>\r\n <tr>\r\n <td style=\"font-size: 14px; font-weight: 400; color: #5256b7;\">“Password : <span style=\"font-weight: 600;\">{{PASSWORD}}”</span></td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot>\r\n <tr>\r\n <td>\r\n <table style=\"width: 100%; padding: 30px; text-align: center;\" class=\"padding15\">\r\n <tr>\r\n <td style=\" border-top: 1px solid rgba(0, 0, 0, 0.2); padding: 15px 0; font-size: 24px; font-weight: bold; color: #2d2d39;\">Thank You!</td>\r\n </tr>\r\n <tr>\r\n <td style=\"color: #5c6574; font-size: 12px;\">Copyright © 2023</td>\r\n </tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n</body>\r\n</html>"
5
+ }];
6
+
7
+ /** HTTP Request related constants */
8
+ export const HTTP_CONTENT_TYPE_JSON = 'application/json';
9
+ export const TRACE_ID_HEADER_NAME = 'Platform-X-Trace-Id';
10
+ export const DEFAULT_APP_PORT = 8080;
11
+ export const DEFAULT_APP_NAME = 'api-gateway';
12
+ export const DEFAULT_REALM_NAME = 'platform-x';
13
+
14
+ export const DynamicValues = {
15
+ SENDGRID_API_KEY: 'SENDGRID_API_KEY',
16
+ TWILIO_ACCOUNT_SID: 'TWILIO_ACCOUNT_SID',
17
+ TWILIO_AUTH_TOKEN: 'TWILIO_AUTH_TOKEN',
18
+ TWILIO_SENDER_NUMBER: 'TWILIO_SENDER_NUMBER',
19
+ MONGO_PASS: 'MONGO_PASS',
20
+ };
@@ -0,0 +1,99 @@
1
+ export const style = `<style>
2
+ .username {
3
+ font-size:24px;
4
+ }
5
+ .main_div {
6
+ background-color: #dff3ff;
7
+ box-sizing: border-box;
8
+ font-family: Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, "sans-serif"
9
+ }
10
+ table {
11
+ height: 100%;
12
+ margin-left: auto;
13
+ margin-right: auto;
14
+ }
15
+ .table_div {
16
+ max-width: 600px;
17
+ width: 100%;
18
+ background-color: #fff;
19
+ padding: 40px;
20
+ border-radius: 5px;
21
+ box-shadow: 8px 8px 16px 0 #b4e3ff;
22
+ box-sizing: border-box;
23
+ }
24
+ .table_2 {
25
+ width: 100%;
26
+ padding-bottom: 30px;
27
+ border-bottom: solid 1px #bfbfbf;
28
+ margin-bottom: 30px;
29
+ }
30
+ .w-400 {
31
+ width: 402px;
32
+ }
33
+ .w_h_30 {
34
+ width: 40px;
35
+ height: auto;
36
+ }
37
+ h1 {
38
+ font-size: 24px;
39
+ color: #000;
40
+ text-transform: capitalize;
41
+ margin: 0 0 20px;
42
+ }
43
+ .main_text {
44
+ font-size: 16px;
45
+ line-height: 1.5;
46
+ color: #000000;
47
+ margin: 0 0 30px;
48
+ }
49
+ a {
50
+ color: #0077b5;
51
+ }
52
+ .mb_20 {
53
+ margin-bottom: 20px;
54
+ }
55
+ .btn {
56
+ display: block;
57
+ width: 100px;
58
+ padding: 15px 30px;
59
+ font-size: 18px;
60
+ font-weight: 600;
61
+ color: #ffffff;
62
+ text-align: center;
63
+ background-color: #2D2D39;
64
+ border-radius: 4px;
65
+ text-decoration: none;
66
+ }
67
+ .border {
68
+ margin-bottom: 30px;
69
+ border-bottom: solid 1px #bfbfbf;
70
+ padding-bottom: 30px;
71
+ }
72
+ .mb_pb_20 {
73
+ margin-bottom: 30px;
74
+ padding-bottom: 30px;
75
+ }
76
+ .sub_text {
77
+ font-size: 14px;
78
+ line-height: 1.5;
79
+ color: #000000;
80
+ margin: 26.5px 16px 15px 1px;
81
+ }
82
+ .link {
83
+ font-size: 14px;
84
+ font-weight: 600;
85
+ color: #0077b5;
86
+ margin-bottom: 20px;
87
+ margin-right: 15px;
88
+ }
89
+ .thanks{
90
+ font-size: 16px;
91
+ line-height: 1.5;
92
+ color: #000000;
93
+ margin-top:40px
94
+ }
95
+ .mt_10{
96
+ margin-top:10px
97
+ }
98
+ </style>
99
+ `
@@ -0,0 +1,34 @@
1
+ import { Logger } from '../../common/util/logger';
2
+ import {
3
+ SolrHttpDataSource,
4
+ SolrQueryRequest,
5
+ } from '../util/solr-data-source/SolrHttpDataSource';
6
+ // NOSONAR-NEXT-LINE
7
+ export class EmailDataSource extends SolrHttpDataSource {
8
+ constructor() {
9
+ super();
10
+ }
11
+
12
+ public async fetchPageModel(tagName: string, documentpath?: string) {
13
+ Logger.info(
14
+ 'emailModelDataSource: Reached fetchPageModel',
15
+ 'fetchPageModel'
16
+ );
17
+ Logger.debug('Before calling createQuery method', 'fetchPageModel', tagName);
18
+
19
+ const escapeSolrValue = (value: string) => value.replace(/([\\"])/g, '\\$1');
20
+
21
+ const baseQuery = `hclplatformx_TagName:"email" AND name:"${escapeSolrValue(tagName)}"`;
22
+ const query = documentpath
23
+ ? `${baseQuery} AND documentpath:"${escapeSolrValue(documentpath)}"`
24
+ : baseQuery;
25
+ Logger.info(`Constructed Solr query: ${query}`, 'fetchPageModel');
26
+ const queryRequest: SolrQueryRequest = { query };
27
+ Logger.info(`Calling createQuery with queryRequest: ${JSON.stringify(queryRequest)}`, 'fetchPageModel');
28
+ this.createQuery(queryRequest);
29
+ Logger.debug('Reached fetchPageModel', 'fetchPageModel', queryRequest);
30
+ let response = await this.executeSearch();
31
+ Logger.debug('Reached fetchPageModel', 'fetchPageModel', response);
32
+ return response;
33
+ }
34
+ }
@@ -0,0 +1,47 @@
1
+ import mongoose from 'mongoose';
2
+ import { Logger } from '../../common/util/logger';
3
+ import config from '../../config/index';
4
+ import { DynamicValues } from '../constants';
5
+ import { getIAMSecrets } from '../..';
6
+
7
+ let database = mongoose.connection;
8
+
9
+ // Exit on error
10
+ mongoose.connection.on('error', (err: any) => {
11
+ Logger.info(`MongoDB connection error: ${err}`, 'mongoose');
12
+ process.exit(-1);
13
+ });
14
+
15
+ const connect = async () => {
16
+ if (database.readyState) {
17
+ return;
18
+ }
19
+ const secrets = await getIAMSecrets();
20
+ mongoose.connect(
21
+ `mongodb://${config.MONGO.USER}:${secrets?.[DynamicValues?.MONGO_PASS]}@${config.MONGO.HOST}:${config.MONGO.PORT}/${config.MONGO.DB_NAME}?directConnection=true&authMechanism=DEFAULT&authSource=${config.MONGO.DB_NAME}`
22
+ );
23
+ database = mongoose.connection;
24
+ database.once('open', async () => {
25
+ Logger.info(`[Server] connected to MongoDB`, 'connect');
26
+ });
27
+
28
+ database.on('error', (err={}) => {
29
+ Logger.error(`[Server] error connecting to MongoDB`, 'connect', err);
30
+ process.exit(-1);
31
+ });
32
+ };
33
+
34
+ const disconnect = () => {
35
+ if (!database) {
36
+ return;
37
+ }
38
+ Logger.info(`Disconnected to MongoDB`, 'disconnect');
39
+ mongoose.disconnect();
40
+ };
41
+
42
+ export default {
43
+ database,
44
+ mongoose,
45
+ connect,
46
+ disconnect,
47
+ };
@@ -0,0 +1,33 @@
1
+ import mongoose from 'mongoose';
2
+ import dynamicModelName from '../models/formBuilder.model';
3
+ import moment from 'moment';
4
+ import { Logger } from '../../../common/util/logger';
5
+
6
+ export default class FormBuilderDao {
7
+
8
+ /**
9
+ * Get data based on collectionName collection
10
+ * @param email
11
+ * @returns
12
+ */
13
+ async fetch(collectionName: string, data: any) {
14
+ try {
15
+ Logger.info('FormBuilder Dao:: fetch', 'fetch');
16
+ let DynamicModel: any = await dynamicModelName(collectionName);
17
+ return await DynamicModel.find(data).sort({ updatedAt: -1 });
18
+ } catch (err: any) {
19
+ Logger.error('Error in FormBuilder Dao:', 'fetch', err);
20
+ throw err;
21
+ }
22
+ }
23
+ async details(collectionName: string, filter: any, sort: any) {
24
+ try {
25
+ Logger.info('FormBuilder Dao: details', 'details');
26
+ let DynamicModel: any = await dynamicModelName(collectionName);
27
+ return await DynamicModel.findOne(filter).sort(sort);
28
+ } catch (err: any) {
29
+ Logger.error('Error in FormBuilder Dao:', 'details', err);
30
+ throw err;
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,7 @@
1
+ import connection from './connection';
2
+
3
+ const db = {
4
+ ...connection,
5
+ };
6
+
7
+ export default db;
@@ -0,0 +1,23 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ /**
4
+ * Function for create model with dynamic collection name
5
+ * @param collectionName
6
+ * @returns
7
+ */
8
+ const dynamicModelName = async (collectionName: string) => {
9
+ if (mongoose.modelNames().includes(collectionName)) {
10
+ return mongoose.model(collectionName);
11
+ } else {
12
+ const schema = new mongoose.Schema({},
13
+ {
14
+ timestamps: true,
15
+ minimize: false,
16
+ strict: false,
17
+ }
18
+ );
19
+ return mongoose.model(collectionName, schema, collectionName);
20
+ }
21
+ };
22
+
23
+ export default dynamicModelName;