@xfilecom/core-sdk 1.3.23

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 (96) hide show
  1. package/README.md +664 -0
  2. package/dist/core.module.d.ts +39 -0
  3. package/dist/core.module.js +188 -0
  4. package/dist/core.module.js.map +1 -0
  5. package/dist/database/database.constants.d.ts +2 -0
  6. package/dist/database/database.constants.js +6 -0
  7. package/dist/database/database.constants.js.map +1 -0
  8. package/dist/database/database.module.d.ts +19 -0
  9. package/dist/database/database.module.js +56 -0
  10. package/dist/database/database.module.js.map +1 -0
  11. package/dist/database/database.query.d.ts +103 -0
  12. package/dist/database/database.query.example.d.ts +36 -0
  13. package/dist/database/database.query.example.js +148 -0
  14. package/dist/database/database.query.example.js.map +1 -0
  15. package/dist/database/database.query.js +369 -0
  16. package/dist/database/database.query.js.map +1 -0
  17. package/dist/database/database.service.d.ts +18 -0
  18. package/dist/database/database.service.js +110 -0
  19. package/dist/database/database.service.js.map +1 -0
  20. package/dist/database/example-usage.d.ts +0 -0
  21. package/dist/database/example-usage.js +1 -0
  22. package/dist/database/example-usage.js.map +1 -0
  23. package/dist/decorators/public.decorator.d.ts +2 -0
  24. package/dist/decorators/public.decorator.js +8 -0
  25. package/dist/decorators/public.decorator.js.map +1 -0
  26. package/dist/decorators/roles.decorator.d.ts +2 -0
  27. package/dist/decorators/roles.decorator.js +8 -0
  28. package/dist/decorators/roles.decorator.js.map +1 -0
  29. package/dist/decorators/user.decorator.d.ts +7 -0
  30. package/dist/decorators/user.decorator.js +10 -0
  31. package/dist/decorators/user.decorator.js.map +1 -0
  32. package/dist/filters/exception.filter.d.ts +36 -0
  33. package/dist/filters/exception.filter.js +201 -0
  34. package/dist/filters/exception.filter.js.map +1 -0
  35. package/dist/guards/jwt-auth.guard.d.ts +14 -0
  36. package/dist/guards/jwt-auth.guard.js +103 -0
  37. package/dist/guards/jwt-auth.guard.js.map +1 -0
  38. package/dist/guards/roles.guard.d.ts +7 -0
  39. package/dist/guards/roles.guard.js +47 -0
  40. package/dist/guards/roles.guard.js.map +1 -0
  41. package/dist/index.d.ts +29 -0
  42. package/dist/index.js +91 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/interceptors/database-check.interceptor.d.ts +12 -0
  45. package/dist/interceptors/database-check.interceptor.js +60 -0
  46. package/dist/interceptors/database-check.interceptor.js.map +1 -0
  47. package/dist/interceptors/error-handling.interceptor.d.ts +8 -0
  48. package/dist/interceptors/error-handling.interceptor.js +33 -0
  49. package/dist/interceptors/error-handling.interceptor.js.map +1 -0
  50. package/dist/interceptors/logging.interceptor.d.ts +21 -0
  51. package/dist/interceptors/logging.interceptor.js +167 -0
  52. package/dist/interceptors/logging.interceptor.js.map +1 -0
  53. package/dist/interceptors/response-transform.interceptor.d.ts +5 -0
  54. package/dist/interceptors/response-transform.interceptor.js +30 -0
  55. package/dist/interceptors/response-transform.interceptor.js.map +1 -0
  56. package/dist/utils/auth.helpers.d.ts +19 -0
  57. package/dist/utils/auth.helpers.js +77 -0
  58. package/dist/utils/auth.helpers.js.map +1 -0
  59. package/dist/utils/config-loader.utils.d.ts +22 -0
  60. package/dist/utils/config-loader.utils.js +77 -0
  61. package/dist/utils/config-loader.utils.js.map +1 -0
  62. package/dist/utils/config.validator.d.ts +13 -0
  63. package/dist/utils/config.validator.js +82 -0
  64. package/dist/utils/config.validator.js.map +1 -0
  65. package/dist/utils/controller.helpers.d.ts +58 -0
  66. package/dist/utils/controller.helpers.js +104 -0
  67. package/dist/utils/controller.helpers.js.map +1 -0
  68. package/dist/utils/crypto.utils.d.ts +12 -0
  69. package/dist/utils/crypto.utils.js +53 -0
  70. package/dist/utils/crypto.utils.js.map +1 -0
  71. package/dist/utils/email-hash.utils.d.ts +7 -0
  72. package/dist/utils/email-hash.utils.js +42 -0
  73. package/dist/utils/email-hash.utils.js.map +1 -0
  74. package/dist/utils/env.utils.d.ts +8 -0
  75. package/dist/utils/env.utils.js +27 -0
  76. package/dist/utils/env.utils.js.map +1 -0
  77. package/dist/utils/error.utils.d.ts +6 -0
  78. package/dist/utils/error.utils.js +65 -0
  79. package/dist/utils/error.utils.js.map +1 -0
  80. package/dist/utils/hash-verification.utils.d.ts +35 -0
  81. package/dist/utils/hash-verification.utils.js +133 -0
  82. package/dist/utils/hash-verification.utils.js.map +1 -0
  83. package/dist/utils/logger.helpers.d.ts +71 -0
  84. package/dist/utils/logger.helpers.js +293 -0
  85. package/dist/utils/logger.helpers.js.map +1 -0
  86. package/dist/utils/logging.config.d.ts +6 -0
  87. package/dist/utils/logging.config.js +42 -0
  88. package/dist/utils/logging.config.js.map +1 -0
  89. package/dist/utils/service.helpers.d.ts +22 -0
  90. package/dist/utils/service.helpers.js +73 -0
  91. package/dist/utils/service.helpers.js.map +1 -0
  92. package/dist/utils/yaml-config.loader.d.ts +15 -0
  93. package/dist/utils/yaml-config.loader.js +219 -0
  94. package/dist/utils/yaml-config.loader.js.map +1 -0
  95. package/package.json +47 -0
  96. package/scripts/publish-to-gitlab.mjs +209 -0
