@triproject/nestjs-core 1.0.5

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 (91) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +140 -0
  3. package/dist/bootstrap.d.ts +2 -0
  4. package/dist/bootstrap.js +43 -0
  5. package/dist/config.d.ts +46 -0
  6. package/dist/config.js +50 -0
  7. package/dist/controllers/controller.d.ts +8 -0
  8. package/dist/controllers/controller.js +56 -0
  9. package/dist/drivers/cache/cache.d.ts +18 -0
  10. package/dist/drivers/cache/cache.driver.d.ts +2 -0
  11. package/dist/drivers/cache/cache.driver.js +22 -0
  12. package/dist/drivers/cache/cache.js +92 -0
  13. package/dist/drivers/cache/index.d.ts +3 -0
  14. package/dist/drivers/cache/index.js +19 -0
  15. package/dist/drivers/cache/redis.d.ts +10 -0
  16. package/dist/drivers/cache/redis.js +52 -0
  17. package/dist/drivers/db/db.helper.d.ts +55 -0
  18. package/dist/drivers/db/db.helper.js +217 -0
  19. package/dist/drivers/db/db.module.d.ts +2 -0
  20. package/dist/drivers/db/db.module.js +44 -0
  21. package/dist/drivers/db/db.service.d.ts +10 -0
  22. package/dist/drivers/db/db.service.js +49 -0
  23. package/dist/drivers/db/index.d.ts +5 -0
  24. package/dist/drivers/db/index.js +21 -0
  25. package/dist/drivers/db/migration.d.ts +42 -0
  26. package/dist/drivers/db/migration.js +81 -0
  27. package/dist/drivers/db/repository.d.ts +41 -0
  28. package/dist/drivers/db/repository.js +255 -0
  29. package/dist/drivers/encryptions/encryption.d.ts +8 -0
  30. package/dist/drivers/encryptions/encryption.js +50 -0
  31. package/dist/drivers/encryptions/encryption.module.d.ts +2 -0
  32. package/dist/drivers/encryptions/encryption.module.js +24 -0
  33. package/dist/drivers/encryptions/index.d.ts +3 -0
  34. package/dist/drivers/encryptions/index.js +19 -0
  35. package/dist/drivers/encryptions/jwt.d.ts +6 -0
  36. package/dist/drivers/encryptions/jwt.js +46 -0
  37. package/dist/drivers/encryptions/password-hash.d.ts +11 -0
  38. package/dist/drivers/encryptions/password-hash.js +38 -0
  39. package/dist/drivers/encryptions/snap.signature.d.ts +32 -0
  40. package/dist/drivers/encryptions/snap.signature.js +110 -0
  41. package/dist/drivers/logger/app.logger.d.ts +23 -0
  42. package/dist/drivers/logger/app.logger.js +183 -0
  43. package/dist/drivers/logger/index.d.ts +2 -0
  44. package/dist/drivers/logger/index.js +18 -0
  45. package/dist/drivers/logger/slack.logger.d.ts +4 -0
  46. package/dist/drivers/logger/slack.logger.js +24 -0
  47. package/dist/drivers/mail/index.d.ts +6 -0
  48. package/dist/drivers/mail/index.js +22 -0
  49. package/dist/drivers/mail/mail-template.d.ts +8 -0
  50. package/dist/drivers/mail/mail-template.js +74 -0
  51. package/dist/drivers/mail/mail.config.d.ts +18 -0
  52. package/dist/drivers/mail/mail.config.js +4 -0
  53. package/dist/drivers/mail/mail.d.ts +23 -0
  54. package/dist/drivers/mail/mail.js +98 -0
  55. package/dist/drivers/mail/mail.module.d.ts +2 -0
  56. package/dist/drivers/mail/mail.module.js +26 -0
  57. package/dist/drivers/mail/mail.queue.d.ts +9 -0
  58. package/dist/drivers/mail/mail.queue.js +37 -0
  59. package/dist/drivers/mail/mailer.d.ts +13 -0
  60. package/dist/drivers/mail/mailer.js +62 -0
  61. package/dist/drivers/notifications/index.d.ts +5 -0
  62. package/dist/drivers/notifications/index.js +21 -0
  63. package/dist/drivers/notifications/notification.config.d.ts +8 -0
  64. package/dist/drivers/notifications/notification.config.js +4 -0
  65. package/dist/drivers/notifications/notification.module.d.ts +2 -0
  66. package/dist/drivers/notifications/notification.module.js +25 -0
  67. package/dist/drivers/notifications/notification.queue.d.ts +9 -0
  68. package/dist/drivers/notifications/notification.queue.js +37 -0
  69. package/dist/drivers/notifications/push-notification.d.ts +10 -0
  70. package/dist/drivers/notifications/push-notification.js +75 -0
  71. package/dist/drivers/notifications/slack.d.ts +15 -0
  72. package/dist/drivers/notifications/slack.js +95 -0
  73. package/dist/drivers/queues/app.queue.d.ts +11 -0
  74. package/dist/drivers/queues/app.queue.js +66 -0
  75. package/dist/drivers/queues/index.d.ts +2 -0
  76. package/dist/drivers/queues/index.js +18 -0
  77. package/dist/drivers/queues/queue.module.d.ts +2 -0
  78. package/dist/drivers/queues/queue.module.js +41 -0
  79. package/dist/helpers/exception.helper.d.ts +35 -0
  80. package/dist/helpers/exception.helper.js +71 -0
  81. package/dist/helpers/http.helper.d.ts +23 -0
  82. package/dist/helpers/http.helper.js +134 -0
  83. package/dist/helpers/swagger.helper.d.ts +20 -0
  84. package/dist/helpers/swagger.helper.js +287 -0
  85. package/dist/helpers/totp.helper.d.ts +16 -0
  86. package/dist/helpers/totp.helper.js +30 -0
  87. package/dist/index.d.ts +8 -0
  88. package/dist/index.js +24 -0
  89. package/dist/middlewares/log.middleware.d.ts +9 -0
  90. package/dist/middlewares/log.middleware.js +59 -0
  91. package/package.json +145 -0
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
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.Repository = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const helpers_1 = require("@triproject/helpers");
18
+ const moment_1 = __importDefault(require("moment"));
19
+ const sequelize_1 = require("sequelize");
20
+ const sequelize_typescript_1 = require("sequelize-typescript");
21
+ const logger_1 = require("../logger");
22
+ class Repository {
23
+ logger = new logger_1.AppLogger(this.constructor.name);
24
+ Model;
25
+ db;
26
+ excludeParamsFromFilter = [
27
+ 'attributes',
28
+ 'include',
29
+ 'where',
30
+ 'orWhere',
31
+ 'andWhere',
32
+ 'q',
33
+ 'searchKey',
34
+ 'page',
35
+ 'perPage',
36
+ 'orderBy',
37
+ 'sort',
38
+ 'groupBy',
39
+ 'order',
40
+ ];
41
+ get attributes() {
42
+ return Object.keys(this.Model.getAttributes());
43
+ }
44
+ get attributesTypes() {
45
+ const attributes = this.Model.getAttributes();
46
+ return Object.keys(attributes).map((attr) => ({
47
+ name: attr,
48
+ type: attributes[attr].type,
49
+ }));
50
+ }
51
+ getTrueKey(key) {
52
+ return key.replace('min_', '').replace('max_', '').replace('start_', '').replace('end_', '');
53
+ }
54
+ parsedBetweenData(where, key, value) {
55
+ const col = this.getTrueKey(key);
56
+ const operation = key.startsWith('start_') || key.startsWith('min_') ? 'gte' : 'lte';
57
+ value =
58
+ key.startsWith('_start') || key.startsWith('end_') ? (0, moment_1.default)(value).utc().format('YYYY-MM-DD HH:mm:ss') : value;
59
+ // @ts-ignore
60
+ if (typeof where[col] === 'undefined')
61
+ return { [sequelize_1.Op[operation]]: value };
62
+ // @ts-ignore
63
+ let beforeValue = where[col][sequelize_1.Op[operation == 'gte' ? 'lte' : 'gte']];
64
+ beforeValue =
65
+ key.startsWith('_start') || key.startsWith('end_')
66
+ ? (0, moment_1.default)(beforeValue).utc().format('YYYY-MM-DD HH:mm:ss')
67
+ : beforeValue;
68
+ return {
69
+ [sequelize_1.Op.between]: operation === 'gte' ? [value, beforeValue] : [beforeValue, value],
70
+ };
71
+ }
72
+ mapFilter(filter, cols) {
73
+ const where = {};
74
+ for (const key of Object.keys(filter)) {
75
+ const isSpecialKey = key.includes('$') || key.includes('.');
76
+ if (!cols.includes(this.getTrueKey(key)) && !isSpecialKey)
77
+ continue;
78
+ const value = filter[key];
79
+ const col = this.getTrueKey(key);
80
+ if (value === undefined || value === '')
81
+ continue;
82
+ if (key.startsWith('min_') || key.startsWith('start_') || key.startsWith('max_') || key.startsWith('end_')) {
83
+ // @ts-ignore
84
+ where[col] = this.parsedBetweenData(where, key, value);
85
+ continue;
86
+ }
87
+ if (typeof value === 'string' && value.includes(',')) {
88
+ // @ts-ignore
89
+ where[col] = value.split(',');
90
+ continue;
91
+ }
92
+ if (typeof value === 'object' && !Array.isArray(value)) {
93
+ // @ts-ignore
94
+ where[col] = { ...value };
95
+ continue;
96
+ }
97
+ // @ts-ignore
98
+ where[col] = value;
99
+ }
100
+ return where;
101
+ }
102
+ _getOptions(params) {
103
+ const fields = this.attributes;
104
+ let where = this.mapFilter({ ...params.where, ...(0, helpers_1.omit)(params, this.excludeParamsFromFilter) }, fields);
105
+ if (params.q && params.searchKey) {
106
+ const searchConditions = Array.isArray(params.searchKey)
107
+ ? params.searchKey.map((key) => ({
108
+ [key]: { [sequelize_1.Op.like]: `%${params.q}%` },
109
+ }))
110
+ : [{ [params.searchKey]: { [sequelize_1.Op.like]: `%${params.q}%` } }];
111
+ where = {
112
+ ...where,
113
+ [sequelize_1.Op.and]: [...(params.andWhere || []), { [sequelize_1.Op.or]: [...searchConditions, ...(params.orWhere || [])] }],
114
+ };
115
+ }
116
+ if (params.orWhere || params.andWhere) {
117
+ where = {
118
+ ...where,
119
+ [sequelize_1.Op.and]: [...(params.andWhere || []), { [sequelize_1.Op.or]: params.orWhere || [] }],
120
+ };
121
+ }
122
+ const order = [];
123
+ if (params?.orderBy && fields.includes(params?.orderBy)) {
124
+ order.push([params?.orderBy, params?.sort ?? 'DESC']);
125
+ }
126
+ if (params?.order)
127
+ order.push(...params.order, ['id', 'ASC']);
128
+ const attributes = params.attributes
129
+ ? params.attributes.filter((d) => (typeof d === 'string' ? fields.includes(d) : true))
130
+ : undefined;
131
+ return {
132
+ where,
133
+ order,
134
+ group: params?.groupBy,
135
+ ...(attributes && { attributes }),
136
+ include: params.include,
137
+ };
138
+ }
139
+ async findForPublic(params, mapInto) {
140
+ const options = this._getOptions(params);
141
+ const limit = +(params?.perPage ?? 20);
142
+ const data = await this.findAll({ ...options, limit });
143
+ return data.map((d) => mapInto(d));
144
+ }
145
+ async paginate(params, mapInto) {
146
+ const options = this._getOptions(params);
147
+ const limit = +(params?.perPage ?? 20);
148
+ const page = +(params?.page ?? 1);
149
+ const offset = page > 1 ? limit * (page - 1) : 0;
150
+ const data = await this.findAndCountAll({
151
+ limit,
152
+ offset,
153
+ ...options,
154
+ distinct: true,
155
+ });
156
+ data.count = Array.isArray(data.count) ? data.count.length : data.count;
157
+ const totalPage = Math.ceil(data.count / limit);
158
+ return {
159
+ data: mapInto ? data.rows.map((d) => mapInto(d)) : data.rows,
160
+ timestamp: (0, moment_1.default)().utc().toISOString(true),
161
+ meta: {
162
+ perPage: limit,
163
+ page: page,
164
+ totalPage: totalPage,
165
+ total: data.count,
166
+ prevPage: page > 1 ? page - 1 : null,
167
+ nextPage: page < totalPage ? page + 1 : null,
168
+ },
169
+ };
170
+ }
171
+ async export(params, mapInto) {
172
+ const options = this._getOptions(params);
173
+ const data = await this.findAll(options);
174
+ if (!mapInto)
175
+ return data;
176
+ return data.map((d) => mapInto(d));
177
+ }
178
+ async updateOrCreate(values, whereOptions, options) {
179
+ const data = await this.findOne({ where: whereOptions });
180
+ if (!data) {
181
+ return await this.create(values, options);
182
+ }
183
+ await this.update(data, values, options);
184
+ return data;
185
+ }
186
+ async findAll(options) {
187
+ return await this.Model.findAll(options);
188
+ }
189
+ async findAndCountAll(options) {
190
+ return await this.Model.findAndCountAll(options);
191
+ }
192
+ async findOne(options) {
193
+ return await this.Model.findOne(options);
194
+ }
195
+ async create(values, options) {
196
+ return await this.Model.create(values, options);
197
+ }
198
+ async update(entity, values, options) {
199
+ // @ts-ignore
200
+ if (typeof entity === 'string')
201
+ entity = (await this.findOne({ where: { id: entity }, attributes: ['id'] }));
202
+ if (!entity)
203
+ throw new common_1.NotFoundException();
204
+ return await entity.update(values, { ...options });
205
+ }
206
+ async upsert(values, options) {
207
+ return await this.Model.upsert(values, { ...options });
208
+ }
209
+ async bulkUpdate(values, options) {
210
+ return await this.Model.update(values, { ...options });
211
+ }
212
+ async bulkCreate(values, options) {
213
+ const idAttribute = this.attributesTypes.find((attr) => attr.name === 'id');
214
+ if (idAttribute && idAttribute.type !== 'BIGINT') {
215
+ values = values.map((val) => {
216
+ // @ts-ignore
217
+ if (!val['id'])
218
+ val['id'] = generateId();
219
+ return val;
220
+ });
221
+ }
222
+ return await this.Model.bulkCreate(values, options);
223
+ }
224
+ async destroy(options) {
225
+ return await this.Model.destroy(options);
226
+ }
227
+ async sum(field, options) {
228
+ return await this.Model.sum(field, options);
229
+ }
230
+ async sumField(params, field) {
231
+ const options = this._getOptions(params);
232
+ return await this.sum(field, options);
233
+ }
234
+ async sumCol(params, fieldToSum, expectedField) {
235
+ const options = this._getOptions(params);
236
+ options.attributes = [[(0, sequelize_1.fn)('sum', (0, sequelize_1.col)(fieldToSum)), expectedField]];
237
+ const result = await this.Model.findAll(options);
238
+ return result.reduce((total, row) => {
239
+ const value = row.get(expectedField);
240
+ return total + parseFloat(String(value) || '0');
241
+ }, 0);
242
+ }
243
+ async count(options) {
244
+ return await this.Model.count(options);
245
+ }
246
+ async filteredFindAll(params) {
247
+ const options = this._getOptions(params);
248
+ return await this.Model.findAll(options);
249
+ }
250
+ }
251
+ exports.Repository = Repository;
252
+ __decorate([
253
+ (0, common_1.Inject)(sequelize_typescript_1.Sequelize),
254
+ __metadata("design:type", sequelize_typescript_1.Sequelize)
255
+ ], Repository.prototype, "db", void 0);
@@ -0,0 +1,8 @@
1
+ export declare class Encryption {
2
+ private keyEncoding;
3
+ private encoding;
4
+ private algorithm;
5
+ private _generateEncryptionIV;
6
+ encrypt(text: string): string;
7
+ decrypt(encryptedData: string): string;
8
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.Encryption = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const crypto_1 = require("crypto");
12
+ const config_1 = require("../../config");
13
+ const exception_helper_1 = require("../../helpers/exception.helper");
14
+ let Encryption = class Encryption {
15
+ keyEncoding = 'hex';
16
+ encoding = 'hex';
17
+ algorithm = 'aes-256-gcm';
18
+ _generateEncryptionIV() {
19
+ return (0, crypto_1.randomBytes)(16).toString(this.keyEncoding);
20
+ }
21
+ encrypt(text) {
22
+ if (!config_1.ENCRYPTION_KEY)
23
+ throw new exception_helper_1.AppUnprocessableEntityException('ENCRYPTION_KEY is not defined');
24
+ const iv = this._generateEncryptionIV();
25
+ const cipher = (0, crypto_1.createCipheriv)(this.algorithm, Buffer.from(config_1.ENCRYPTION_KEY, this.keyEncoding), Buffer.from(iv, this.keyEncoding));
26
+ const encrypted = cipher.update(text, 'utf8', this.encoding) + cipher.final(this.encoding);
27
+ const tag = cipher.getAuthTag();
28
+ const data = [iv, tag.toString(this.encoding), encrypted].join(';;');
29
+ return Buffer.from(data).toString('base64');
30
+ }
31
+ decrypt(encryptedData) {
32
+ if (!config_1.ENCRYPTION_KEY)
33
+ throw new exception_helper_1.AppUnprocessableEntityException('ENCRYPTION_KEY is not defined');
34
+ try {
35
+ const bufferData = Buffer.from(encryptedData, 'base64').toString();
36
+ const [iv, tag, encrypted] = bufferData.split(';;');
37
+ const decipher = (0, crypto_1.createDecipheriv)(this.algorithm, Buffer.from(config_1.ENCRYPTION_KEY, this.keyEncoding), Buffer.from(iv, this.keyEncoding));
38
+ decipher.setAuthTag(Buffer.from(tag, this.encoding));
39
+ const decrypted = decipher.update(encrypted, this.encoding, 'utf8') + decipher.final('utf8');
40
+ return decrypted;
41
+ }
42
+ catch (error) {
43
+ throw new exception_helper_1.AppInternalServerErrorException('Error while decrypting data');
44
+ }
45
+ }
46
+ };
47
+ exports.Encryption = Encryption;
48
+ exports.Encryption = Encryption = __decorate([
49
+ (0, common_1.Injectable)()
50
+ ], Encryption);
@@ -0,0 +1,2 @@
1
+ export declare class EncryptionModule {
2
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.EncryptionModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const encryption_1 = require("./encryption");
12
+ const jwt_1 = require("./jwt");
13
+ const password_hash_1 = require("./password-hash");
14
+ const snap_signature_1 = require("./snap.signature");
15
+ let EncryptionModule = class EncryptionModule {
16
+ };
17
+ exports.EncryptionModule = EncryptionModule;
18
+ exports.EncryptionModule = EncryptionModule = __decorate([
19
+ (0, common_1.Global)(),
20
+ (0, common_1.Module)({
21
+ providers: [password_hash_1.PasswordHash, jwt_1.Jwt, encryption_1.Encryption, snap_signature_1.SnapSignature],
22
+ exports: [password_hash_1.PasswordHash, jwt_1.Jwt, encryption_1.Encryption, snap_signature_1.SnapSignature],
23
+ })
24
+ ], EncryptionModule);
@@ -0,0 +1,3 @@
1
+ export * from './encryption.module';
2
+ export * from './jwt';
3
+ export * from './password-hash';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./encryption.module"), exports);
18
+ __exportStar(require("./jwt"), exports);
19
+ __exportStar(require("./password-hash"), exports);
@@ -0,0 +1,6 @@
1
+ import { Algorithm } from 'jsonwebtoken';
2
+ export declare class Jwt {
3
+ protected jwtAlgorithms: Algorithm[];
4
+ verify<T>(token: string): T;
5
+ sign(data: object, expiresIn?: number): string;
6
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.Jwt = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const jsonwebtoken_1 = require("jsonwebtoken");
12
+ const config_1 = require("../../config");
13
+ const exception_helper_1 = require("../../helpers/exception.helper");
14
+ let Jwt = class Jwt {
15
+ jwtAlgorithms = ['RS512'];
16
+ verify(token) {
17
+ try {
18
+ return (0, jsonwebtoken_1.verify)(token, config_1.JWT_PUBLIC_KEY, {
19
+ algorithms: this.jwtAlgorithms,
20
+ });
21
+ }
22
+ catch (error) {
23
+ throw new exception_helper_1.AppUnprocessableEntityException('Invalid or expired JWT token.');
24
+ }
25
+ }
26
+ sign(data, expiresIn = 15_000) {
27
+ try {
28
+ const key = typeof config_1.JWT_PRIVATE_KEY === 'string' && config_1.JWT_PRIVATE_KEY
29
+ ? Buffer.from(config_1.JWT_PRIVATE_KEY)
30
+ : { key: config_1.JWT_PRIVATE_KEY, passphrase: '' };
31
+ return (0, jsonwebtoken_1.sign)({ ...data }, key, {
32
+ algorithm: this.jwtAlgorithms[0],
33
+ expiresIn,
34
+ allowInsecureKeySizes: false,
35
+ encoding: 'utf-8',
36
+ });
37
+ }
38
+ catch (error) {
39
+ throw new exception_helper_1.AppUnprocessableEntityException('Failed to sign JWT token.');
40
+ }
41
+ }
42
+ };
43
+ exports.Jwt = Jwt;
44
+ exports.Jwt = Jwt = __decorate([
45
+ (0, common_1.Injectable)()
46
+ ], Jwt);
@@ -0,0 +1,11 @@
1
+ export declare class PasswordHash {
2
+ private DIGEST;
3
+ private ITERATIONS;
4
+ private KEYLEN;
5
+ private SALT_LENGTH;
6
+ private HASH_ENCODING;
7
+ private HASH_DELIMITER;
8
+ private _hash;
9
+ sign(password: string): string;
10
+ verify(password: string, passwordHash: string): boolean;
11
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.PasswordHash = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const crypto_1 = require("crypto");
12
+ const config_1 = require("../../config");
13
+ let PasswordHash = class PasswordHash {
14
+ DIGEST = 'sha512';
15
+ ITERATIONS = 100000;
16
+ KEYLEN = 64;
17
+ SALT_LENGTH = 8;
18
+ HASH_ENCODING = 'base64';
19
+ HASH_DELIMITER = '.';
20
+ _hash(password, salt) {
21
+ return (0, crypto_1.pbkdf2Sync)(config_1.PASSWORD_HASH_SECRET + password, salt, this.ITERATIONS, this.KEYLEN, this.DIGEST);
22
+ }
23
+ sign(password) {
24
+ const salt = (0, crypto_1.randomBytes)(this.SALT_LENGTH).toString('hex');
25
+ const key = this._hash(password, salt).toString(this.HASH_ENCODING);
26
+ return `$${salt}${this.HASH_DELIMITER}$${key}`;
27
+ }
28
+ verify(password, passwordHash) {
29
+ const [salt, key] = passwordHash.replace('$', '').split(this.HASH_DELIMITER);
30
+ const derivedKey = this._hash(password, salt);
31
+ const storedHashBuffer = Buffer.from(key, this.HASH_ENCODING);
32
+ return (0, crypto_1.timingSafeEqual)(storedHashBuffer, derivedKey);
33
+ }
34
+ };
35
+ exports.PasswordHash = PasswordHash;
36
+ exports.PasswordHash = PasswordHash = __decorate([
37
+ (0, common_1.Injectable)()
38
+ ], PasswordHash);
@@ -0,0 +1,32 @@
1
+ import { BinaryToTextEncoding } from 'crypto';
2
+ import { Request } from 'express';
3
+ export interface SnapBodySignatureParams {
4
+ url: string;
5
+ body: object;
6
+ timestamp: string;
7
+ method?: 'POST' | 'GET';
8
+ accessToken?: string;
9
+ }
10
+ export interface VerifyGetTokenSignature {
11
+ client_id: string;
12
+ signature?: string;
13
+ timestamp: string;
14
+ }
15
+ export declare class SnapSignature {
16
+ sha256Encoding: BinaryToTextEncoding;
17
+ sha512Encoding: BinaryToTextEncoding;
18
+ minifiedObjectEncoding: BinaryToTextEncoding;
19
+ private _signSHA256;
20
+ private _verifySHA256WithRSA;
21
+ private _verifySHA256;
22
+ private _signSHA512;
23
+ private _verifySHA512;
24
+ private _reqBodySignatureString;
25
+ private _minifyParams;
26
+ signBodySignature(params: SnapBodySignatureParams, secret: string): string;
27
+ private _verifyBodySignature;
28
+ signAccessTokenSignature(params: VerifyGetTokenSignature, secretKey: string): string;
29
+ private _verifyAccessTokenSignature;
30
+ middleware(secret: string, req: Request): void;
31
+ }
32
+ export declare const snapSignature: SnapSignature;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.snapSignature = exports.SnapSignature = void 0;
4
+ const helpers_1 = require("@triproject/helpers");
5
+ const crypto_1 = require("crypto");
6
+ class SnapSignature {
7
+ sha256Encoding = 'base64';
8
+ sha512Encoding = 'hex';
9
+ minifiedObjectEncoding = 'hex';
10
+ _signSHA256(stringToSign, privateKey) {
11
+ const signer = (0, crypto_1.createSign)('SHA256');
12
+ signer.update(stringToSign);
13
+ return signer.sign((0, helpers_1.parsedKeyPair)(privateKey), this.sha256Encoding);
14
+ }
15
+ _verifySHA256WithRSA(stringToVerify, signature, publicKey) {
16
+ const verifier = (0, crypto_1.createVerify)('SHA256');
17
+ verifier.update(stringToVerify);
18
+ return verifier.verify({
19
+ key: (0, helpers_1.parsedKeyPair)(publicKey),
20
+ padding: crypto_1.constants.RSA_PKCS1_PSS_PADDING,
21
+ saltLength: 32,
22
+ }, signature, this.sha256Encoding);
23
+ }
24
+ _verifySHA256(stringToVerify, signature, publicKey) {
25
+ try {
26
+ const verifier = (0, crypto_1.createVerify)('SHA256');
27
+ verifier.update(stringToVerify);
28
+ const isValid = verifier.verify((0, helpers_1.parsedKeyPair)(publicKey), signature, this.sha256Encoding);
29
+ if (isValid)
30
+ return true;
31
+ return this._verifySHA256WithRSA(stringToVerify, signature, publicKey);
32
+ }
33
+ catch (error) {
34
+ return false;
35
+ }
36
+ }
37
+ _signSHA512(stringToSign, secret) {
38
+ try {
39
+ const hmac = (0, crypto_1.createHmac)('sha512', secret);
40
+ hmac.update(stringToSign);
41
+ return hmac.digest(this.sha256Encoding);
42
+ }
43
+ catch (error) {
44
+ throw new Error('Error while signing data');
45
+ }
46
+ }
47
+ _verifySHA512(stringToVerify, signature, secret) {
48
+ const hmac = (0, crypto_1.createHmac)('sha512', secret);
49
+ hmac.update(stringToVerify);
50
+ const calculatedSignature = hmac.digest(this.sha512Encoding);
51
+ return calculatedSignature === signature;
52
+ }
53
+ _reqBodySignatureString(params) {
54
+ const stringToSign = [
55
+ params?.method ?? 'POST',
56
+ params.url,
57
+ params.accessToken,
58
+ this._minifyParams(params.body),
59
+ params.timestamp,
60
+ ].filter((d) => d);
61
+ return stringToSign.join(':');
62
+ }
63
+ _minifyParams(object) {
64
+ const minifiedRequestBody = typeof object === 'object' ? JSON.stringify(object) : object?.toString() ?? '';
65
+ const sha256Hash = (0, crypto_1.createHash)('SHA256');
66
+ sha256Hash.update(minifiedRequestBody);
67
+ const sha256HashString = sha256Hash.digest(this.minifiedObjectEncoding);
68
+ return sha256HashString.toLowerCase();
69
+ }
70
+ signBodySignature(params, secret) {
71
+ return this._signSHA512(this._reqBodySignatureString(params), secret);
72
+ }
73
+ _verifyBodySignature(params, signature, secret) {
74
+ return this._verifySHA512(this._reqBodySignatureString(params), signature, secret);
75
+ }
76
+ signAccessTokenSignature(params, secretKey) {
77
+ const { client_id, timestamp } = params;
78
+ const stringToSing = [client_id, timestamp];
79
+ return this._signSHA256(stringToSing.join('|'), secretKey);
80
+ }
81
+ _verifyAccessTokenSignature(params, publicKey) {
82
+ const { client_id, timestamp, signature } = params;
83
+ if (!signature)
84
+ return false;
85
+ const stringToSing = [client_id, timestamp];
86
+ return this._verifySHA256(stringToSing.join('|'), signature, publicKey);
87
+ }
88
+ middleware(secret, req) {
89
+ if (!['POST', 'GET'].includes(req.method))
90
+ throw new Error('Invalid request method');
91
+ if (req.path?.includes('/access-token/b2b')) {
92
+ const { 'client-id': client_id, 'x-timestamp': timestamp, 'x-signature': signature } = req.headers;
93
+ const isValid = this._verifyAccessTokenSignature({ client_id, timestamp, signature }, secret);
94
+ if (!isValid)
95
+ throw new Error('Invalid signature');
96
+ }
97
+ const { 'x-timestamp': timestamp, 'x-signature': signature, accessToken } = req.headers;
98
+ const isValid = this._verifyBodySignature({
99
+ url: req.path,
100
+ body: req.body,
101
+ timestamp,
102
+ method: req.method,
103
+ accessToken: (accessToken ?? '')?.replace('Bearer ', ''),
104
+ }, signature, secret);
105
+ if (!isValid)
106
+ throw new Error('Invalid signature');
107
+ }
108
+ }
109
+ exports.SnapSignature = SnapSignature;
110
+ exports.snapSignature = new SnapSignature();
@@ -0,0 +1,23 @@
1
+ import { ConsoleLogger } from '@nestjs/common';
2
+ type LogMessageType = string | object | Error | undefined | null | number | boolean;
3
+ export declare class AppLogger extends ConsoleLogger {
4
+ protected readonly context: string;
5
+ private LOG_STACKS;
6
+ constructor(context?: string);
7
+ private _notifyError;
8
+ private excludeContexts;
9
+ private _excludeContext;
10
+ private _sanitizePolicyData;
11
+ private _formatBgLevel;
12
+ private _formatException;
13
+ private _parseMessage;
14
+ private _mapLog;
15
+ private _formatConsoleError;
16
+ private _console;
17
+ log(...args: LogMessageType[]): void;
18
+ error(...args: LogMessageType[]): void;
19
+ fatal(...args: LogMessageType[]): void;
20
+ warn(...args: LogMessageType[]): void;
21
+ debug(...args: LogMessageType[]): void;
22
+ }
23
+ export {};