peer-term 1.2.11 → 1.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +69 -17
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -368,25 +368,54 @@ class Session {
|
|
|
368
368
|
|
|
369
369
|
async _completeKeyExchange(clientPublicKeyBase64) {
|
|
370
370
|
if (!this.keyPair || !this.hostPublicKeyBase64) return;
|
|
371
|
+
if (typeof clientPublicKeyBase64 !== 'string' || clientPublicKeyBase64.length === 0) {
|
|
372
|
+
this._rejectProtocolMessage('Invalid key-exchange public key');
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
371
375
|
|
|
372
|
-
|
|
373
|
-
|
|
376
|
+
try {
|
|
377
|
+
this.logDebug('Deriving shared secret...');
|
|
378
|
+
this.clientPublicKeyBase64 = clientPublicKeyBase64;
|
|
379
|
+
|
|
380
|
+
const peerPublicKey = await importPublicKey(clientPublicKeyBase64);
|
|
381
|
+
this.sharedKey = await deriveSharedKey(this.keyPair.privateKey, peerPublicKey);
|
|
382
|
+
|
|
383
|
+
if (this.secureMode) {
|
|
384
|
+
this.securityFingerprint = await fingerprintPublicKeys(
|
|
385
|
+
this.code,
|
|
386
|
+
this.hostPublicKeyBase64,
|
|
387
|
+
this.clientPublicKeyBase64
|
|
388
|
+
);
|
|
389
|
+
this.fingerprintAuthorized = false;
|
|
390
|
+
this._printFingerprintAuthorization();
|
|
391
|
+
} else {
|
|
392
|
+
this.fingerprintAuthorized = true;
|
|
393
|
+
await this._activateSecureSession();
|
|
394
|
+
}
|
|
395
|
+
} catch (err) {
|
|
396
|
+
this._rejectProtocolMessage(`Invalid key exchange: ${err.message}`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
374
399
|
|
|
375
|
-
|
|
376
|
-
this.
|
|
400
|
+
_rejectProtocolMessage(reason) {
|
|
401
|
+
this.log(`Protocol error: ${reason}`);
|
|
402
|
+
this.isClientConnected = false;
|
|
403
|
+
this.awaitingRejoin = false;
|
|
404
|
+
this.sharedKey = null;
|
|
405
|
+
this.keyPair = null;
|
|
406
|
+
this.hostPublicKeyBase64 = null;
|
|
407
|
+
this.clientPublicKeyBase64 = null;
|
|
408
|
+
this.securityFingerprint = null;
|
|
409
|
+
this.fingerprintAuthorized = false;
|
|
410
|
+
this.stopHeartbeat();
|
|
411
|
+
this._cleanupWebRTC();
|
|
412
|
+
this.destroy();
|
|
413
|
+
}
|
|
377
414
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
this.clientPublicKeyBase64
|
|
383
|
-
);
|
|
384
|
-
this.fingerprintAuthorized = false;
|
|
385
|
-
this._printFingerprintAuthorization();
|
|
386
|
-
} else {
|
|
387
|
-
this.fingerprintAuthorized = true;
|
|
388
|
-
await this._activateSecureSession();
|
|
389
|
-
}
|
|
415
|
+
_handleMessageError(err) {
|
|
416
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
417
|
+
this.log(`Protocol handler error: ${message}`);
|
|
418
|
+
this.destroy();
|
|
390
419
|
}
|
|
391
420
|
|
|
392
421
|
_printFingerprintAuthorization() {
|
|
@@ -481,6 +510,7 @@ class Session {
|
|
|
481
510
|
});
|
|
482
511
|
|
|
483
512
|
this.ws.on('message', async (raw) => {
|
|
513
|
+
try {
|
|
484
514
|
let msg;
|
|
485
515
|
try {
|
|
486
516
|
msg = JSON.parse(raw.toString());
|
|
@@ -488,6 +518,10 @@ class Session {
|
|
|
488
518
|
this.log('Invalid message from relay');
|
|
489
519
|
return;
|
|
490
520
|
}
|
|
521
|
+
if (!msg || typeof msg.type !== 'string') {
|
|
522
|
+
this._rejectProtocolMessage('Malformed relay message');
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
491
525
|
|
|
492
526
|
switch (msg.type) {
|
|
493
527
|
case 'code': {
|
|
@@ -614,6 +648,9 @@ class Session {
|
|
|
614
648
|
break;
|
|
615
649
|
}
|
|
616
650
|
}
|
|
651
|
+
} catch (err) {
|
|
652
|
+
this._handleMessageError(err);
|
|
653
|
+
}
|
|
617
654
|
});
|
|
618
655
|
|
|
619
656
|
this.ws.on('close', () => {
|
|
@@ -910,12 +947,17 @@ class Session {
|
|
|
910
947
|
});
|
|
911
948
|
|
|
912
949
|
newWs.on('message', async (raw) => {
|
|
950
|
+
try {
|
|
913
951
|
let msg;
|
|
914
952
|
try {
|
|
915
953
|
msg = JSON.parse(raw.toString());
|
|
916
954
|
} catch {
|
|
917
955
|
return;
|
|
918
956
|
}
|
|
957
|
+
if (!msg || typeof msg.type !== 'string') {
|
|
958
|
+
this._rejectProtocolMessage('Malformed relay message');
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
919
961
|
|
|
920
962
|
if (msg.type === 'rejoined') {
|
|
921
963
|
// Success — replace the old ws with this new one
|
|
@@ -935,6 +977,9 @@ class Session {
|
|
|
935
977
|
this.destroy();
|
|
936
978
|
try { newWs.close(); } catch {}
|
|
937
979
|
}
|
|
980
|
+
} catch (err) {
|
|
981
|
+
this._handleMessageError(err);
|
|
982
|
+
}
|
|
938
983
|
});
|
|
939
984
|
|
|
940
985
|
newWs.on('error', () => {
|
|
@@ -970,6 +1015,7 @@ class Session {
|
|
|
970
1015
|
*/
|
|
971
1016
|
_attachWsHandlers(newWs) {
|
|
972
1017
|
newWs.on('message', async (raw) => {
|
|
1018
|
+
try {
|
|
973
1019
|
let msg;
|
|
974
1020
|
try {
|
|
975
1021
|
msg = JSON.parse(raw.toString());
|
|
@@ -977,6 +1023,10 @@ class Session {
|
|
|
977
1023
|
this.log('Invalid message from relay');
|
|
978
1024
|
return;
|
|
979
1025
|
}
|
|
1026
|
+
if (!msg || typeof msg.type !== 'string') {
|
|
1027
|
+
this._rejectProtocolMessage('Malformed relay message');
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
980
1030
|
|
|
981
1031
|
switch (msg.type) {
|
|
982
1032
|
case 'client-connected': {
|
|
@@ -1084,6 +1134,9 @@ class Session {
|
|
|
1084
1134
|
break;
|
|
1085
1135
|
}
|
|
1086
1136
|
}
|
|
1137
|
+
} catch (err) {
|
|
1138
|
+
this._handleMessageError(err);
|
|
1139
|
+
}
|
|
1087
1140
|
});
|
|
1088
1141
|
|
|
1089
1142
|
newWs.on('close', () => {
|
|
@@ -1414,7 +1467,6 @@ process.on('uncaughtException', (err) => {
|
|
|
1414
1467
|
process.on('unhandledRejection', (reason) => {
|
|
1415
1468
|
const err = reason instanceof Error ? reason : new Error(String(reason));
|
|
1416
1469
|
logger.error(`Unhandled rejection: ${err.message}`, err);
|
|
1417
|
-
process.exit(1);
|
|
1418
1470
|
});
|
|
1419
1471
|
|
|
1420
1472
|
// ─── Run ─────────────────────────────────────────────────────────────────────
|