Files
securebit-chat/tests/disconnect-cleanup.test.mjs
T
lockbitchat 0a42aa13c3
CodeQL Analysis / Analyze CodeQL (push) Has been cancelled
Deploy Application / deploy (push) Has been cancelled
Mirror to Codeberg / mirror (push) Has been cancelled
Mirror to PrivacyGuides / mirror (push) Has been cancelled
release: prepare v4.8.5 security hardening release
2026-05-17 14:48:52 -04:00

121 lines
4.4 KiB
JavaScript

import assert from 'node:assert/strict';
globalThis.window = {
EnhancedSecureCryptoUtils: {
secureLog: { log() {} }
}
};
globalThis.CustomEvent = class CustomEvent {
constructor(type, init) {
this.type = type;
this.detail = init?.detail;
}
};
const dispatchedEvents = [];
globalThis.document = {
dispatchEvent(event) {
dispatchedEvents.push(event);
}
};
const { EnhancedSecureWebRTCManager } = await import('../src/network/EnhancedSecureWebRTCManager.js');
function closableChannel() {
return {
readyState: 'open',
closed: false,
onopen() {},
onclose() {},
onmessage() {},
onerror() {},
close() { this.closed = true; }
};
}
{
let transferCleanups = 0;
const dataChannel = closableChannel();
const heartbeatChannel = closableChannel();
const decoyChannel = closableChannel();
const peerConnection = {
closed: false,
onconnectionstatechange() {},
ondatachannel() {},
close() { this.closed = true; }
};
const timer = setTimeout(() => {}, 10_000);
const manager = {
intentionalDisconnect: false,
fileTransferSystem: { cleanup() { transferCleanups += 1; } },
dataChannel,
heartbeatChannel,
peerConnection,
decoyTimers: new Map([['decoy', timer]]),
decoyChannels: new Map([['decoy', decoyChannel]]),
packetBuffer: new Map([['p', 1]]),
chunkQueue: [1],
processedMessageIds: new Set(['m']),
messageCounter: 4,
keyVersions: new Map([['v', 1]]),
oldKeys: new Map([['o', 1]]),
currentKeyVersion: 3,
lastKeyRotation: 1,
sequenceNumber: 7,
expectedSequenceNumber: 8,
replayWindow: new Set([9]),
messageQueue: [{ secret: true }],
calls: [],
_stopAllTimers() { this.calls.push('_stopAllTimers'); },
stopHeartbeat() { this.calls.push('stopHeartbeat'); },
stopFakeTrafficGeneration() { this.calls.push('stopFakeTrafficGeneration'); },
_wipeEphemeralKeys() { this.calls.push('_wipeEphemeralKeys'); },
_hardWipeOldKeys() { this.calls.push('_hardWipeOldKeys'); },
_secureCleanupCryptographicMaterials() { this.calls.push('_secureCleanupCryptographicMaterials'); },
_clearVerificationStates() {
this.calls.push('_clearVerificationStates');
this.localVerificationConfirmed = false;
this.remoteVerificationConfirmed = false;
this.bothVerificationsConfirmed = false;
this.isVerified = false;
this.verificationCode = null;
this.pendingSASCode = null;
},
_secureWipeMemory() { this.calls.push('_secureWipeMemory'); },
_forceGarbageCollection() { return Promise.resolve(); },
sendDisconnectNotification() { this.calls.push('sendDisconnectNotification'); },
onStatusChange(value) { this.status = value; },
onKeyExchange(value) { this.keyExchange = value; },
onVerificationRequired(value) { this.verificationRequired = value; },
_secureLog() {}
};
EnhancedSecureWebRTCManager.prototype.disconnect.call(manager);
assert.equal(transferCleanups, 1);
assert.equal(manager.fileTransferSystem, null);
assert.equal(dataChannel.closed, true);
assert.equal(heartbeatChannel.closed, true);
assert.equal(decoyChannel.closed, true);
assert.equal(peerConnection.closed, true);
assert.equal(manager.dataChannel, null);
assert.equal(manager.heartbeatChannel, null);
assert.equal(manager.peerConnection, null);
assert.equal(manager.decoyTimers.size, 0);
assert.equal(manager.decoyChannels.size, 0);
assert.equal(manager.packetBuffer.size, 0);
assert.deepEqual(manager.chunkQueue, []);
assert.equal(manager.processedMessageIds.size, 0);
assert.equal(manager.keyVersions.size, 0);
assert.equal(manager.oldKeys.size, 0);
assert.equal(manager.replayWindow.size, 0);
assert.deepEqual(manager.messageQueue, []);
assert.equal(manager.status, 'disconnected');
assert.equal(manager.keyExchange, '');
assert.equal(manager.verificationRequired, '');
assert.ok(manager.calls.includes('_clearVerificationStates'));
assert.ok(dispatchedEvents.some(event => event.type === 'peer-disconnect'));
assert.ok(dispatchedEvents.some(event => event.type === 'connection-cleaned'));
}
console.log('Disconnect cleanup tests passed');