@nest-omni/core 4.1.3-29 → 4.1.3-30

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 (51) hide show
  1. package/audit/interceptors/audit-action.interceptor.js +1 -1
  2. package/audit/services/audit-action.service.js +1 -1
  3. package/audit/services/operation-description.service.js +1 -1
  4. package/audit/services/transaction-audit.service.js +1 -1
  5. package/email-log/email-log.constants.d.ts +8 -0
  6. package/email-log/email-log.constants.js +11 -0
  7. package/email-log/email-log.module.d.ts +47 -0
  8. package/email-log/email-log.module.js +140 -0
  9. package/email-log/index.d.ts +11 -0
  10. package/email-log/index.js +48 -0
  11. package/email-log/interfaces/email-log-options.interface.d.ts +61 -0
  12. package/email-log/interfaces/email-log-options.interface.js +134 -0
  13. package/email-log/interfaces/email-log-transport.interface.d.ts +20 -0
  14. package/email-log/interfaces/email-log-transport.interface.js +2 -0
  15. package/email-log/interfaces/index.d.ts +2 -0
  16. package/email-log/interfaces/index.js +18 -0
  17. package/email-log/providers/email-provider.d.ts +42 -0
  18. package/email-log/providers/email-provider.js +127 -0
  19. package/email-log/providers/index.d.ts +1 -0
  20. package/email-log/providers/index.js +17 -0
  21. package/email-log/services/email-log-alert.service.d.ts +46 -0
  22. package/email-log/services/email-log-alert.service.js +162 -0
  23. package/email-log/services/email-log-formatter.service.d.ts +78 -0
  24. package/email-log/services/email-log-formatter.service.js +442 -0
  25. package/email-log/services/email-log-logger.service.d.ts +85 -0
  26. package/email-log/services/email-log-logger.service.js +168 -0
  27. package/email-log/services/email-log-rate-limiter.service.d.ts +42 -0
  28. package/email-log/services/email-log-rate-limiter.service.js +110 -0
  29. package/email-log/services/email-log-transport.service.d.ts +80 -0
  30. package/email-log/services/email-log-transport.service.js +271 -0
  31. package/email-log/services/index.d.ts +5 -0
  32. package/email-log/services/index.js +21 -0
  33. package/email-log/transports/index.d.ts +1 -0
  34. package/email-log/transports/index.js +17 -0
  35. package/email-log/transports/pino-email.transport.d.ts +56 -0
  36. package/email-log/transports/pino-email.transport.js +188 -0
  37. package/email-log/utils/index.d.ts +2 -0
  38. package/email-log/utils/index.js +18 -0
  39. package/email-log/utils/log-level.helper.d.ts +46 -0
  40. package/email-log/utils/log-level.helper.js +74 -0
  41. package/email-log/utils/pino-transport.utils.d.ts +135 -0
  42. package/email-log/utils/pino-transport.utils.js +238 -0
  43. package/filters/bad-request.filter.d.ts +9 -0
  44. package/filters/bad-request.filter.js +38 -12
  45. package/index.d.ts +1 -0
  46. package/index.js +2 -0
  47. package/package.json +3 -1
  48. package/setup/bootstrap.setup.js +1 -1
  49. package/shared/service-registry.module.js +14 -0
  50. package/shared/services/api-config.service.d.ts +41 -0
  51. package/shared/services/api-config.service.js +163 -6
