UNPKG

e2ee-adapter

Version:

Plug-and-play End-to-End Encryption middleware for Express.js and NestJS using hybrid AES-CBC + RSA encryption with secure key exchange

89 lines 3.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createE2EEMiddleware = createE2EEMiddleware; const e2ee_common_1 = require("../utils/e2ee-common"); /** * Create E2EE middleware for Express.js * @param options - Middleware configuration options * @returns E2EEMiddleware */ function createE2EEMiddleware(options) { const { config, onError, onDecrypt, onEncrypt } = options; // Validate configuration (0, e2ee_common_1.validateConfig)(config); // Merge configuration with defaults const finalConfig = (0, e2ee_common_1.mergeConfigWithDefaults)(config); /** * Create E2EE error */ function createError(message, code, statusCode = 400) { return (0, e2ee_common_1.createE2EEError)(message, code, statusCode); } /** * Main middleware function */ return async (req, res, next) => { try { // Process request and check if it should be handled const processingResult = (0, e2ee_common_1.processRequest)(req, finalConfig, createError); if (processingResult.shouldContinue) { return next(); } // Handle request decryption let e2eeContext = await (0, e2ee_common_1.handleRequestDecryption)(req, finalConfig, createError, onDecrypt); // Setup encryption context for response-only encryption if needed if (!finalConfig.enableRequestDecryption && finalConfig.enableResponseEncryption) { e2eeContext = await (0, e2ee_common_1.setupResponseEncryptionContext)(req, finalConfig, createError); } // Store encryption context for response if (e2eeContext) { req.e2ee = e2eeContext; } // Handle response encryption only if (finalConfig.enableResponseEncryption) { // Store original send method const originalSend = res.send; // Override send method to encrypt response data res.send = function (data) { const e2eeContext = req.e2ee; if (!e2eeContext || !e2eeContext.aesKey || !e2eeContext.iv) { // If no encryption context, send original data return originalSend.call(this, data); } // Handle encryption asynchronously (0, e2ee_common_1.handleResponseEncryption)(data, e2eeContext, createError, onEncrypt, res) .then((encryptedData) => { // Send the encrypted data originalSend.call(this, encryptedData); }) .catch((error) => { if (onError) { onError(error, req, res); } // Send error response originalSend.call(this, { error: 'Encryption failed', message: error instanceof Error ? error.message : 'Unknown error', }); }); // Return the response object for chaining return this; }; } next(); } catch (error) { if (onError) { onError(error, req, res); } const e2eeError = error; res.status(e2eeError.statusCode || 400).json({ error: 'E2EE Error', code: e2eeError.code || 'UNKNOWN_ERROR', message: e2eeError.message, }); } }; } //# sourceMappingURL=e2ee.js.map