UNPKG

@message-in-the-middle/core

Version:

Framework-agnostic middleware pattern for message queue processing. Core package with all middlewares.

83 lines 3.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EncryptOutboundMiddleware = exports.DecryptInboundMiddleware = void 0; const DEFAULT_MAX_DECRYPTED_SIZE = 10 * 1024 * 1024; class DecryptInboundMiddleware { encryptionService; fields; maxDecryptedSize; constructor(encryptionService, fields, options) { this.encryptionService = encryptionService; this.fields = fields; this.maxDecryptedSize = options?.maxDecryptedSize ?? DEFAULT_MAX_DECRYPTED_SIZE; } sanitizeObject(obj) { if (obj === null || typeof obj !== 'object') { return obj; } if (Array.isArray(obj)) { return obj.map(item => this.sanitizeObject(item)); } const sanitized = {}; const forbidden = ['__proto__', 'constructor', 'prototype']; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { if (!forbidden.includes(key)) { sanitized[key] = this.sanitizeObject(obj[key]); } } } return sanitized; } async process(context, next) { if (this.fields && typeof context.message === 'object' && context.message !== null) { const messageObj = context.message; for (const field of this.fields) { if (messageObj[field]) { const decrypted = await this.encryptionService.decrypt(messageObj[field]); if (decrypted.length > this.maxDecryptedSize) { throw new Error(`Decrypted field "${field}" size (${decrypted.length} bytes) exceeds maximum allowed size (${this.maxDecryptedSize} bytes)`); } messageObj[field] = decrypted; } } } else if (typeof context.message === 'string') { const decrypted = await this.encryptionService.decrypt(context.message); if (decrypted.length > this.maxDecryptedSize) { throw new Error(`Decrypted message size (${decrypted.length} bytes) exceeds maximum allowed size (${this.maxDecryptedSize} bytes)`); } const parsed = JSON.parse(decrypted); context.message = this.sanitizeObject(parsed); } context.metadata.decrypted = true; await next(); } } exports.DecryptInboundMiddleware = DecryptInboundMiddleware; class EncryptOutboundMiddleware { encryptionService; fields; constructor(encryptionService, fields) { this.encryptionService = encryptionService; this.fields = fields; } async processOutbound(context, next) { if (this.fields && typeof context.message === 'object' && context.message !== null) { const messageObj = context.message; for (const field of this.fields) { if (messageObj[field]) { messageObj[field] = await this.encryptionService.encrypt(JSON.stringify(messageObj[field])); } } } else { const encrypted = await this.encryptionService.encrypt(JSON.stringify(context.message)); context.message = encrypted; } context.metadata.encrypted = true; await next(); } } exports.EncryptOutboundMiddleware = EncryptOutboundMiddleware; //# sourceMappingURL=encryption.middleware.js.map