@@ -0,0 +1,58 @@
1
+ import { Request } from 'express';
2
+ export interface PaginationMeta {
3
+ total: number;
4
+ page: number;
5
+ limit: number;
6
+ totalPages: number;
7
+ hasNext: boolean;
8
+ hasPrev: boolean;
9
+ }
10
+ export interface ResponseMeta {
11
+ message?: string | object;
12
+ pagination?: PaginationMeta;
13
+ }
14
+ export declare class CommonResponseDto {
15
+ code: number;
16
+ data: any[];
17
+ meta?: ResponseMeta;
18
+ error: null | {
19
+ message: string | object;
20
+ };
21
+ constructor(data?: any[], meta?: ResponseMeta);
22
+ }
23
+ export declare class CommonErrorDto {
24
+ code: number;
25
+ data: any[];
26
+ error: {
27
+ message: string | object;
28
+ } | null;
29
+ constructor(code: number, message: string | object, data?: any[]);
30
+ }
31
+ export interface AuditContext {
32
+ userId?: number;
33
+ userEmail?: string;
34
+ userRole?: string;
35
+ ipAddress?: string;
36
+ userAgent?: string;
37
+ }
38
+ export interface PaginationParams {
39
+ page: number;
40
+ limit: number;
41
+ offset: number;
42
+ }
43
+ export interface SortParams {
44
+ field: string;
45
+ order: 'asc' | 'desc';
46
+ }
47
+ export declare class ControllerHelpers {
48
+ extractAuditContext(req: Request & {
49
+ user?: any;
50
+ }): AuditContext;
51
+ success<T>(data: T | T[], message?: string | object, pagination?: PaginationMeta): CommonResponseDto;
52
+ error(code: number, message: string | object, data?: any[]): CommonErrorDto;
53
+ parsePagination(query: any): PaginationParams;
54
+ parseSort(query: any, defaultField?: string): SortParams;
55
+ parseFilters(query: any): Record<string, any>;
56
+ checkService<T>(service: T | undefined | null, serviceName: string): T;
57
+ private getErrorCode;
58
+ }
@@ -0,0 +1,104 @@
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.ControllerHelpers = exports.CommonErrorDto = exports.CommonResponseDto = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ class CommonResponseDto {
12
+ constructor(data = [], meta) {
13
+ this.code = 0;
14
+ this.data = data;
15
+ this.meta = meta;
16
+ this.error = null;
17
+ }
18
+ }
19
+ exports.CommonResponseDto = CommonResponseDto;
20
+ class CommonErrorDto {
21
+ constructor(code, message, data = []) {
22
+ this.code = code;
23
+ this.data = data;
24
+ this.error = {
25
+ message: typeof message === 'string' ? message : message,
26
+ };
27
+ }
28
+ }
29
+ exports.CommonErrorDto = CommonErrorDto;
30
+ let ControllerHelpers = class ControllerHelpers {
31
+ extractAuditContext(req) {
32
+ const user = req.user || {};
33
+ return {
34
+ userId: user.id || user.sub,
35
+ userEmail: user.email,
36
+ userRole: user.role || user.adminRole,
37
+ ipAddress: req.ip ||
38
+ req.headers['x-forwarded-for'] ||
39
+ req.connection?.remoteAddress,
40
+ userAgent: req.headers['user-agent'],
41
+ };
42
+ }
43
+ success(data, message, pagination) {
44
+ const dataArray = Array.isArray(data) ? data : [data];
45
+ const meta = (message || pagination) ? {
46
+ ...(message && { message }),
47
+ ...(pagination && { pagination }),
48
+ } : undefined;
49
+ return new CommonResponseDto(dataArray, meta);
50
+ }
51
+ error(code, message, data = []) {
52
+ const errorCode = code === 0 ? 500 : code;
53
+ return new CommonErrorDto(errorCode, message, data);
54
+ }
55
+ parsePagination(query) {
56
+ const page = Math.max(1, parseInt(query.page || '1', 10));
57
+ const limit = Math.min(100, Math.max(1, parseInt(query.limit || '10', 10)));
58
+ return {
59
+ page,
60
+ limit,
61
+ offset: (page - 1) * limit,
62
+ };
63
+ }
64
+ parseSort(query, defaultField = 'id') {
65
+ const sort = query.sort || defaultField;
66
+ const isDesc = sort.startsWith('-');
67
+ const field = isDesc ? sort.substring(1) : sort;
68
+ const order = isDesc ? 'desc' : 'asc';
69
+ return { field, order };
70
+ }
71
+ parseFilters(query) {
72
+ const filters = {};
73
+ Object.keys(query).forEach(key => {
74
+ if (!['page', 'limit', 'sort', 'offset'].includes(key)) {
75
+ filters[key] = query[key];
76
+ }
77
+ });
78
+ return filters;
79
+ }
80
+ checkService(service, serviceName) {
81
+ if (!service) {
82
+ throw new Error(`${serviceName} is not available`);
83
+ }
84
+ return service;
85
+ }
86
+ getErrorCode(statusCode) {
87
+ const codes = {
88
+ 400: 'BAD_REQUEST',
89
+ 401: 'UNAUTHORIZED',
90
+ 403: 'FORBIDDEN',
91
+ 404: 'NOT_FOUND',
92
+ 409: 'CONFLICT',
93
+ 422: 'UNPROCESSABLE_ENTITY',
94
+ 500: 'INTERNAL_SERVER_ERROR',
95
+ 503: 'SERVICE_UNAVAILABLE',
96
+ };
97
+ return codes[statusCode] || 'UNKNOWN_ERROR';
98
+ }
99
+ };
100
+ exports.ControllerHelpers = ControllerHelpers;
101
+ exports.ControllerHelpers = ControllerHelpers = __decorate([
102
+ (0, common_1.Injectable)()
103
+ ], ControllerHelpers);
104
+ //# sourceMappingURL=controller.helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.helpers.js","sourceRoot":"","sources":["../../src/utils/controller.helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare const PBKDF2_DEFAULT_ITERATIONS = 100000;
2
+ export declare const PBKDF2_DEFAULT_KEYLEN = 64;
3
+ export declare const PBKDF2_DEFAULT_DIGEST = "sha512";
4
+ export declare const PBKDF2_SALT_BYTES = 32;
5
+ export interface Pbkdf2Options {
6
+ iterations?: number;
7
+ keylen?: number;
8
+ digest?: string;
9
+ }
10
+ export declare function pbkdf2HashPassword(password: string, salt?: Buffer | string, options?: Pbkdf2Options): string;
11
+ export declare function pbkdf2VerifyPassword(plainPassword: string, stored: string, options?: Pbkdf2Options): boolean;
12
+ export declare function deriveKeySha256(secret: string): Buffer;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PBKDF2_SALT_BYTES = exports.PBKDF2_DEFAULT_DIGEST = exports.PBKDF2_DEFAULT_KEYLEN = exports.PBKDF2_DEFAULT_ITERATIONS = void 0;
4
+ exports.pbkdf2HashPassword = pbkdf2HashPassword;
5
+ exports.pbkdf2VerifyPassword = pbkdf2VerifyPassword;
6
+ exports.deriveKeySha256 = deriveKeySha256;
7
+ const crypto = require("crypto");
8
+ exports.PBKDF2_DEFAULT_ITERATIONS = 100_000;
9
+ exports.PBKDF2_DEFAULT_KEYLEN = 64;
10
+ exports.PBKDF2_DEFAULT_DIGEST = 'sha512';
11
+ exports.PBKDF2_SALT_BYTES = 32;
12
+ function pbkdf2HashPassword(password, salt, options = {}) {
13
+ if (password == null || typeof password !== 'string') {
14
+ throw new Error('password must be a non-empty string');
15
+ }
16
+ const iterations = options.iterations ?? exports.PBKDF2_DEFAULT_ITERATIONS;
17
+ const keylen = options.keylen ?? exports.PBKDF2_DEFAULT_KEYLEN;
18
+ const digest = options.digest ?? exports.PBKDF2_DEFAULT_DIGEST;
19
+ const saltBuf = salt instanceof Buffer
20
+ ? salt
21
+ : typeof salt === 'string' && salt.length > 0
22
+ ? Buffer.from(salt, 'hex')
23
+ : crypto.randomBytes(exports.PBKDF2_SALT_BYTES);
24
+ const hash = crypto.pbkdf2Sync(password, saltBuf, iterations, keylen, digest);
25
+ return `${saltBuf.toString('hex')}:${hash.toString('hex')}`;
26
+ }
27
+ function pbkdf2VerifyPassword(plainPassword, stored, options = {}) {
28
+ if (!stored || plainPassword == null)
29
+ return false;
30
+ const colonIndex = stored.indexOf(':');
31
+ if (colonIndex <= 0 || colonIndex === stored.length - 1)
32
+ return false;
33
+ try {
34
+ const saltHex = stored.slice(0, colonIndex);
35
+ const hashHex = stored.slice(colonIndex + 1);
36
+ const salt = Buffer.from(saltHex, 'hex');
37
+ const iterations = options.iterations ?? exports.PBKDF2_DEFAULT_ITERATIONS;
38
+ const keylen = options.keylen ?? exports.PBKDF2_DEFAULT_KEYLEN;
39
+ const digest = options.digest ?? exports.PBKDF2_DEFAULT_DIGEST;
40
+ const computed = crypto.pbkdf2Sync(plainPassword, salt, iterations, keylen, digest);
41
+ const storedBuf = Buffer.from(hashHex, 'hex');
42
+ if (computed.length !== storedBuf.length)
43
+ return false;
44
+ return crypto.timingSafeEqual(computed, storedBuf);
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ function deriveKeySha256(secret) {
51
+ return crypto.createHash('sha256').update(secret).digest();
52
+ }
53
+ //# sourceMappingURL=crypto.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.utils.js","sourceRoot":"","sources":["../../src/utils/crypto.utils.ts"],"names":[],"mappings":";;;AAkBA,gDAqBC;AAMD,oDAuBC;AAKD,0CAEC;AA3ED,iCAAiC;AAGpB,QAAA,yBAAyB,GAAG,OAAO,CAAC;AACpC,QAAA,qBAAqB,GAAG,EAAE,CAAC;AAC3B,QAAA,qBAAqB,GAAG,QAAQ,CAAC;AACjC,QAAA,iBAAiB,GAAG,EAAE,CAAC;AAYpC,SAAgB,kBAAkB,CAChC,QAAgB,EAChB,IAAsB,EACtB,UAAyB,EAAE;IAE3B,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iCAAyB,CAAC;IACnE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,6BAAqB,CAAC;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,6BAAqB,CAAC;IAEvD,MAAM,OAAO,GACX,IAAI,YAAY,MAAM;QACpB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAC3C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC;YAC1B,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,yBAAiB,CAAC,CAAC;IAE9C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9E,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9D,CAAC;AAMD,SAAgB,oBAAoB,CAClC,aAAqB,EACrB,MAAc,EACd,UAAyB,EAAE;IAE3B,IAAI,CAAC,MAAM,IAAI,aAAa,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IACnD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,UAAU,IAAI,CAAC,IAAI,UAAU,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACzC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iCAAyB,CAAC;QACnE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,6BAAqB,CAAC;QACvD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,6BAAqB,CAAC;QAEvD,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACpF,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACvD,OAAO,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAKD,SAAgB,eAAe,CAAC,MAAc;IAC5C,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface EmailHashConfig {
2
+ algorithm?: string;
3
+ secret?: string;
4
+ encoding?: 'hex' | 'base64';
5
+ }
6
+ export declare function hashEmail(email: string, config?: EmailHashConfig | null): string;
7
+ export declare function compareEmail(plainEmail: string, storedHash: string, config?: EmailHashConfig | null): boolean;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hashEmail = hashEmail;
4
+ exports.compareEmail = compareEmail;
5
+ const crypto = require("crypto");
6
+ const DEFAULT_ALGORITHM = 'sha256';
7
+ const DEFAULT_ENCODING = 'hex';
8
+ function resolveSecret(config) {
9
+ const secret = config?.secret ?? process.env.EMAIL_HASH_SECRET;
10
+ if (!secret || typeof secret !== 'string') {
11
+ throw new Error('Email hash secret is required. Set email.hash.secret in application.yml or EMAIL_HASH_SECRET env.');
12
+ }
13
+ return secret;
14
+ }
15
+ function hashEmail(email, config) {
16
+ if (!email || typeof email !== 'string') {
17
+ throw new Error('email must be a non-empty string');
18
+ }
19
+ const secret = resolveSecret(config);
20
+ const algorithm = config?.algorithm ?? DEFAULT_ALGORITHM;
21
+ const encoding = config?.encoding ?? DEFAULT_ENCODING;
22
+ const hmac = crypto.createHmac(algorithm, secret);
23
+ hmac.update(email.trim().toLowerCase());
24
+ return hmac.digest(encoding);
25
+ }
26
+ function compareEmail(plainEmail, storedHash, config) {
27
+ if (!storedHash || !plainEmail)
28
+ return false;
29
+ try {
30
+ const computed = hashEmail(plainEmail, config);
31
+ const encoding = config?.encoding ?? DEFAULT_ENCODING;
32
+ const a = Buffer.from(computed, encoding);
33
+ const b = Buffer.from(storedHash, encoding);
34
+ if (a.length !== b.length)
35
+ return false;
36
+ return crypto.timingSafeEqual(a, b);
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ }
42
+ //# sourceMappingURL=email-hash.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-hash.utils.js","sourceRoot":"","sources":["../../src/utils/email-hash.utils.ts"],"names":[],"mappings":";;AAqDA,8BAUC;AAoBD,oCAgBC;AAnGD,iCAAiC;AAuBjC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AACnC,MAAM,gBAAgB,GAAqB,KAAK,CAAC;AAEjD,SAAS,aAAa,CAAC,MAA+B;IACpD,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC/D,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,mGAAmG,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAmBD,SAAgB,SAAS,CAAC,KAAa,EAAE,MAA+B;IACtE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,iBAAiB,CAAC;IACzD,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,gBAAgB,CAAC;IACtD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAoBD,SAAgB,YAAY,CAC1B,UAAkB,EAClB,UAAkB,EAClB,MAA+B;IAE/B,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,gBAAgB,CAAC;QACtD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACxC,OAAO,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type AppEnv = 'development' | 'staging' | 'production';
2
+ export declare const getAppEnv: () => AppEnv;
3
+ export declare function isDevelopment(): boolean;
4
+ export declare function isProduction(): boolean;
5
+ export declare function isStaging(): boolean;
6
+ export declare const currentAppEnv: AppEnv;
7
+ export declare const isDev: boolean;
8
+ export declare const isProd: boolean;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isProd = exports.isDev = exports.currentAppEnv = exports.getAppEnv = void 0;
4
+ exports.isDevelopment = isDevelopment;
5
+ exports.isProduction = isProduction;
6
+ exports.isStaging = isStaging;
7
+ const raw = (typeof process !== 'undefined' && (process.env.APP_ENV ?? process.env.NODE_ENV)) || 'development';
8
+ const normalized = raw.toLowerCase();
9
+ const getAppEnv = () => normalized === 'production' || normalized === 'prod'
10
+ ? 'production'
11
+ : normalized === 'staging' || normalized === 'stage'
12
+ ? 'staging'
13
+ : 'development';
14
+ exports.getAppEnv = getAppEnv;
15
+ function isDevelopment() {
16
+ return (0, exports.getAppEnv)() === 'development';
17
+ }
18
+ function isProduction() {
19
+ return (0, exports.getAppEnv)() === 'production';
20
+ }
21
+ function isStaging() {
22
+ return (0, exports.getAppEnv)() === 'staging';
23
+ }
24
+ exports.currentAppEnv = (0, exports.getAppEnv)();
25
+ exports.isDev = exports.currentAppEnv === 'development';
26
+ exports.isProd = exports.currentAppEnv === 'production';
27
+ //# sourceMappingURL=env.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.utils.js","sourceRoot":"","sources":["../../src/utils/env.utils.ts"],"names":[],"mappings":";;;AAmBA,sCAEC;AAGD,oCAEC;AAGD,8BAEC;AAzBD,MAAM,GAAG,GACP,CAAC,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,aAAa,CAAC;AACrG,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;AAG9B,MAAM,SAAS,GAAG,GAAW,EAAE,CACpC,UAAU,KAAK,YAAY,IAAI,UAAU,KAAK,MAAM;IAClD,CAAC,CAAC,YAAY;IACd,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,OAAO;QAClD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,aAAa,CAAC;AALT,QAAA,SAAS,aAKA;AAGtB,SAAgB,aAAa;IAC3B,OAAO,IAAA,iBAAS,GAAE,KAAK,aAAa,CAAC;AACvC,CAAC;AAGD,SAAgB,YAAY;IAC1B,OAAO,IAAA,iBAAS,GAAE,KAAK,YAAY,CAAC;AACtC,CAAC;AAGD,SAAgB,SAAS;IACvB,OAAO,IAAA,iBAAS,GAAE,KAAK,SAAS,CAAC;AACnC,CAAC;AAGY,QAAA,aAAa,GAAW,IAAA,iBAAS,GAAE,CAAC;AAGpC,QAAA,KAAK,GAAG,qBAAa,KAAK,aAAa,CAAC;AAExC,QAAA,MAAM,GAAG,qBAAa,KAAK,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { CommonErrorDto } from './controller.helpers';
2
+ export declare class ErrorUtils {
3
+ createError(code: number, message: string, details?: any): CommonErrorDto;
4
+ private getErrorCode;
5
+ fromException(exception: unknown): CommonErrorDto;
6
+ }
@@ -0,0 +1,65 @@
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.ErrorUtils = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const controller_helpers_1 = require("./controller.helpers");
12
+ let ErrorUtils = class ErrorUtils {
13
+ createError(code, message, details) {
14
+ const errorCode = code === 0 ? 500 : code;
15
+ const errorMessage = typeof message === 'string'
16
+ ? (details ? { message, ...details } : message)
17
+ : message;
18
+ return new controller_helpers_1.CommonErrorDto(errorCode, errorMessage, []);
19
+ }
20
+ getErrorCode(statusCode) {
21
+ const codes = {
22
+ 400: 'BAD_REQUEST',
23
+ 401: 'UNAUTHORIZED',
24
+ 403: 'FORBIDDEN',
25
+ 404: 'NOT_FOUND',
26
+ 409: 'CONFLICT',
27
+ 422: 'UNPROCESSABLE_ENTITY',
28
+ 500: 'INTERNAL_SERVER_ERROR',
29
+ 503: 'SERVICE_UNAVAILABLE',
30
+ };
31
+ return codes[statusCode] || 'UNKNOWN_ERROR';
32
+ }
33
+ fromException(exception) {
34
+ if (exception && typeof exception === 'object' && 'code' in exception && 'error' in exception && 'data' in exception) {
35
+ return exception;
36
+ }
37
+ if (exception &&
38
+ typeof exception === 'object' &&
39
+ 'getStatus' in exception &&
40
+ 'getResponse' in exception) {
41
+ const httpException = exception;
42
+ const statusCode = httpException.getStatus();
43
+ const response = httpException.getResponse();
44
+ const message = typeof response === 'string'
45
+ ? response
46
+ : response?.message || 'Internal server error';
47
+ const details = typeof response === 'object' ? response : undefined;
48
+ return this.createError(statusCode, message, details);
49
+ }
50
+ if (exception instanceof Error) {
51
+ const statusCode = exception.status || 500;
52
+ const message = exception.message || 'Internal server error';
53
+ const details = exception.details;
54
+ return this.createError(statusCode, message, details);
55
+ }
56
+ return this.createError(500, 'Internal server error', {
57
+ originalError: String(exception),
58
+ });
59
+ }
60
+ };
61
+ exports.ErrorUtils = ErrorUtils;
62
+ exports.ErrorUtils = ErrorUtils = __decorate([
63
+ (0, common_1.Injectable)()
64
+ ], ErrorUtils);
65
+ //# sourceMappingURL=error.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.utils.js","sourceRoot":"","sources":["../../src/utils/error.utils.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAC5C,6DAAsD;AAW/C,IAAM,UAAU,GAAhB,MAAM,UAAU;IAcrB,WAAW,CAAC,IAAY,EAAE,OAAe,EAAE,OAAa;QAEtD,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAG1C,MAAM,YAAY,GAAG,OAAO,OAAO,KAAK,QAAQ;YAC9C,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/C,CAAC,CAAC,OAAO,CAAC;QAEZ,OAAO,IAAI,mCAAc,CAAC,SAAS,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC;IAKO,YAAY,CAAC,UAAkB;QACrC,MAAM,KAAK,GAA2B;YACpC,GAAG,EAAE,aAAa;YAClB,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,sBAAsB;YAC3B,GAAG,EAAE,uBAAuB;YAC5B,GAAG,EAAE,qBAAqB;SAC3B,CAAC;QACF,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,eAAe,CAAC;IAC9C,CAAC;IAKD,aAAa,CAAC,SAAkB;QAE9B,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,MAAM,IAAI,SAAS,IAAI,OAAO,IAAI,SAAS,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;YACrH,OAAO,SAA2B,CAAC;QACrC,CAAC;QAGD,IACE,SAAS;YACT,OAAO,SAAS,KAAK,QAAQ;YAC7B,WAAW,IAAI,SAAS;YACxB,aAAa,IAAI,SAAS,EAC1B,CAAC;YACD,MAAM,aAAa,GAAG,SAAgE,CAAC;YACvF,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;YAC7C,MAAM,OAAO,GACX,OAAO,QAAQ,KAAK,QAAQ;gBAC1B,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAE,QAAgB,EAAE,OAAO,IAAI,uBAAuB,CAAC;YAC5D,MAAM,OAAO,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YAEpE,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC;QAGD,IAAI,SAAS,YAAY,KAAK,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAI,SAAiB,CAAC,MAAM,IAAI,GAAG,CAAC;YACpD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,IAAI,uBAAuB,CAAC;YAC7D,MAAM,OAAO,GAAI,SAAiB,CAAC,OAAO,CAAC;YAE3C,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,CAAC;QAGD,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,uBAAuB,EAAE;YACpD,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AArFY,gCAAU;qBAAV,UAAU;IADtB,IAAA,mBAAU,GAAE;GACA,UAAU,CAqFtB"}
@@ -0,0 +1,35 @@
1
+ export interface HashVerificationConfig {
2
+ algorithm?: string;
3
+ secret?: string;
4
+ encoding?: 'hex' | 'base64';
5
+ normalizer?: 'email' | 'digits';
6
+ keyDerivation?: 'none' | 'sha256';
7
+ }
8
+ export interface HashVerificationConfigMap {
9
+ default?: HashVerificationConfig;
10
+ profiles?: Record<string, HashVerificationConfig>;
11
+ [key: string]: HashVerificationConfig | Record<string, HashVerificationConfig> | undefined;
12
+ }
13
+ export declare function hashValue(value: string, config?: HashVerificationConfig | null, options?: {
14
+ normalizer?: (s: string) => string;
15
+ fallbackEnvKey?: string;
16
+ }): string;
17
+ export declare function compareValue(plain: string, storedHash: string, config?: HashVerificationConfig | null, options?: {
18
+ normalizer?: (s: string) => string;
19
+ fallbackEnvKey?: string;
20
+ }): boolean;
21
+ export declare const emailNormalizer: (s: string) => string;
22
+ export declare const digitsNormalizer: (s: string) => string;
23
+ export declare const BUILT_IN_NORMALIZERS: Record<string, (s: string) => string>;
24
+ export declare function getProfileConfig(key: string, configMap: HashVerificationConfigMap | null | undefined): HashVerificationConfig | null;
25
+ export declare function hashByKey(key: string, value: string, configMap: HashVerificationConfigMap | null | undefined): string;
26
+ export declare function compareByKey(key: string, plain: string, storedHash: string, configMap: HashVerificationConfigMap | null | undefined): boolean;
27
+ export declare function hashEmail(email: string, config?: HashVerificationConfig | null): string;
28
+ export declare function compareEmail(plainEmail: string, storedHash: string, config?: HashVerificationConfig | null): boolean;
29
+ export interface LookupHashOptions {
30
+ keyDerivation?: 'none' | 'sha256';
31
+ normalizer?: (s: string) => string;
32
+ fallbackEnvKey?: string;
33
+ }
34
+ export declare function lookupHash(value: string, secret?: string | null, options?: LookupHashOptions): string;
35
+ export declare function compareLookupHash(plain: string, storedHash: string, secret?: string | null, options?: LookupHashOptions): boolean;
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BUILT_IN_NORMALIZERS = exports.digitsNormalizer = exports.emailNormalizer = void 0;
4
+ exports.hashValue = hashValue;
5
+ exports.compareValue = compareValue;
6
+ exports.getProfileConfig = getProfileConfig;
7
+ exports.hashByKey = hashByKey;
8
+ exports.compareByKey = compareByKey;
9
+ exports.hashEmail = hashEmail;
10
+ exports.compareEmail = compareEmail;
11
+ exports.lookupHash = lookupHash;
12
+ exports.compareLookupHash = compareLookupHash;
13
+ const crypto = require("crypto");
14
+ const crypto_utils_1 = require("./crypto.utils");
15
+ const DEFAULT_ALGORITHM = 'sha256';
16
+ const DEFAULT_ENCODING = 'hex';
17
+ function resolveSecret(config, fallbackEnv) {
18
+ const envKey = fallbackEnv ?? 'HASH_VERIFICATION_SECRET';
19
+ const secret = config?.secret ?? (typeof process !== 'undefined' ? process.env[envKey] : undefined);
20
+ if (!secret || typeof secret !== 'string') {
21
+ throw new Error(`Hash secret is required. Set hashVerification.*.secret in application.yml or ${envKey} env.`);
22
+ }
23
+ return secret;
24
+ }
25
+ function hashValue(value, config, options) {
26
+ if (value == null || typeof value !== 'string') {
27
+ throw new Error('value must be a non-empty string');
28
+ }
29
+ const raw = options?.normalizer ? options.normalizer(value) : value;
30
+ if (!raw)
31
+ throw new Error('value is empty after normalizer');
32
+ const secret = resolveSecret(config, options?.fallbackEnvKey);
33
+ const algorithm = config?.algorithm ?? DEFAULT_ALGORITHM;
34
+ const encoding = config?.encoding ?? DEFAULT_ENCODING;
35
+ const keyDerivation = config?.keyDerivation ?? 'none';
36
+ const hmacKey = keyDerivation === 'sha256' ? (0, crypto_utils_1.deriveKeySha256)(secret) : secret;
37
+ const hmac = crypto.createHmac(algorithm, hmacKey);
38
+ hmac.update(raw);
39
+ return hmac.digest(encoding);
40
+ }
41
+ function compareValue(plain, storedHash, config, options) {
42
+ if (!storedHash || plain == null)
43
+ return false;
44
+ try {
45
+ const computed = hashValue(plain, config, options);
46
+ const encoding = config?.encoding ?? DEFAULT_ENCODING;
47
+ const a = Buffer.from(computed, encoding);
48
+ const b = Buffer.from(storedHash, encoding);
49
+ if (a.length !== b.length)
50
+ return false;
51
+ return crypto.timingSafeEqual(a, b);
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ }
57
+ const emailNormalizer = (s) => s.trim().toLowerCase();
58
+ exports.emailNormalizer = emailNormalizer;
59
+ const digitsNormalizer = (s) => s.replace(/\D/g, '');
60
+ exports.digitsNormalizer = digitsNormalizer;
61
+ exports.BUILT_IN_NORMALIZERS = {
62
+ email: exports.emailNormalizer,
63
+ digits: exports.digitsNormalizer,
64
+ };
65
+ function getProfileConfig(key, configMap) {
66
+ if (!configMap || typeof configMap !== 'object')
67
+ return null;
68
+ if (key === 'profiles')
69
+ return null;
70
+ if (key === 'default')
71
+ return configMap.default ?? null;
72
+ const profiles = configMap.profiles;
73
+ if (profiles && typeof profiles[key] === 'object')
74
+ return profiles[key];
75
+ const root = configMap[key];
76
+ if (root && typeof root === 'object' && !('default' in root) && !('profiles' in root))
77
+ return root;
78
+ if (configMap.default)
79
+ return configMap.default;
80
+ return null;
81
+ }
82
+ function hashByKey(key, value, configMap) {
83
+ const config = getProfileConfig(key, configMap);
84
+ const normalizerName = config?.normalizer;
85
+ const normalizer = normalizerName ? exports.BUILT_IN_NORMALIZERS[normalizerName] : undefined;
86
+ const fallbackEnv = key === 'email' ? 'EMAIL_HASH_SECRET' : 'HASH_VERIFICATION_SECRET';
87
+ return hashValue(value, config ?? undefined, {
88
+ normalizer,
89
+ fallbackEnvKey: fallbackEnv,
90
+ });
91
+ }
92
+ function compareByKey(key, plain, storedHash, configMap) {
93
+ const config = getProfileConfig(key, configMap);
94
+ const normalizerName = config?.normalizer;
95
+ const normalizer = normalizerName ? exports.BUILT_IN_NORMALIZERS[normalizerName] : undefined;
96
+ const fallbackEnv = key === 'email' ? 'EMAIL_HASH_SECRET' : 'HASH_VERIFICATION_SECRET';
97
+ return compareValue(plain, storedHash, config ?? undefined, {
98
+ normalizer,
99
+ fallbackEnvKey: fallbackEnv,
100
+ });
101
+ }
102
+ function hashEmail(email, config) {
103
+ return hashValue(email, config, { normalizer: exports.emailNormalizer, fallbackEnvKey: 'EMAIL_HASH_SECRET' });
104
+ }
105
+ function compareEmail(plainEmail, storedHash, config) {
106
+ return compareValue(plainEmail, storedHash, config, {
107
+ normalizer: exports.emailNormalizer,
108
+ fallbackEnvKey: 'EMAIL_HASH_SECRET',
109
+ });
110
+ }
111
+ function lookupHash(value, secret, options = {}) {
112
+ const keyDerivation = options.keyDerivation ?? 'none';
113
+ const config = {
114
+ secret: secret ?? undefined,
115
+ keyDerivation: keyDerivation === 'sha256' ? 'sha256' : 'none',
116
+ };
117
+ return hashValue(value, config, {
118
+ normalizer: options.normalizer,
119
+ fallbackEnvKey: options.fallbackEnvKey ?? 'HASH_VERIFICATION_SECRET',
120
+ });
121
+ }
122
+ function compareLookupHash(plain, storedHash, secret, options = {}) {
123
+ const keyDerivation = options.keyDerivation ?? 'none';
124
+ const config = {
125
+ secret: secret ?? undefined,
126
+ keyDerivation: keyDerivation === 'sha256' ? 'sha256' : 'none',
127
+ };
128
+ return compareValue(plain, storedHash, config, {
129
+ normalizer: options.normalizer,
130
+ fallbackEnvKey: options.fallbackEnvKey ?? 'HASH_VERIFICATION_SECRET',
131
+ });
132
+ }
133
+ //# sourceMappingURL=hash-verification.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-verification.utils.js","sourceRoot":"","sources":["../../src/utils/hash-verification.utils.ts"],"names":[],"mappings":"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"}