@dumanarge/xssrv-shared-lib 1.0.6 → 1.0.8

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 (40) hide show
  1. package/dist/context/observability-context.d.ts +3 -0
  2. package/dist/context/observability-context.js +8 -2
  3. package/dist/context/observability-context.js.map +1 -1
  4. package/dist/context/observability.interceptor.js +139 -2
  5. package/dist/context/observability.interceptor.js.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +28 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/log-events/access-log-payload.builder.d.ts +69 -0
  10. package/dist/log-events/access-log-payload.builder.js +237 -0
  11. package/dist/log-events/access-log-payload.builder.js.map +1 -0
  12. package/dist/log-events/access-log.interceptor.d.ts +29 -0
  13. package/dist/log-events/access-log.interceptor.js +456 -0
  14. package/dist/log-events/access-log.interceptor.js.map +1 -0
  15. package/dist/log-events/index.d.ts +8 -0
  16. package/dist/log-events/index.js +37 -0
  17. package/dist/log-events/index.js.map +1 -0
  18. package/dist/log-events/log-event.types.d.ts +138 -0
  19. package/dist/log-events/log-event.types.js +56 -0
  20. package/dist/log-events/log-event.types.js.map +1 -0
  21. package/dist/log-events/log-publisher.d.ts +8 -0
  22. package/dist/log-events/log-publisher.js +26 -0
  23. package/dist/log-events/log-publisher.js.map +1 -0
  24. package/dist/log-events/rabbitmq-log-publisher.d.ts +34 -0
  25. package/dist/log-events/rabbitmq-log-publisher.js +159 -0
  26. package/dist/log-events/rabbitmq-log-publisher.js.map +1 -0
  27. package/dist/log-events/redaction.d.ts +16 -0
  28. package/dist/log-events/redaction.js +140 -0
  29. package/dist/log-events/redaction.js.map +1 -0
  30. package/dist/log-events/ring-buffer.d.ts +18 -0
  31. package/dist/log-events/ring-buffer.js +54 -0
  32. package/dist/log-events/ring-buffer.js.map +1 -0
  33. package/dist/log-events/sampling-policy.d.ts +26 -0
  34. package/dist/log-events/sampling-policy.js +95 -0
  35. package/dist/log-events/sampling-policy.js.map +1 -0
  36. package/dist/observability/request-context.js +3 -0
  37. package/dist/observability/request-context.js.map +1 -1
  38. package/dist/tracing/tracing.js +27 -0
  39. package/dist/tracing/tracing.js.map +1 -1
  40. package/package.json +5 -1
