@message-in-the-middle/core
Version:
Framework-agnostic middleware pattern for message queue processing. Core package with all middlewares.
83 lines • 3.45 kB
JavaScript
;
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