cli-tunnel 1.3.1-beta.1 → 1.3.1-beta.2
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/dist/index.js +12 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -187,7 +187,6 @@ setInterval(() => {
|
|
|
187
187
|
}, 30000);
|
|
188
188
|
// ─── Security: Redact secrets from replay events ────────────
|
|
189
189
|
// ─── Bridge server ──────────────────────────────────────────
|
|
190
|
-
const acpEventLog = [];
|
|
191
190
|
const connections = new Map();
|
|
192
191
|
let localResizeAt = 0; // Timestamp of last local terminal resize
|
|
193
192
|
// #10: Session TTL enforcement — periodically close expired connections
|
|
@@ -526,12 +525,10 @@ wss.on('connection', (ws, req) => {
|
|
|
526
525
|
// F-10: WS ping/pong heartbeat
|
|
527
526
|
ws._isAlive = true;
|
|
528
527
|
ws.on('pong', () => { ws._isAlive = true; });
|
|
529
|
-
// Replay
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
ws.send(JSON.stringify({ type: '_replay_done' }));
|
|
528
|
+
// Replay: send accumulated PTY output as one bulk write
|
|
529
|
+
// xterm.js processes the full ANSI stream so cursor codes work correctly
|
|
530
|
+
if (hasReplay && replayBuffer.length > 0) {
|
|
531
|
+
ws.send(JSON.stringify({ type: 'pty', data: replayBuffer }));
|
|
535
532
|
}
|
|
536
533
|
ws.on('message', (data) => {
|
|
537
534
|
// F-13: Enforce WS message rate limit (100 msg/sec)
|
|
@@ -587,19 +584,19 @@ setInterval(() => {
|
|
|
587
584
|
ws.ping();
|
|
588
585
|
}
|
|
589
586
|
}, 30000);
|
|
590
|
-
//
|
|
591
|
-
|
|
587
|
+
// Replay buffer: store raw PTY bytes in a single rolling buffer
|
|
588
|
+
// xterm.js processes the full stream on connect, so ANSI cursor codes work correctly
|
|
589
|
+
const MAX_REPLAY_BYTES = 256 * 1024; // 256KB
|
|
590
|
+
let replayBuffer = '';
|
|
592
591
|
function broadcast(data) {
|
|
593
|
-
// F-01: Redact secrets from live broadcast (not just replay)
|
|
594
592
|
const redacted = redactSecrets(data);
|
|
595
593
|
const msg = JSON.stringify({ type: 'pty', data: redacted });
|
|
596
594
|
if (hasReplay) {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
595
|
+
replayBuffer += redacted;
|
|
596
|
+
// Trim from the front if too large
|
|
597
|
+
if (replayBuffer.length > MAX_REPLAY_BYTES) {
|
|
598
|
+
replayBuffer = replayBuffer.slice(replayBuffer.length - MAX_REPLAY_BYTES);
|
|
600
599
|
}
|
|
601
|
-
if (acpEventLog.length > 2000)
|
|
602
|
-
acpEventLog.splice(0, acpEventLog.length - 2000);
|
|
603
600
|
}
|
|
604
601
|
for (const [, ws] of connections) {
|
|
605
602
|
if (ws.readyState === WebSocket.OPEN)
|