Updated all text to English

This commit is contained in:
lockbitchat
2025-08-13 14:48:24 -04:00
parent 0b8f5d345c
commit b71de54720

View File

@@ -2,7 +2,7 @@ class EnhancedSecureWebRTCManager {
constructor(onMessage, onStatusChange, onKeyExchange, onVerificationRequired, onAnswerError = null) { constructor(onMessage, onStatusChange, onKeyExchange, onVerificationRequired, onAnswerError = null) {
// Проверяем доступность глобального объекта // Проверяем доступность глобального объекта
if (!window.EnhancedSecureCryptoUtils) { if (!window.EnhancedSecureCryptoUtils) {
throw new Error('EnhancedSecureCryptoUtils не загружен. Убедитесь, что модуль загружен первым.'); throw new Error('EnhancedSecureCryptoUtils is not loaded. Please ensure the module is loaded first.');
} }
this.peerConnection = null; this.peerConnection = null;
@@ -109,7 +109,7 @@ class EnhancedSecureWebRTCManager {
return false; return false;
} }
// Отправляем сигнал о ротации ключей партнеру // Sending key rotation signal to partner.
const rotationSignal = { const rotationSignal = {
type: 'key_rotation_signal', type: 'key_rotation_signal',
newVersion: this.currentKeyVersion + 1, newVersion: this.currentKeyVersion + 1,
@@ -118,14 +118,14 @@ class EnhancedSecureWebRTCManager {
this.dataChannel.send(JSON.stringify(rotationSignal)); this.dataChannel.send(JSON.stringify(rotationSignal));
// Ждем подтверждения от партнера перед ротацией // Waiting for partner's confirmation before rotation.
return new Promise((resolve) => { return new Promise((resolve) => {
this.pendingRotation = { this.pendingRotation = {
newVersion: this.currentKeyVersion + 1, newVersion: this.currentKeyVersion + 1,
resolve: resolve resolve: resolve
}; };
// Таймаут на случай если партнер не ответит // Timeout in case the partner doesn't respond.
setTimeout(() => { setTimeout(() => {
if (this.pendingRotation) { if (this.pendingRotation) {
this.pendingRotation.resolve(false); this.pendingRotation.resolve(false);
@@ -159,7 +159,7 @@ class EnhancedSecureWebRTCManager {
// PFS: Get keys for specific version (for decryption) // PFS: Get keys for specific version (for decryption)
getKeysForVersion(version) { getKeysForVersion(version) {
// Сначала проверяем старые ключи (включая версию 0) // First, we check the old keys (including version 0).
const oldKeySet = this.oldKeys.get(version); const oldKeySet = this.oldKeys.get(version);
if (oldKeySet && oldKeySet.encryptionKey && oldKeySet.macKey && oldKeySet.metadataKey) { if (oldKeySet && oldKeySet.encryptionKey && oldKeySet.macKey && oldKeySet.metadataKey) {
return { return {
@@ -169,7 +169,7 @@ class EnhancedSecureWebRTCManager {
}; };
} }
// Если это текущая версия, возвращаем текущие ключи // If this is the current version, return the current keys.
if (version === this.currentKeyVersion) { if (version === this.currentKeyVersion) {
if (this.encryptionKey && this.macKey && this.metadataKey) { if (this.encryptionKey && this.macKey && this.metadataKey) {
return { return {
@@ -213,12 +213,12 @@ class EnhancedSecureWebRTCManager {
} else if (state === 'connected' && this.isVerified) { } else if (state === 'connected' && this.isVerified) {
this.onStatusChange('connected'); this.onStatusChange('connected');
} else if (state === 'disconnected' || state === 'closed') { } else if (state === 'disconnected' || state === 'closed') {
// Если это намеренное отключение, сразу очищаем // If this is an intentional disconnect, clear immediately.
if (this.intentionalDisconnect) { if (this.intentionalDisconnect) {
this.onStatusChange('disconnected'); this.onStatusChange('disconnected');
setTimeout(() => this.cleanupConnection(), 100); setTimeout(() => this.cleanupConnection(), 100);
} else { } else {
// Неожиданное отключение - пытаемся уведомить партнера // Unexpected disconnection — attempting to notify partner.
this.onStatusChange('reconnecting'); this.onStatusChange('reconnecting');
this.handleUnexpectedDisconnect(); this.handleUnexpectedDisconnect();
} }
@@ -261,11 +261,11 @@ class EnhancedSecureWebRTCManager {
if (!this.intentionalDisconnect) { if (!this.intentionalDisconnect) {
this.onStatusChange('reconnecting'); this.onStatusChange('reconnecting');
this.onMessage('🔄 Канал данных закрыт. Попытка восстановления...', 'system'); this.onMessage('🔄 Data channel closed. Attempting recovery...', 'system');
this.handleUnexpectedDisconnect(); this.handleUnexpectedDisconnect();
} else { } else {
this.onStatusChange('disconnected'); this.onStatusChange('disconnected');
this.onMessage('🔌 Соединение закрыто', 'system'); this.onMessage('🔌 Connection closed', 'system');
} }
this.stopHeartbeat(); this.stopHeartbeat();
@@ -334,22 +334,22 @@ class EnhancedSecureWebRTCManager {
throw new Error(`Invalid key types for version ${keyVersion}`); throw new Error(`Invalid key types for version ${keyVersion}`);
} }
// Используем более гибкую проверку sequence number // Using a more flexible sequence number check
const decryptedData = await window.EnhancedSecureCryptoUtils.decryptMessage( const decryptedData = await window.EnhancedSecureCryptoUtils.decryptMessage(
payload.data, payload.data,
keys.encryptionKey, keys.encryptionKey,
keys.macKey, keys.macKey,
keys.metadataKey, keys.metadataKey,
null // Отключаем строгую проверку sequence number null // Disabling strict sequence number verification
); );
// Проверяем replay attack по messageId // Checking for replay attack using messageId
if (this.processedMessageIds.has(decryptedData.messageId)) { if (this.processedMessageIds.has(decryptedData.messageId)) {
throw new Error('Duplicate message detected - possible replay attack'); throw new Error('Duplicate message detected - possible replay attack');
} }
this.processedMessageIds.add(decryptedData.messageId); this.processedMessageIds.add(decryptedData.messageId);
// Обновляем ожидаемый sequence number более гибко // Updating expected sequence number more flexibly
if (decryptedData.sequenceNumber >= this.expectedSequenceNumber) { if (decryptedData.sequenceNumber >= this.expectedSequenceNumber) {
this.expectedSequenceNumber = decryptedData.sequenceNumber + 1; this.expectedSequenceNumber = decryptedData.sequenceNumber + 1;
} }
@@ -411,13 +411,13 @@ class EnhancedSecureWebRTCManager {
window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Message processing error', { window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Message processing error', {
error: error.message error: error.message
}); });
this.onMessage(`Ошибка обработки: ${error.message}`, 'system'); this.onMessage(`Processing error: ${error.message}`, 'system');
} }
}; };
this.dataChannel.onerror = (error) => { this.dataChannel.onerror = (error) => {
console.error('Data channel error:', error); console.error('Data channel error:', error);
this.onMessage('❌ Ошибка канала данных', 'system'); this.onMessage('❌ Data channel error', 'system');
}; };
} }
@@ -546,7 +546,7 @@ class EnhancedSecureWebRTCManager {
}); });
if (!this.validateEnhancedOfferData(offerData)) { if (!this.validateEnhancedOfferData(offerData)) {
throw new Error('Неверный формат данных подключения'); throw new Error('Invalid connection data format');
} }
// Check rate limiting // Check rate limiting
@@ -602,7 +602,7 @@ class EnhancedSecureWebRTCManager {
privateKeyType: typeof this.ecdhKeyPair?.privateKey, privateKeyType: typeof this.ecdhKeyPair?.privateKey,
privateKeyAlgorithm: this.ecdhKeyPair?.privateKey?.algorithm?.name privateKeyAlgorithm: this.ecdhKeyPair?.privateKey?.algorithm?.name
}); });
throw new Error('Локальный ECDH приватный ключ не является CryptoKey'); throw new Error('The local ECDH private key is not a valid CryptoKey.');
} }
if (!(peerECDHPublicKey instanceof CryptoKey)) { if (!(peerECDHPublicKey instanceof CryptoKey)) {
@@ -610,7 +610,7 @@ class EnhancedSecureWebRTCManager {
publicKeyType: typeof peerECDHPublicKey, publicKeyType: typeof peerECDHPublicKey,
publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name
}); });
throw new Error('ECDH публичный ключ собеседника не является CryptoKey'); throw new Error('The peer"s ECDH public key is not a valid CryptoKey');
} }
// Store peer's public key for PFS key rotation // Store peer's public key for PFS key rotation
@@ -745,22 +745,22 @@ class EnhancedSecureWebRTCManager {
async handleSecureAnswer(answerData) { async handleSecureAnswer(answerData) {
try { try {
if (!answerData || answerData.type !== 'enhanced_secure_answer' || !answerData.sdp) { if (!answerData || answerData.type !== 'enhanced_secure_answer' || !answerData.sdp) {
throw new Error('Неверный формат ответа'); throw new Error('Invalid response format');
} }
// Import peer's ECDH public key from the signed package // Import peer's ECDH public key from the signed package
if (!answerData.ecdhPublicKey || !answerData.ecdhPublicKey.keyData) { if (!answerData.ecdhPublicKey || !answerData.ecdhPublicKey.keyData) {
throw new Error('Отсутствуют данные ECDH публичного ключа'); throw new Error('Missing ECDH public key data');
} }
// First, import and verify the ECDSA public key for signature verification // First, import and verify the ECDSA public key for signature verification
if (!answerData.ecdsaPublicKey || !answerData.ecdsaPublicKey.keyData) { if (!answerData.ecdsaPublicKey || !answerData.ecdsaPublicKey.keyData) {
throw new Error('Отсутствуют данные ECDSA публичного ключа для верификации подписи'); throw new Error('Missing ECDSA public key data for signature verification');
} }
// Additional MITM protection: Validate answer data structure // Additional MITM protection: Validate answer data structure
if (!answerData.timestamp || !answerData.version) { if (!answerData.timestamp || !answerData.version) {
throw new Error('Отсутствуют обязательные поля в данных ответа - возможная MITM атака'); throw new Error('Missing required fields in response data possible MITM attack');
} }
// MITM Protection: Verify session ID if present (for enhanced security) // MITM Protection: Verify session ID if present (for enhanced security)
@@ -769,7 +769,7 @@ class EnhancedSecureWebRTCManager {
expectedSessionId: this.sessionId, expectedSessionId: this.sessionId,
receivedSessionId: answerData.sessionId receivedSessionId: answerData.sessionId
}); });
throw new Error('Несоответствие идентификатора сессии - возможная MITM атака'); throw new Error('Session ID mismatch possible MITM attack');
} }
// Check for replay attacks (reject answers older than 1 hour) // Check for replay attacks (reject answers older than 1 hour)
@@ -782,10 +782,10 @@ class EnhancedSecureWebRTCManager {
// Уведомляем основной код о ошибке replay attack // Уведомляем основной код о ошибке replay attack
if (this.onAnswerError) { if (this.onAnswerError) {
this.onAnswerError('replay_attack', 'Данные ответа слишком старые - возможная атака повтора'); this.onAnswerError('replay_attack', 'Response data is too old possible replay attack');
} }
throw new Error('Данные ответа слишком старые - возможная атака повтора'); throw new Error('Response data is too old possible replay attack');
} }
// Check protocol version compatibility // Check protocol version compatibility
@@ -823,7 +823,7 @@ class EnhancedSecureWebRTCManager {
timestamp: answerData.timestamp, timestamp: answerData.timestamp,
version: answerData.version version: answerData.version
}); });
throw new Error('Недействительная подпись ECDSA ключа - возможная MITM атака'); throw new Error('Invalid ECDSA key signature possible MITM attack');
} }
window.EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDSA signature verification passed', { window.EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDSA signature verification passed', {
@@ -842,7 +842,7 @@ class EnhancedSecureWebRTCManager {
window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Invalid session salt detected - possible session hijacking', { window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Invalid session salt detected - possible session hijacking', {
saltLength: this.sessionSalt ? this.sessionSalt.length : 0 saltLength: this.sessionSalt ? this.sessionSalt.length : 0
}); });
throw new Error('Недействительная сессионная соль - возможная атака перехвата сессии'); throw new Error('Invalid session salt possible session hijacking attempt');
} }
// Verify that the session salt hasn't been tampered with // Verify that the session salt hasn't been tampered with
@@ -858,7 +858,7 @@ class EnhancedSecureWebRTCManager {
privateKeyType: typeof this.ecdhKeyPair?.privateKey, privateKeyType: typeof this.ecdhKeyPair?.privateKey,
privateKeyAlgorithm: this.ecdhKeyPair?.privateKey?.algorithm?.name privateKeyAlgorithm: this.ecdhKeyPair?.privateKey?.algorithm?.name
}); });
throw new Error('Локальный ECDH приватный ключ не является CryptoKey'); throw new Error('Local ECDH private key is not a CryptoKey');
} }
if (!(peerPublicKey instanceof CryptoKey)) { if (!(peerPublicKey instanceof CryptoKey)) {
@@ -866,7 +866,7 @@ class EnhancedSecureWebRTCManager {
publicKeyType: typeof peerPublicKey, publicKeyType: typeof peerPublicKey,
publicKeyAlgorithm: peerPublicKey?.algorithm?.name publicKeyAlgorithm: peerPublicKey?.algorithm?.name
}); });
throw new Error('ECDH публичный ключ собеседника не является CryptoKey'); throw new Error('Peer ECDH public key is not a CryptoKey');
} }
// Store peer's public key for PFS key rotation // Store peer's public key for PFS key rotation
@@ -898,7 +898,7 @@ class EnhancedSecureWebRTCManager {
macKeyAlgorithm: this.macKey?.algorithm?.name, macKeyAlgorithm: this.macKey?.algorithm?.name,
metadataKeyAlgorithm: this.metadataKey?.algorithm?.name metadataKeyAlgorithm: this.metadataKey?.algorithm?.name
}); });
throw new Error('Недействительные типы ключей после вывода'); throw new Error('Invalid key types after export');
} }
window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Encryption keys set in handleSecureAnswer', { window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Encryption keys set in handleSecureAnswer', {
@@ -938,8 +938,7 @@ class EnhancedSecureWebRTCManager {
} catch (error) { } catch (error) {
console.error('Enhanced secure answer handling failed:', error); console.error('Enhanced secure answer handling failed:', error);
this.onStatusChange('failed'); this.onStatusChange('failed');
// Уведомляем основной код о критических ошибках
if (this.onAnswerError) { if (this.onAnswerError) {
if (error.message.includes('слишком старые') || error.message.includes('too old')) { if (error.message.includes('слишком старые') || error.message.includes('too old')) {
this.onAnswerError('replay_attack', error.message); this.onAnswerError('replay_attack', error.message);
@@ -957,7 +956,7 @@ class EnhancedSecureWebRTCManager {
initiateVerification() { initiateVerification() {
if (this.isInitiator) { if (this.isInitiator) {
// Initiator waits for verification confirmation // Initiator waits for verification confirmation
this.onMessage('🔐 Подтвердите код безопасности с собеседником для завершения подключения', 'system'); this.onMessage('🔐 Confirm the security code with your peer to complete the connection', 'system');
} else { } else {
// Responder confirms verification automatically if codes match // Responder confirms verification automatically if codes match
this.confirmVerification(); this.confirmVerification();
@@ -977,11 +976,11 @@ class EnhancedSecureWebRTCManager {
this.dataChannel.send(JSON.stringify(verificationPayload)); this.dataChannel.send(JSON.stringify(verificationPayload));
this.isVerified = true; this.isVerified = true;
this.onStatusChange('connected'); this.onStatusChange('connected');
this.onMessage('✅ Верификация прошла успешно. Канал защищен!', 'system'); this.onMessage('✅ Verification successful. The channel is now secure!', 'system');
this.processMessageQueue(); this.processMessageQueue();
} catch (error) { } catch (error) {
console.error('Verification failed:', error); console.error('Verification failed:', error);
this.onMessage('❌ Ошибка верификации', 'system'); this.onMessage('❌ Verification failed', 'system');
} }
} }
@@ -997,10 +996,10 @@ class EnhancedSecureWebRTCManager {
this.dataChannel.send(JSON.stringify(responsePayload)); this.dataChannel.send(JSON.stringify(responsePayload));
this.isVerified = true; this.isVerified = true;
this.onStatusChange('connected'); this.onStatusChange('connected');
this.onMessage('✅ Верификация прошла успешно. Канал защищен!', 'system'); this.onMessage('✅ Verification successful. The channel is now secure!', 'system');
this.processMessageQueue(); this.processMessageQueue();
} else { } else {
this.onMessage('❌ Код верификации не совпадает! Возможна атака!', 'system'); this.onMessage('❌ Verification code mismatch! Possible MITM attack detected. Connection aborted for safety!', 'system');
this.disconnect(); this.disconnect();
} }
} }
@@ -1009,10 +1008,10 @@ class EnhancedSecureWebRTCManager {
if (data.verified) { if (data.verified) {
this.isVerified = true; this.isVerified = true;
this.onStatusChange('connected'); this.onStatusChange('connected');
this.onMessage('✅ Верификация прошла успешно. Канал защищен!', 'system'); this.onMessage('✅ Verification successful. The channel is now secure.!', 'system');
this.processMessageQueue(); this.processMessageQueue();
} else { } else {
this.onMessage('❌ Верификация не прошла!', 'system'); this.onMessage('❌ Verification failed!', 'system');
this.disconnect(); this.disconnect();
} }
} }
@@ -1137,7 +1136,7 @@ class EnhancedSecureWebRTCManager {
async sendSecureMessage(message) { async sendSecureMessage(message) {
if (!this.isConnected() || !this.isVerified) { if (!this.isConnected() || !this.isVerified) {
this.messageQueue.push(message); this.messageQueue.push(message);
throw new Error('Соединение не готово. Сообщение добавлено в очередь.'); throw new Error('Connection not ready. Message queued for sending.');
} }
// Validate encryption keys // Validate encryption keys
@@ -1149,7 +1148,7 @@ class EnhancedSecureWebRTCManager {
isConnected: this.isConnected(), isConnected: this.isConnected(),
isVerified: this.isVerified isVerified: this.isVerified
}); });
throw new Error('Ключи шифрования не инициализированы. Проверьте соединение.'); throw new Error('Encryption keys not initialized. Please check the connection.');
} }
try { try {
@@ -1273,17 +1272,14 @@ class EnhancedSecureWebRTCManager {
} }
disconnect() { disconnect() {
// Устанавливаем флаг намеренного отключения
this.intentionalDisconnect = true; this.intentionalDisconnect = true;
window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Starting intentional disconnect'); window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Starting intentional disconnect');
// Отправляем уведомление несколько раз для надежности
this.sendDisconnectNotification(); this.sendDisconnectNotification();
// Ждем немного для доставки уведомления, затем очищаем
setTimeout(() => { setTimeout(() => {
this.sendDisconnectNotification(); // Еще одна попытка this.sendDisconnectNotification();
}, 100); }, 100);
setTimeout(() => { setTimeout(() => {
@@ -1294,7 +1290,7 @@ class EnhancedSecureWebRTCManager {
handleUnexpectedDisconnect() { handleUnexpectedDisconnect() {
this.sendDisconnectNotification(); this.sendDisconnectNotification();
this.isVerified = false; this.isVerified = false;
this.onMessage('🔌 Соединение потеряно. Попытка переподключения...', 'system'); this.onMessage('🔌 Connection lost. Attempting to reconnect...', 'system');
setTimeout(() => { setTimeout(() => {
if (!this.intentionalDisconnect) { if (!this.intentionalDisconnect) {
@@ -1311,8 +1307,7 @@ class EnhancedSecureWebRTCManager {
timestamp: Date.now(), timestamp: Date.now(),
reason: this.intentionalDisconnect ? 'user_disconnect' : 'connection_lost' reason: this.intentionalDisconnect ? 'user_disconnect' : 'connection_lost'
}; };
// Пытаемся отправить уведомление несколько раз
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
try { try {
this.dataChannel.send(JSON.stringify(notification)); this.dataChannel.send(JSON.stringify(notification));
@@ -1322,7 +1317,7 @@ class EnhancedSecureWebRTCManager {
}); });
break; break;
} catch (sendError) { } catch (sendError) {
if (i === 2) { // Последняя попытка if (i === 2) {
window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Failed to send disconnect notification', { window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Failed to send disconnect notification', {
error: sendError.message error: sendError.message
}); });
@@ -1338,27 +1333,24 @@ class EnhancedSecureWebRTCManager {
} }
attemptReconnection() { attemptReconnection() {
this.onMessage('❌ Не удается переподключиться. Требуется новое соединение.', 'system'); this.onMessage('❌ Unable to reconnect. A new connection is required.', 'system');
this.cleanupConnection(); this.cleanupConnection();
} }
handlePeerDisconnectNotification(data) { handlePeerDisconnectNotification(data) {
const reason = data.reason || 'unknown'; const reason = data.reason || 'unknown';
const reasonText = reason === 'user_disconnect' ? 'намеренно отключился' : 'потерял соединение'; const reasonText = reason === 'user_disconnect' ? 'manually disconnected.' : 'connection lost.';
this.onMessage(`👋 Собеседник ${reasonText}`, 'system'); this.onMessage(`👋 Peer ${reasonText}`, 'system');
this.onStatusChange('peer_disconnected'); this.onStatusChange('peer_disconnected');
// Устанавливаем флаг что это не наше намеренное отключение
this.intentionalDisconnect = false; this.intentionalDisconnect = false;
this.isVerified = false; this.isVerified = false;
this.stopHeartbeat(); this.stopHeartbeat();
// Очищаем UI данные this.onKeyExchange('');
this.onKeyExchange(''); // Очищаем отпечаток this.onVerificationRequired('');
this.onVerificationRequired(''); // Очищаем код верификации
// Очищаем соединение через небольшую задержку
setTimeout(() => { setTimeout(() => {
this.cleanupConnection(); this.cleanupConnection();
}, 2000); }, 2000);
@@ -1373,8 +1365,7 @@ class EnhancedSecureWebRTCManager {
this.isVerified = false; this.isVerified = false;
this.processedMessageIds.clear(); this.processedMessageIds.clear();
this.messageCounter = 0; this.messageCounter = 0;
// Полная очистка всех криптографических данных
this.encryptionKey = null; this.encryptionKey = null;
this.macKey = null; this.macKey = null;
this.metadataKey = null; this.metadataKey = null;
@@ -1384,21 +1375,21 @@ class EnhancedSecureWebRTCManager {
this.peerPublicKey = null; this.peerPublicKey = null;
this.verificationCode = null; this.verificationCode = null;
// PFS: Очистка всех версий ключей // PFS: Clearing all key versions
this.keyVersions.clear(); this.keyVersions.clear();
this.oldKeys.clear(); this.oldKeys.clear();
this.currentKeyVersion = 0; this.currentKeyVersion = 0;
this.lastKeyRotation = Date.now(); this.lastKeyRotation = Date.now();
// Очистка пар ключей // Clearing key pairs
this.ecdhKeyPair = null; this.ecdhKeyPair = null;
this.ecdsaKeyPair = null; this.ecdsaKeyPair = null;
// Сброс счетчиков сообщений // Resetting message counters
this.sequenceNumber = 0; this.sequenceNumber = 0;
this.expectedSequenceNumber = 0; this.expectedSequenceNumber = 0;
// Сброс флагов безопасности // Security flags reset completed
this.securityFeatures = { this.securityFeatures = {
hasEncryption: false, hasEncryption: false,
hasECDH: false, hasECDH: false,
@@ -1412,7 +1403,7 @@ class EnhancedSecureWebRTCManager {
hasPFS: false hasPFS: false
}; };
// Закрытие соединений // Closing connections
if (this.dataChannel) { if (this.dataChannel) {
this.dataChannel.close(); this.dataChannel.close();
this.dataChannel = null; this.dataChannel = null;
@@ -1422,23 +1413,22 @@ class EnhancedSecureWebRTCManager {
this.peerConnection = null; this.peerConnection = null;
} }
// Очистка очереди сообщений // Clearing message queue
this.messageQueue = []; this.messageQueue = [];
// ВАЖНО: Очистка логов безопасности // IMPORTANT: Clearing security logs
window.EnhancedSecureCryptoUtils.secureLog.clearLogs(); window.EnhancedSecureCryptoUtils.secureLog.clearLogs();
// Уведомляем UI о полной очистке // Notifying the UI about complete cleanup
this.onStatusChange('disconnected'); this.onStatusChange('disconnected');
this.onKeyExchange(''); this.onKeyExchange('');
this.onVerificationRequired(''); this.onVerificationRequired('');
window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Connection cleaned up completely'); window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Connection cleaned up completely');
// Сброс флага намеренного отключения // Resetting the intentional disconnect flag
this.intentionalDisconnect = false; this.intentionalDisconnect = false;
// Принудительная сборка мусора
if (window.gc) { if (window.gc) {
window.gc(); window.gc();
} }