@@ -0,0 +1,138 @@
1
+ export declare const LOG_KIND: {
2
+ readonly ACCESS: "access";
3
+ readonly AUDIT: "audit";
4
+ readonly EVENT: "event";
5
+ };
6
+ export type LogKind = (typeof LOG_KIND)[keyof typeof LOG_KIND];
7
+ export declare const LOG_TRANSPORT: {
8
+ readonly HTTP: "http";
9
+ readonly GRAPHQL: "graphql";
10
+ readonly GRPC: "grpc";
11
+ readonly RABBITMQ: "rabbitmq";
12
+ readonly INTERNAL: "internal";
13
+ };
14
+ export type LogTransport = (typeof LOG_TRANSPORT)[keyof typeof LOG_TRANSPORT];
15
+ export declare const ACCESS_LOG_RESULT_STATUS: {
16
+ readonly SUCCESS: "SUCCESS";
17
+ readonly FAILURE: "FAILURE";
18
+ };
19
+ export type AccessLogResultStatus = (typeof ACCESS_LOG_RESULT_STATUS)[keyof typeof ACCESS_LOG_RESULT_STATUS];
20
+ export declare const ACCESS_LOG_OUTCOME: {
21
+ readonly SUCCESS: "success";
22
+ readonly ERROR: "error";
23
+ readonly TIMEOUT: "timeout";
24
+ readonly ABORTED: "aborted";
25
+ readonly CRASHED: "crashed";
26
+ };
27
+ export type AccessLogOutcome = (typeof ACCESS_LOG_OUTCOME)[keyof typeof ACCESS_LOG_OUTCOME];
28
+ export declare const ACCESS_LOG_FAILURE_SOURCE: {
29
+ readonly APPLICATION: "application";
30
+ readonly TRANSPORT: "transport";
31
+ readonly UPSTREAM: "upstream";
32
+ readonly CLIENT: "client";
33
+ };
34
+ export type AccessLogFailureSource = (typeof ACCESS_LOG_FAILURE_SOURCE)[keyof typeof ACCESS_LOG_FAILURE_SOURCE];
35
+ export declare const AUDIT_ACTOR_TYPE: {
36
+ readonly ACCOUNT: "ACCOUNT";
37
+ readonly SYSTEM: "SYSTEM";
38
+ readonly AUTOMATION: "AUTOMATION";
39
+ readonly DEVICE: "DEVICE";
40
+ readonly ANONYMOUS: "ANONYMOUS";
41
+ };
42
+ export type AuditActorType = (typeof AUDIT_ACTOR_TYPE)[keyof typeof AUDIT_ACTOR_TYPE];
43
+ export declare const AUDIT_SEVERITY: {
44
+ readonly INFO: "INFO";
45
+ readonly WARN: "WARN";
46
+ readonly ERROR: "ERROR";
47
+ };
48
+ export type AuditSeverity = (typeof AUDIT_SEVERITY)[keyof typeof AUDIT_SEVERITY];
49
+ export interface AccessLogPayload {
50
+ readonly started_at: string;
51
+ readonly completed_at: string;
52
+ readonly duration_ms: number;
53
+ readonly correlation_id: string;
54
+ readonly request_id?: string;
55
+ readonly trace_id?: string;
56
+ readonly span_id?: string;
57
+ readonly tenant_id?: string;
58
+ readonly tenant_name?: string;
59
+ readonly application_id?: string;
60
+ readonly application_name?: string;
61
+ readonly account_id?: string;
62
+ readonly email?: string;
63
+ readonly result_status: AccessLogResultStatus;
64
+ readonly outcome: AccessLogOutcome;
65
+ readonly failure_reason?: string;
66
+ readonly failure_source?: AccessLogFailureSource;
67
+ readonly error_key?: string;
68
+ readonly error_category?: string;
69
+ readonly exception_class?: string;
70
+ readonly method?: string;
71
+ readonly path?: string;
72
+ readonly status_code?: number;
73
+ readonly transport?: LogTransport;
74
+ readonly source_service?: string;
75
+ readonly source_transport?: LogTransport;
76
+ readonly source_operation?: string;
77
+ readonly request_headers?: Record<string, string>;
78
+ readonly request_body?: unknown;
79
+ readonly response_body?: unknown;
80
+ readonly body_truncated?: boolean;
81
+ }
82
+ export interface AccessLogEvent {
83
+ readonly kind: typeof LOG_KIND.ACCESS;
84
+ readonly transport: LogTransport;
85
+ readonly payload: AccessLogPayload;
86
+ }
87
+ export interface AuditLogPayload {
88
+ readonly started_at: string;
89
+ readonly correlation_id: string;
90
+ readonly request_id?: string;
91
+ readonly trace_id?: string;
92
+ readonly span_id?: string;
93
+ readonly tenant_id: string;
94
+ readonly tenant_name?: string;
95
+ readonly application_id?: string;
96
+ readonly application_name?: string;
97
+ readonly actor_type: AuditActorType;
98
+ readonly actor_id?: string;
99
+ readonly actor_email?: string;
100
+ readonly actor_email_hash?: string;
101
+ readonly actor_ip?: string;
102
+ readonly target_type?: string;
103
+ readonly target_id?: string;
104
+ readonly category?: string;
105
+ readonly severity?: AuditSeverity;
106
+ readonly before?: Record<string, unknown>;
107
+ readonly after?: Record<string, unknown>;
108
+ readonly diff?: Record<string, unknown>;
109
+ readonly metadata?: Record<string, unknown>;
110
+ readonly result_status: AccessLogResultStatus;
111
+ readonly failure_reason?: string;
112
+ }
113
+ export interface AuditLogEvent {
114
+ readonly kind: typeof LOG_KIND.AUDIT;
115
+ readonly action: string;
116
+ readonly payload: AuditLogPayload;
117
+ }
118
+ export interface DomainEventLogPayload {
119
+ readonly started_at: string;
120
+ readonly correlation_id: string;
121
+ readonly request_id?: string;
122
+ readonly trace_id?: string;
123
+ readonly span_id?: string;
124
+ readonly tenant_id?: string;
125
+ readonly event_type: string;
126
+ readonly aggregate_type: string;
127
+ readonly aggregate_id: string;
128
+ readonly event_version?: number;
129
+ readonly payload: Record<string, unknown>;
130
+ readonly metadata?: Record<string, unknown>;
131
+ }
132
+ export interface DomainLogEvent {
133
+ readonly kind: typeof LOG_KIND.EVENT;
134
+ readonly domain: string;
135
+ readonly payload: DomainEventLogPayload;
136
+ }
137
+ export type LogEvent = AccessLogEvent | AuditLogEvent | DomainLogEvent;
138
+ export declare function buildLogRoutingKey(event: LogEvent, serviceName: string): string;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AUDIT_SEVERITY = exports.AUDIT_ACTOR_TYPE = exports.ACCESS_LOG_FAILURE_SOURCE = exports.ACCESS_LOG_OUTCOME = exports.ACCESS_LOG_RESULT_STATUS = exports.LOG_TRANSPORT = exports.LOG_KIND = void 0;
4
+ exports.buildLogRoutingKey = buildLogRoutingKey;
5
+ exports.LOG_KIND = {
6
+ ACCESS: 'access',
7
+ AUDIT: 'audit',
8
+ EVENT: 'event',
9
+ };
10
+ exports.LOG_TRANSPORT = {
11
+ HTTP: 'http',
12
+ GRAPHQL: 'graphql',
13
+ GRPC: 'grpc',
14
+ RABBITMQ: 'rabbitmq',
15
+ INTERNAL: 'internal',
16
+ };
17
+ exports.ACCESS_LOG_RESULT_STATUS = {
18
+ SUCCESS: 'SUCCESS',
19
+ FAILURE: 'FAILURE',
20
+ };
21
+ exports.ACCESS_LOG_OUTCOME = {
22
+ SUCCESS: 'success',
23
+ ERROR: 'error',
24
+ TIMEOUT: 'timeout',
25
+ ABORTED: 'aborted',
26
+ CRASHED: 'crashed',
27
+ };
28
+ exports.ACCESS_LOG_FAILURE_SOURCE = {
29
+ APPLICATION: 'application',
30
+ TRANSPORT: 'transport',
31
+ UPSTREAM: 'upstream',
32
+ CLIENT: 'client',
33
+ };
34
+ exports.AUDIT_ACTOR_TYPE = {
35
+ ACCOUNT: 'ACCOUNT',
36
+ SYSTEM: 'SYSTEM',
37
+ AUTOMATION: 'AUTOMATION',
38
+ DEVICE: 'DEVICE',
39
+ ANONYMOUS: 'ANONYMOUS',
40
+ };
41
+ exports.AUDIT_SEVERITY = {
42
+ INFO: 'INFO',
43
+ WARN: 'WARN',
44
+ ERROR: 'ERROR',
45
+ };
46
+ function buildLogRoutingKey(event, serviceName) {
47
+ switch (event.kind) {
48
+ case exports.LOG_KIND.ACCESS:
49
+ return `access.${event.transport}.${serviceName}`;
50
+ case exports.LOG_KIND.AUDIT:
51
+ return `audit.${serviceName}.${event.action}`;
52
+ case exports.LOG_KIND.EVENT:
53
+ return `event.${serviceName}.${event.domain}`;
54
+ }
55
+ }
56
+ //# sourceMappingURL=log-event.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-event.types.js","sourceRoot":"","sources":["../../src/log-events/log-event.types.ts"],"names":[],"mappings":";;;AA+OA,gDAYC;AA5OY,QAAA,QAAQ,GAAG;IACtB,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,OAAO;CACN,CAAC;AAIE,QAAA,aAAa,GAAG;IAC3B,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;CACZ,CAAC;AAIE,QAAA,wBAAwB,GAAG;IACtC,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;CACV,CAAC;AAKE,QAAA,kBAAkB,GAAG;IAChC,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;CACV,CAAC;AAKE,QAAA,yBAAyB,GAAG;IACvC,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;CACR,CAAC;AAKE,QAAA,gBAAgB,GAAG;IAC9B,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,WAAW;CACd,CAAC;AAKE,QAAA,cAAc,GAAG;IAC5B,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;CACN,CAAC;AAkKX,SAAgB,kBAAkB,CAChC,KAAe,EACf,WAAmB;IAEnB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,gBAAQ,CAAC,MAAM;YAClB,OAAO,UAAU,KAAK,CAAC,SAAS,IAAI,WAAW,EAAE,CAAC;QACpD,KAAK,gBAAQ,CAAC,KAAK;YACjB,OAAO,SAAS,WAAW,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAChD,KAAK,gBAAQ,CAAC,KAAK;YACjB,OAAO,SAAS,WAAW,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;IAClD,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { LogEvent } from './log-event.types';
2
+ export declare abstract class LogPublisher {
3
+ abstract publish(event: LogEvent): Promise<void>;
4
+ flush(_maxWaitMs?: number): Promise<void>;
5
+ }
6
+ export declare class NoopLogPublisher extends LogPublisher {
7
+ publish(_event: LogEvent): Promise<void>;
8
+ }
@@ -0,0 +1,26 @@
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.NoopLogPublisher = exports.LogPublisher = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ class LogPublisher {
12
+ async flush(_maxWaitMs) {
13
+ return;
14
+ }
15
+ }
16
+ exports.LogPublisher = LogPublisher;
17
+ let NoopLogPublisher = class NoopLogPublisher extends LogPublisher {
18
+ async publish(_event) {
19
+ return;
20
+ }
21
+ };
22
+ exports.NoopLogPublisher = NoopLogPublisher;
23
+ exports.NoopLogPublisher = NoopLogPublisher = __decorate([
24
+ (0, common_1.Injectable)()
25
+ ], NoopLogPublisher);
26
+ //# sourceMappingURL=log-publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-publisher.js","sourceRoot":"","sources":["../../src/log-events/log-publisher.ts"],"names":[],"mappings":";;;;;;;;;AAeA,2CAA4C;AAG5C,MAAsB,YAAY;IAOhC,KAAK,CAAC,KAAK,CAAC,UAAmB;QAC7B,OAAO;IACT,CAAC;CACF;AAVD,oCAUC;AAOM,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,YAAY;IAChD,KAAK,CAAC,OAAO,CAAC,MAAgB;QAC5B,OAAO;IACT,CAAC;CACF,CAAA;AAJY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;GACA,gBAAgB,CAI5B"}
@@ -0,0 +1,34 @@
1
+ import { type OnModuleDestroy, type OnModuleInit } from '@nestjs/common';
2
+ import { LogPublisher } from './log-publisher';
3
+ import { type LogEvent } from './log-event.types';
4
+ export interface RabbitMqLogPublisherPort {
5
+ publish(exchange: string, routingKey: string, buffer: Buffer, options?: Record<string, unknown>): Promise<void>;
6
+ }
7
+ export interface RabbitMqLogPublisherOptions {
8
+ readonly publisher: RabbitMqLogPublisherPort;
9
+ readonly serviceName: string;
10
+ readonly exchange?: string;
11
+ readonly bufferCapacity?: number;
12
+ readonly drainIntervalMs?: number;
13
+ readonly drainBatchSize?: number;
14
+ }
15
+ export declare class RabbitMqLogPublisher extends LogPublisher implements OnModuleInit, OnModuleDestroy {
16
+ private readonly logger;
17
+ private readonly port;
18
+ private readonly serviceName;
19
+ private readonly exchange;
20
+ private readonly buffer;
21
+ private readonly drainIntervalMs;
22
+ private readonly drainBatchSize;
23
+ private drainTimer;
24
+ private draining;
25
+ constructor(options: RabbitMqLogPublisherOptions);
26
+ static create(options: RabbitMqLogPublisherOptions): RabbitMqLogPublisher;
27
+ onModuleInit(): void;
28
+ onModuleDestroy(): Promise<void>;
29
+ publish(event: LogEvent): Promise<void>;
30
+ flush(maxWaitMs?: number): Promise<void>;
31
+ private drainBuffer;
32
+ private tryDirectPublish;
33
+ protected serializeEvent(event: LogEvent): Buffer;
34
+ }
@@ -0,0 +1,159 @@
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 RabbitMqLogPublisher_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.RabbitMqLogPublisher = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const span_decorator_1 = require("../tracing/span.decorator");
16
+ const log_publisher_1 = require("./log-publisher");
17
+ const ring_buffer_1 = require("./ring-buffer");
18
+ const log_event_types_1 = require("./log-event.types");
19
+ const DEFAULT_EXCHANGE = 'xenonsmart.logs';
20
+ const DEFAULT_BUFFER_CAPACITY = 10_000;
21
+ const DEFAULT_DRAIN_INTERVAL_MS = 2_000;
22
+ const DEFAULT_DRAIN_BATCH_SIZE = 100;
23
+ const DEFAULT_FLUSH_TIMEOUT_MS = 5_000;
24
+ let RabbitMqLogPublisher = RabbitMqLogPublisher_1 = class RabbitMqLogPublisher extends log_publisher_1.LogPublisher {
25
+ logger = new common_1.Logger(RabbitMqLogPublisher_1.name);
26
+ port;
27
+ serviceName;
28
+ exchange;
29
+ buffer;
30
+ drainIntervalMs;
31
+ drainBatchSize;
32
+ drainTimer = null;
33
+ draining = false;
34
+ constructor(options) {
35
+ super();
36
+ this.port = options.publisher;
37
+ this.serviceName = options.serviceName;
38
+ this.exchange =
39
+ options.exchange ??
40
+ process.env.RABBITMQ_LOGS_EXCHANGE ??
41
+ DEFAULT_EXCHANGE;
42
+ this.buffer = new ring_buffer_1.RingBuffer({
43
+ capacity: options.bufferCapacity ?? DEFAULT_BUFFER_CAPACITY,
44
+ });
45
+ this.drainIntervalMs =
46
+ options.drainIntervalMs ?? DEFAULT_DRAIN_INTERVAL_MS;
47
+ this.drainBatchSize =
48
+ options.drainBatchSize ?? DEFAULT_DRAIN_BATCH_SIZE;
49
+ }
50
+ static create(options) {
51
+ return new RabbitMqLogPublisher_1(options);
52
+ }
53
+ onModuleInit() {
54
+ this.drainTimer = setInterval(() => {
55
+ void this.drainBuffer();
56
+ }, this.drainIntervalMs);
57
+ this.logger.log(`RabbitMqLogPublisher ready (exchange=${this.exchange}, bufferCapacity=${this.buffer.maxCapacity})`);
58
+ }
59
+ async onModuleDestroy() {
60
+ if (this.drainTimer) {
61
+ clearInterval(this.drainTimer);
62
+ this.drainTimer = null;
63
+ }
64
+ await this.flush(DEFAULT_FLUSH_TIMEOUT_MS);
65
+ }
66
+ async publish(event) {
67
+ const delivered = await this.tryDirectPublish(event);
68
+ if (!delivered) {
69
+ this.buffer.push(event);
70
+ this.logger.debug(`Log publish buffered (kind=${event.kind}, bufferLen=${this.buffer.length}, drops=${this.buffer.totalDrops})`);
71
+ }
72
+ }
73
+ async flush(maxWaitMs = DEFAULT_FLUSH_TIMEOUT_MS) {
74
+ const deadline = Date.now() + maxWaitMs;
75
+ while (this.buffer.length > 0 && Date.now() < deadline) {
76
+ const drained = await this.drainBuffer();
77
+ if (!drained && this.buffer.length > 0) {
78
+ await new Promise((resolve) => setTimeout(resolve, 100));
79
+ }
80
+ }
81
+ if (this.buffer.length > 0) {
82
+ this.logger.warn(`LogPublisher flush timeout — ${this.buffer.length} events remained unflushed`);
83
+ }
84
+ }
85
+ async drainBuffer() {
86
+ if (this.draining) {
87
+ return false;
88
+ }
89
+ if (this.buffer.length === 0) {
90
+ return true;
91
+ }
92
+ this.draining = true;
93
+ try {
94
+ const maxPerTick = Math.min(this.drainBatchSize, this.buffer.length);
95
+ for (let i = 0; i < maxPerTick; i++) {
96
+ const event = this.buffer.shift();
97
+ if (!event) {
98
+ break;
99
+ }
100
+ const delivered = await this.tryDirectPublish(event);
101
+ if (!delivered) {
102
+ this.buffer.push(event);
103
+ return false;
104
+ }
105
+ }
106
+ return true;
107
+ }
108
+ finally {
109
+ this.draining = false;
110
+ }
111
+ }
112
+ async tryDirectPublish(event) {
113
+ const routingKey = (0, log_event_types_1.buildLogRoutingKey)(event, this.serviceName);
114
+ const body = this.serializeEvent(event);
115
+ try {
116
+ await this.port.publish(this.exchange, routingKey, body, {
117
+ persistent: true,
118
+ contentType: 'application/json',
119
+ headers: {
120
+ 'x-log-kind': event.kind,
121
+ 'x-source-service': this.serviceName,
122
+ },
123
+ });
124
+ return true;
125
+ }
126
+ catch (error) {
127
+ const message = error instanceof Error ? error.message : String(error);
128
+ this.logger.debug(`Log direct publish failed (kind=${event.kind}, routingKey=${routingKey}): ${message}`);
129
+ return false;
130
+ }
131
+ }
132
+ serializeEvent(event) {
133
+ const envelope = {
134
+ kind: event.kind,
135
+ serviceName: this.serviceName,
136
+ publishedAt: new Date().toISOString(),
137
+ ...event,
138
+ };
139
+ return Buffer.from(JSON.stringify(envelope));
140
+ }
141
+ };
142
+ exports.RabbitMqLogPublisher = RabbitMqLogPublisher;
143
+ __decorate([
144
+ (0, span_decorator_1.Span)('logs.publish'),
145
+ __metadata("design:type", Function),
146
+ __metadata("design:paramtypes", [Object]),
147
+ __metadata("design:returntype", Promise)
148
+ ], RabbitMqLogPublisher.prototype, "publish", null);
149
+ __decorate([
150
+ (0, span_decorator_1.Span)('logs.drain'),
151
+ __metadata("design:type", Function),
152
+ __metadata("design:paramtypes", []),
153
+ __metadata("design:returntype", Promise)
154
+ ], RabbitMqLogPublisher.prototype, "drainBuffer", null);
155
+ exports.RabbitMqLogPublisher = RabbitMqLogPublisher = RabbitMqLogPublisher_1 = __decorate([
156
+ (0, common_1.Injectable)(),
157
+ __metadata("design:paramtypes", [Object])
158
+ ], RabbitMqLogPublisher);
159
+ //# sourceMappingURL=rabbitmq-log-publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rabbitmq-log-publisher.js","sourceRoot":"","sources":["../../src/log-events/rabbitmq-log-publisher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export declare const REDACTED_VALUE: string;
2
+ export declare const DEFAULT_REDACTED_HEADER_KEYS: ReadonlyArray<string>;
3
+ export declare const DEFAULT_REDACTED_BODY_KEYS: ReadonlyArray<string>;
4
+ export interface RedactionOptions {
5
+ readonly keys?: ReadonlyArray<string>;
6
+ readonly maxDepth?: number;
7
+ }
8
+ export declare function redactHeaders(headers: Record<string, string | string[] | undefined> | undefined, options?: RedactionOptions): Record<string, string>;
9
+ export declare function redactObject<T>(input: T, options?: RedactionOptions): T;
10
+ export interface TruncateBodyResult<T> {
11
+ readonly body: T | string;
12
+ readonly truncated: boolean;
13
+ readonly size_bytes: number;
14
+ }
15
+ export declare function truncateBody<T>(body: T, maxBytes: number): TruncateBodyResult<T>;
16
+ export declare function hashEmail(email: string, tenantSalt: string): string;
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_REDACTED_BODY_KEYS = exports.DEFAULT_REDACTED_HEADER_KEYS = exports.REDACTED_VALUE = void 0;
4
+ exports.redactHeaders = redactHeaders;
5
+ exports.redactObject = redactObject;
6
+ exports.truncateBody = truncateBody;
7
+ exports.hashEmail = hashEmail;
8
+ const crypto_1 = require("crypto");
9
+ exports.REDACTED_VALUE = '[REDACTED]';
10
+ exports.DEFAULT_REDACTED_HEADER_KEYS = [
11
+ 'authorization',
12
+ 'cookie',
13
+ 'set-cookie',
14
+ 'proxy-authorization',
15
+ 'x-api-key',
16
+ 'x-auth-token',
17
+ 'x-access-token',
18
+ 'x-refresh-token',
19
+ 'x-user-token',
20
+ 'x-session-token',
21
+ 'x-csrf-token',
22
+ 'x-amz-security-token',
23
+ ];
24
+ exports.DEFAULT_REDACTED_BODY_KEYS = [
25
+ 'password',
26
+ 'new_password',
27
+ 'old_password',
28
+ 'password_confirmation',
29
+ 'token',
30
+ 'access_token',
31
+ 'refresh_token',
32
+ 'id_token',
33
+ 'api_key',
34
+ 'apikey',
35
+ 'secret',
36
+ 'client_secret',
37
+ 'private_key',
38
+ 'credit_card',
39
+ 'card_number',
40
+ 'cvv',
41
+ 'cvc',
42
+ 'ssn',
43
+ 'tc_kimlik',
44
+ 'tc_kimlik_no',
45
+ 'pin',
46
+ 'otp',
47
+ 'mfa_code',
48
+ 'verification_code',
49
+ ];
50
+ const DEFAULT_MAX_DEPTH = 10;
51
+ function normalizeKey(key) {
52
+ return key.toLowerCase().trim();
53
+ }
54
+ function toKeySet(keys) {
55
+ const set = new Set();
56
+ for (const key of keys) {
57
+ set.add(normalizeKey(key));
58
+ }
59
+ return set;
60
+ }
61
+ function redactHeaders(headers, options = {}) {
62
+ if (!headers) {
63
+ return {};
64
+ }
65
+ const redactedKeys = toKeySet(options.keys ?? exports.DEFAULT_REDACTED_HEADER_KEYS);
66
+ const redacted = {};
67
+ for (const [rawKey, rawValue] of Object.entries(headers)) {
68
+ if (rawValue === undefined) {
69
+ continue;
70
+ }
71
+ const normalizedKey = normalizeKey(rawKey);
72
+ const value = Array.isArray(rawValue) ? rawValue.join(',') : rawValue;
73
+ redacted[rawKey] = redactedKeys.has(normalizedKey) ? exports.REDACTED_VALUE : value;
74
+ }
75
+ return redacted;
76
+ }
77
+ function redactObject(input, options = {}) {
78
+ const redactedKeys = toKeySet(options.keys ?? exports.DEFAULT_REDACTED_BODY_KEYS);
79
+ const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
80
+ return recursiveRedact(input, redactedKeys, maxDepth, 0);
81
+ }
82
+ function recursiveRedact(value, keys, maxDepth, depth) {
83
+ if (depth >= maxDepth) {
84
+ return value;
85
+ }
86
+ if (value === null || value === undefined) {
87
+ return value;
88
+ }
89
+ if (Array.isArray(value)) {
90
+ return value.map((item) => recursiveRedact(item, keys, maxDepth, depth + 1));
91
+ }
92
+ if (typeof value === 'object') {
93
+ const source = value;
94
+ const next = {};
95
+ for (const [rawKey, rawValue] of Object.entries(source)) {
96
+ const normalizedKey = normalizeKey(rawKey);
97
+ if (keys.has(normalizedKey)) {
98
+ next[rawKey] = exports.REDACTED_VALUE;
99
+ }
100
+ else {
101
+ next[rawKey] = recursiveRedact(rawValue, keys, maxDepth, depth + 1);
102
+ }
103
+ }
104
+ return next;
105
+ }
106
+ return value;
107
+ }
108
+ function truncateBody(body, maxBytes) {
109
+ if (body === undefined || body === null) {
110
+ return { body, truncated: false, size_bytes: 0 };
111
+ }
112
+ let serialized;
113
+ try {
114
+ serialized = typeof body === 'string' ? body : JSON.stringify(body);
115
+ }
116
+ catch {
117
+ return {
118
+ body: '[UNSERIALIZABLE]',
119
+ truncated: true,
120
+ size_bytes: 0,
121
+ };
122
+ }
123
+ const sizeBytes = Buffer.byteLength(serialized, 'utf8');
124
+ if (sizeBytes <= maxBytes) {
125
+ return { body, truncated: false, size_bytes: sizeBytes };
126
+ }
127
+ const truncatedText = serialized.slice(0, Math.max(0, maxBytes - '[...TRUNCATED]'.length));
128
+ return {
129
+ body: `${truncatedText}[...TRUNCATED]`,
130
+ truncated: true,
131
+ size_bytes: sizeBytes,
132
+ };
133
+ }
134
+ function hashEmail(email, tenantSalt) {
135
+ const normalized = email.trim().toLowerCase();
136
+ return (0, crypto_1.createHash)('sha256')
137
+ .update(`${tenantSalt}:${normalized}`)
138
+ .digest('hex');
139
+ }
140
+ //# sourceMappingURL=redaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redaction.js","sourceRoot":"","sources":["../../src/log-events/redaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface RingBufferOptions {
2
+ readonly capacity: number;
3
+ }
4
+ export declare class RingBuffer<T> {
5
+ private readonly items;
6
+ private readonly capacity;
7
+ private head;
8
+ private tail;
9
+ private count;
10
+ private dropCount;
11
+ constructor(options: RingBufferOptions);
12
+ push(item: T): boolean;
13
+ shift(): T | undefined;
14
+ get length(): number;
15
+ get maxCapacity(): number;
16
+ get totalDrops(): number;
17
+ resetDropCounter(): void;
18
+ }