@tigthor/kokocrypt
Version:
Enhanced Fortress Edition - Secure, quantum-resistant, high-performance encryption package
227 lines • 10.4 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var KafkaService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.KafkaService = void 0;
const common_1 = require("@nestjs/common");
const microservices_1 = require("@nestjs/microservices");
const crypto_service_1 = require("../core/crypto.service");
const rxjs_1 = require("rxjs");
const sodiumNative = __importStar(require("sodium-native"));
let KafkaService = KafkaService_1 = class KafkaService {
logError(message, error) {
if (this.isTestEnv) {
this.logger.debug(message, error);
return;
}
this.logger.error(message, error);
}
constructor(cryptoService, client) {
this.cryptoService = cryptoService;
this.client = client;
this.logger = new common_1.Logger(KafkaService_1.name);
this.topics = [
'test.topic',
'test.batch',
'test.errors',
'test.performance',
];
this.isTestEnv = process.env.NODE_ENV === 'test' || !!process.env.JEST_WORKER_ID;
}
async onModuleInit() {
try {
await this.client.connect();
this.logger.log('✓ Connected to Kafka');
for (const topic of this.topics) {
this.client.subscribeToResponseOf(topic);
}
this.logger.log(`✓ Subscribed to response topics: ${this.topics.join(', ')}`);
}
catch (error) {
this.logError('❌ Failed to initialize Kafka service:', error);
throw new common_1.ServiceUnavailableException('Failed to connect to Kafka service');
}
}
async onModuleDestroy() {
try {
await this.client.close();
this.logger.log('✓ Disconnected from Kafka');
}
catch (error) {
this.logError('❌ Error disconnecting from Kafka:', error);
}
}
async sendMessage(topic, message, key) {
var _a, _b;
try {
if (key.length !== sodiumNative.crypto_secretbox_KEYBYTES) {
throw new common_1.BadRequestException(`Invalid key length. Expected ${sodiumNative.crypto_secretbox_KEYBYTES} bytes`);
}
this.logger.debug(`📤 Sending message to ${topic}`);
if (!message || typeof message !== 'object') {
throw new common_1.BadRequestException('Invalid message format');
}
const encryptedMessage = await this.cryptoService.boxRaw(Buffer.from(JSON.stringify(message)), key);
const response = (await (0, rxjs_1.firstValueFrom)(this.client.send(topic, {
value: encryptedMessage.toString('base64'),
timestamp: Date.now().toString(),
})));
this.logger.debug(`✓ Message sent to topic ${topic}`);
return response;
}
catch (err) {
const error = err;
this.logError(`❌ Error sending message to ${topic}:`, error);
if (error instanceof common_1.BadRequestException) {
throw error;
}
if ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('ECONNREFUSED')) {
throw new common_1.ServiceUnavailableException('Kafka service is not available');
}
if ((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('decryption failed')) {
throw new common_1.BadRequestException('Message encryption failed');
}
throw error;
}
}
async sendBatch(topic, messages, key) {
var _a;
try {
if (key.length !== sodiumNative.crypto_secretbox_KEYBYTES) {
throw new common_1.BadRequestException(`Invalid key length. Expected ${sodiumNative.crypto_secretbox_KEYBYTES} bytes`);
}
if (!Array.isArray(messages) || messages.length === 0) {
throw new common_1.BadRequestException('Invalid batch message format');
}
this.logger.debug(`📤 Sending batch of ${messages.length} messages to ${topic}`);
const encryptedMessages = await Promise.all(messages.map(async (message) => {
if (!message || typeof message !== 'object') {
throw new common_1.BadRequestException('Invalid message in batch');
}
const encrypted = await this.cryptoService.boxRaw(Buffer.from(JSON.stringify(message)), key);
return {
value: encrypted.toString('base64'),
timestamp: Date.now().toString(),
};
}));
const responses = (await Promise.all(encryptedMessages.map(msg => (0, rxjs_1.firstValueFrom)(this.client.send(topic, msg)))));
this.logger.debug(`✓ Batch sent to topic ${topic}`);
return responses;
}
catch (err) {
const error = err;
this.logError(`❌ Error sending batch to ${topic}:`, error);
if (error instanceof common_1.BadRequestException) {
throw error;
}
if ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('ECONNREFUSED')) {
throw new common_1.ServiceUnavailableException('Kafka service is not available');
}
throw error;
}
}
async sendInvalidMessage() {
try {
this.logger.debug('📤 Sending invalid message for error testing');
const response = (await (0, rxjs_1.firstValueFrom)(this.client.send('test.errors', {
value: 'invalid_data',
timestamp: Date.now().toString(),
})));
return response;
}
catch (error) {
this.logError('❌ Expected error sending invalid message:', error);
throw error;
}
}
async runPerformanceTest(messageCount, key) {
var _a;
try {
if (key.length !== sodiumNative.crypto_secretbox_KEYBYTES) {
throw new common_1.BadRequestException(`Invalid key length. Expected ${sodiumNative.crypto_secretbox_KEYBYTES} bytes`);
}
if (!Number.isInteger(messageCount) || messageCount <= 0) {
throw new common_1.BadRequestException('Invalid message count');
}
this.logger.debug(`📊 Running performance test with ${messageCount} messages`);
const startTime = Date.now();
const messages = Array.from({ length: messageCount }, (_, i) => ({
id: i,
data: `Performance test message ${i}`,
timestamp: Date.now(),
}));
const responses = (await Promise.all(messages.map(message => this.sendMessage('test.performance', message, key))));
const endTime = Date.now();
const duration = (endTime - startTime) / 1000;
const messagesPerSecond = messageCount / duration;
this.logger.debug(`✓ Performance test completed:
- Messages sent: ${messageCount}
- Duration: ${duration.toFixed(2)} seconds
- Rate: ${messagesPerSecond.toFixed(2)} messages/second`);
return responses;
}
catch (err) {
const error = err;
this.logError('❌ Error in performance test:', error);
if (error instanceof common_1.BadRequestException) {
throw error;
}
if ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('ECONNREFUSED')) {
throw new common_1.ServiceUnavailableException('Kafka service is not available');
}
throw error;
}
}
};
exports.KafkaService = KafkaService;
exports.KafkaService = KafkaService = KafkaService_1 = __decorate([
(0, common_1.Injectable)(),
__param(1, (0, common_1.Inject)('KAFKA_CLIENT')),
__metadata("design:paramtypes", [crypto_service_1.CryptoService,
microservices_1.ClientKafka])
], KafkaService);
//# sourceMappingURL=kafka.service.js.map