@@ -0,0 +1,127 @@
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var EmailLogProvider_1;
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.EmailLogProvider = void 0;
23
+ const common_1 = require("@nestjs/common");
24
+ const nodemailer = require("nodemailer");
25
+ /**
26
+ * Email provider for log alerts
27
+ * Wraps nodemailer for SMTP email sending
28
+ */
29
+ let EmailLogProvider = EmailLogProvider_1 = class EmailLogProvider {
30
+ constructor(options) {
31
+ this.options = options;
32
+ this.logger = new common_1.Logger(EmailLogProvider_1.name);
33
+ this.transporter = null;
34
+ this.initializeTransporter();
35
+ }
36
+ /**
37
+ * Initialize nodemailer transporter
38
+ */
39
+ initializeTransporter() {
40
+ const config = {
41
+ host: this.options.smtpHost,
42
+ port: this.options.smtpPort || 587,
43
+ secure: this.options.smtpSecure || false,
44
+ tls: {
45
+ rejectUnauthorized: this.options.smtpIgnoreTLSError !== undefined
46
+ ? !this.options.smtpIgnoreTLSError
47
+ : true,
48
+ },
49
+ };
50
+ if (this.options.smtpUsername || this.options.smtpPassword) {
51
+ config.auth = {
52
+ user: this.options.smtpUsername,
53
+ pass: this.options.smtpPassword,
54
+ };
55
+ }
56
+ this.transporter = nodemailer.createTransport(config);
57
+ this.logger.log(`Email transporter initialized: ${this.options.smtpHost}:${this.options.smtpPort || 587}`);
58
+ }
59
+ /**
60
+ * Verify SMTP connection (useful for health checks)
61
+ */
62
+ verifyConnection() {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ if (!this.transporter) {
65
+ return false;
66
+ }
67
+ try {
68
+ yield this.transporter.verify();
69
+ this.logger.debug('SMTP connection verified successfully');
70
+ return true;
71
+ }
72
+ catch (error) {
73
+ this.logger.error(`SMTP connection verification failed: ${error.message}`);
74
+ return false;
75
+ }
76
+ });
77
+ }
78
+ /**
79
+ * Send log email
80
+ */
81
+ sendLogEmail(params) {
82
+ return __awaiter(this, void 0, void 0, function* () {
83
+ if (!this.transporter) {
84
+ throw new Error('Email transporter not initialized');
85
+ }
86
+ try {
87
+ const mailOptions = {
88
+ from: params.from,
89
+ to: params.to.join(', '),
90
+ subject: params.subject,
91
+ };
92
+ if (params.cc && params.cc.length > 0) {
93
+ mailOptions.cc = params.cc.join(', ');
94
+ }
95
+ if (params.html) {
96
+ mailOptions.html = params.html;
97
+ }
98
+ else if (params.text) {
99
+ mailOptions.text = params.text;
100
+ }
101
+ const info = yield this.transporter.sendMail(mailOptions);
102
+ this.logger.debug(`Log email sent to ${params.to.join(', ')} - Message ID: ${info.messageId}`);
103
+ }
104
+ catch (error) {
105
+ this.logger.error(`Failed to send log email: ${error.message}`, error.stack);
106
+ throw error;
107
+ }
108
+ });
109
+ }
110
+ /**
111
+ * Close the transporter connection
112
+ */
113
+ close() {
114
+ return __awaiter(this, void 0, void 0, function* () {
115
+ if (this.transporter) {
116
+ this.transporter.close();
117
+ this.transporter = null;
118
+ this.logger.debug('Email transporter closed');
119
+ }
120
+ });
121
+ }
122
+ };
123
+ exports.EmailLogProvider = EmailLogProvider;
124
+ exports.EmailLogProvider = EmailLogProvider = EmailLogProvider_1 = __decorate([
125
+ (0, common_1.Injectable)(),
126
+ __metadata("design:paramtypes", [Object])
127
+ ], EmailLogProvider);
@@ -0,0 +1 @@
1
+ export * from './email-provider';
@@ -0,0 +1,17 @@
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("./email-provider"), exports);
@@ -0,0 +1,46 @@
1
+ import type { EmailLogOptions } from '../interfaces';
2
+ import { EmailLogRateLimiterService } from './email-log-rate-limiter.service';
3
+ import { EmailLogFormatterService } from './email-log-formatter.service';
4
+ /**
5
+ * Email log alert service
6
+ * Sends email notifications for critical log entries
7
+ *
8
+ * This service can be used directly to send email alerts
9
+ * without requiring Pino transport integration
10
+ *
11
+ * Note: Manual email alerts don't include HTTP context.
12
+ * For HTTP context, use Pino logger which automatically includes it via customProps.
13
+ */
14
+ export declare class EmailLogAlertService {
15
+ private readonly options;
16
+ private readonly rateLimiter;
17
+ private readonly formatter;
18
+ private readonly logger;
19
+ private readonly appName;
20
+ private emailProvider;
21
+ constructor(options: EmailLogOptions, rateLimiter: EmailLogRateLimiterService, formatter: EmailLogFormatterService);
22
+ /**
23
+ * Send a log alert via email
24
+ * @param level Log level (error, fatal, etc.)
25
+ * @param message Log message
26
+ * @param error Optional error object
27
+ * @param context Optional additional context
28
+ */
29
+ sendAlert(level: string, message: string, error?: Error, context?: Record<string, any>): Promise<void>;
30
+ /**
31
+ * Send error alert
32
+ */
33
+ error(message: string, error?: Error, context?: Record<string, any>): Promise<void>;
34
+ /**
35
+ * Send fatal alert
36
+ */
37
+ fatal(message: string, error?: Error, context?: Record<string, any>): Promise<void>;
38
+ /**
39
+ * Format and send email
40
+ */
41
+ private sendEmail;
42
+ /**
43
+ * Cleanup on module destroy
44
+ */
45
+ onModuleDestroy(): Promise<void>;
46
+ }
@@ -0,0 +1,162 @@
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 __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ var EmailLogAlertService_1;
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.EmailLogAlertService = void 0;
26
+ const common_1 = require("@nestjs/common");
27
+ const email_log_constants_1 = require("../email-log.constants");
28
+ const email_log_rate_limiter_service_1 = require("./email-log-rate-limiter.service");
29
+ const email_log_formatter_service_1 = require("./email-log-formatter.service");
30
+ const email_provider_1 = require("../providers/email-provider");
31
+ const log_level_helper_1 = require("../utils/log-level.helper");
32
+ /**
33
+ * Email log alert service
34
+ * Sends email notifications for critical log entries
35
+ *
36
+ * This service can be used directly to send email alerts
37
+ * without requiring Pino transport integration
38
+ *
39
+ * Note: Manual email alerts don't include HTTP context.
40
+ * For HTTP context, use Pino logger which automatically includes it via customProps.
41
+ */
42
+ let EmailLogAlertService = EmailLogAlertService_1 = class EmailLogAlertService {
43
+ constructor(options, rateLimiter, formatter) {
44
+ this.options = options;
45
+ this.rateLimiter = rateLimiter;
46
+ this.formatter = formatter;
47
+ this.logger = new common_1.Logger(EmailLogAlertService_1.name);
48
+ this.appName = process.env.NAME || process.env.APP_NAME || 'omni-app';
49
+ this.emailProvider = new email_provider_1.EmailLogProvider({
50
+ smtpHost: options.smtpHost,
51
+ smtpPort: options.smtpPort || 587,
52
+ smtpUsername: options.smtpUsername,
53
+ smtpPassword: options.smtpPassword,
54
+ smtpSecure: options.smtpSecure || false,
55
+ smtpIgnoreTLSError: options.smtpIgnoreTLSError || false,
56
+ });
57
+ }
58
+ /**
59
+ * Send a log alert via email
60
+ * @param level Log level (error, fatal, etc.)
61
+ * @param message Log message
62
+ * @param error Optional error object
63
+ * @param context Optional additional context
64
+ */
65
+ sendAlert(level, message, error, context) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ // Check if enabled
68
+ if (!this.options.enabled) {
69
+ return;
70
+ }
71
+ // Check log level threshold
72
+ const levelValue = (0, log_level_helper_1.getLevelValue)(level);
73
+ const thresholdValue = (0, log_level_helper_1.getLevelValue)(this.options.level);
74
+ if (levelValue < thresholdValue) {
75
+ return;
76
+ }
77
+ // Check rate limiting
78
+ const rateLimitKey = `email-log:${this.appName}:${level}`;
79
+ if (!this.rateLimiter.canSend(rateLimitKey)) {
80
+ this.logger.debug(`Rate limited email for log: ${message}`);
81
+ return;
82
+ }
83
+ // Create log entry
84
+ const logEntry = {
85
+ level,
86
+ message,
87
+ timestamp: Date.now(),
88
+ };
89
+ if (error) {
90
+ logEntry.error = error;
91
+ }
92
+ if (context) {
93
+ logEntry.context = context;
94
+ }
95
+ // Send email
96
+ yield this.sendEmail(logEntry);
97
+ });
98
+ }
99
+ /**
100
+ * Send error alert
101
+ */
102
+ error(message, error, context) {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ return this.sendAlert('error', message, error, context);
105
+ });
106
+ }
107
+ /**
108
+ * Send fatal alert
109
+ */
110
+ fatal(message, error, context) {
111
+ return __awaiter(this, void 0, void 0, function* () {
112
+ return this.sendAlert('fatal', message, error, context);
113
+ });
114
+ }
115
+ /**
116
+ * Format and send email
117
+ */
118
+ sendEmail(logEntry) {
119
+ return __awaiter(this, void 0, void 0, function* () {
120
+ const subjectPrefix = this.options.subjectPrefix || '[Log Alert]';
121
+ // Convert log entry to Pino format for formatter
122
+ const pinoLog = Object.assign(Object.assign({ level: (0, log_level_helper_1.getLevelValue)(logEntry.level), time: logEntry.timestamp || Date.now(), msg: logEntry.message }, (logEntry.error
123
+ ? {
124
+ err: {
125
+ type: logEntry.error.name,
126
+ message: logEntry.error.message,
127
+ stack: logEntry.error.stack,
128
+ },
129
+ }
130
+ : {})), (logEntry.context || {}));
131
+ const emailContent = this.options.useHtmlFormat
132
+ ? this.formatter.formatHtml(pinoLog, this.appName, subjectPrefix)
133
+ : this.formatter.formatText(pinoLog, this.appName, subjectPrefix);
134
+ yield this.emailProvider.sendLogEmail({
135
+ to: this.options.to,
136
+ cc: this.options.cc,
137
+ from: this.options.from,
138
+ subject: emailContent.subject,
139
+ html: 'html' in emailContent ? emailContent.html : undefined,
140
+ text: 'text' in emailContent ? emailContent.text : undefined,
141
+ });
142
+ this.logger.debug(`Log email sent for ${this.appName}: ${logEntry.message}`);
143
+ });
144
+ }
145
+ /**
146
+ * Cleanup on module destroy
147
+ */
148
+ onModuleDestroy() {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ yield this.emailProvider.close();
151
+ });
152
+ }
153
+ };
154
+ exports.EmailLogAlertService = EmailLogAlertService;
155
+ exports.EmailLogAlertService = EmailLogAlertService = EmailLogAlertService_1 = __decorate([
156
+ (0, common_1.Injectable)(),
157
+ __param(0, (0, common_1.Inject)(email_log_constants_1.EMAIL_LOG_OPTIONS)),
158
+ __param(1, (0, common_1.Inject)(email_log_constants_1.EMAIL_LOG_RATE_LIMITER)),
159
+ __param(2, (0, common_1.Inject)(email_log_constants_1.EMAIL_LOG_FORMATTER)),
160
+ __metadata("design:paramtypes", [Function, email_log_rate_limiter_service_1.EmailLogRateLimiterService,
161
+ email_log_formatter_service_1.EmailLogFormatterService])
162
+ ], EmailLogAlertService);
@@ -0,0 +1,78 @@
1
+ import { LogDescriptor } from 'pino';
2
+ /**
3
+ * Formats log entries for email delivery
4
+ * Supports both HTML and plain text formats
5
+ */
6
+ export declare class EmailLogFormatterService {
7
+ /**
8
+ * Format log entry as HTML email
9
+ */
10
+ formatHtml(log: LogDescriptor, appName: string, subjectPrefix: string): {
11
+ subject: string;
12
+ html: string;
13
+ };
14
+ /**
15
+ * Format log entry as plain text
16
+ */
17
+ formatText(log: LogDescriptor, appName: string, subjectPrefix: string): {
18
+ subject: string;
19
+ text: string;
20
+ };
21
+ /**
22
+ * Extract HTTP context from log metadata
23
+ */
24
+ private extractHttpContext;
25
+ /**
26
+ * Exclude HTTP context from general metadata
27
+ */
28
+ private excludeHttpContext;
29
+ /**
30
+ * Format request information for HTML
31
+ */
32
+ private formatRequestInfo;
33
+ /**
34
+ * Format request information for text
35
+ */
36
+ private formatRequestInfoText;
37
+ /**
38
+ * Generate a curl command for the request (single line for easy copying)
39
+ */
40
+ private generateCurlCommand;
41
+ /**
42
+ * Format user information for HTML
43
+ */
44
+ private formatUserInfo;
45
+ /**
46
+ * Format user information for text
47
+ */
48
+ private formatUserInfoText;
49
+ /**
50
+ * Format error object for HTML
51
+ */
52
+ private formatError;
53
+ /**
54
+ * Format error object for text
55
+ */
56
+ private formatErrorText;
57
+ /**
58
+ * Format metadata object for HTML
59
+ */
60
+ private formatMetadata;
61
+ /**
62
+ * Format a value for HTML display
63
+ */
64
+ private formatValue;
65
+ /**
66
+ * Get human-readable log level label
67
+ * Uses shared utility from log-level.helper
68
+ */
69
+ private getLevelLabel;
70
+ /**
71
+ * Get color for log level
72
+ */
73
+ private getLevelColor;
74
+ /**
75
+ * Escape HTML special characters
76
+ */
77
+ private escapeHtml;
78
+ }