livedesk 0.1.122 → 0.1.124

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.
@@ -31,6 +31,8 @@ const REMOTE_FRAME_PROTOCOL = 'mindexec.remote.frame.v2';
31
31
  const REMOTE_FRAME_PROTOCOL_VERSION = 2;
32
32
  const REMOTE_FRAME_HANDSHAKE = 'smartview-request-open-frame';
33
33
  const DEFAULT_REMOTE_FRAME_MODE = 'mode1-jpeg';
34
+ const TCP_BINARY_FRAME_MAGIC = Buffer.from('LDFB', 'ascii');
35
+ const TCP_BINARY_FRAME_HEADER_BYTES = 12;
34
36
  const REMOTE_FRAME_MODE_PROFILES = Object.freeze({
35
37
  thumbnail: Object.freeze({
36
38
  mode: 'thumbnail',
@@ -1003,6 +1005,59 @@ function parseRemoteHubWebSocketBinaryFrame(buffer) {
1003
1005
  return { header, payload };
1004
1006
  }
1005
1007
 
1008
+ function hasTcpBinaryFrameMagicPrefix(buffer) {
1009
+ if (!Buffer.isBuffer(buffer) || buffer.length <= 0 || buffer.length > TCP_BINARY_FRAME_MAGIC.length) {
1010
+ return false;
1011
+ }
1012
+
1013
+ for (let index = 0; index < buffer.length; index += 1) {
1014
+ if (buffer[index] !== TCP_BINARY_FRAME_MAGIC[index]) {
1015
+ return false;
1016
+ }
1017
+ }
1018
+ return true;
1019
+ }
1020
+
1021
+ function startsWithTcpBinaryFrameMagic(buffer) {
1022
+ return Buffer.isBuffer(buffer)
1023
+ && buffer.length >= TCP_BINARY_FRAME_MAGIC.length
1024
+ && buffer.subarray(0, TCP_BINARY_FRAME_MAGIC.length).equals(TCP_BINARY_FRAME_MAGIC);
1025
+ }
1026
+
1027
+ function parseTcpBinaryFramePacket(buffer) {
1028
+ if (!Buffer.isBuffer(buffer) || buffer.length < TCP_BINARY_FRAME_HEADER_BYTES) {
1029
+ return { incomplete: true };
1030
+ }
1031
+ if (!startsWithTcpBinaryFrameMagic(buffer)) {
1032
+ return null;
1033
+ }
1034
+
1035
+ const metaLength = buffer.readUInt32BE(4);
1036
+ const payloadLength = buffer.readUInt32BE(8);
1037
+ const maxPayloadBytes = Math.max(MAX_THUMBNAIL_BINARY_BYTES, MAX_STREAM_BINARY_BYTES, MAX_AUDIO_BINARY_BYTES);
1038
+ if (!Number.isFinite(metaLength)
1039
+ || !Number.isFinite(payloadLength)
1040
+ || metaLength <= 0
1041
+ || metaLength > 64 * 1024
1042
+ || payloadLength <= 0
1043
+ || payloadLength > maxPayloadBytes) {
1044
+ return { invalid: true, reason: 'invalid-tcp-binary-frame-size' };
1045
+ }
1046
+
1047
+ const packetLength = TCP_BINARY_FRAME_HEADER_BYTES + metaLength + payloadLength;
1048
+ if (buffer.length < packetLength) {
1049
+ return { incomplete: true };
1050
+ }
1051
+
1052
+ try {
1053
+ const header = JSON.parse(buffer.subarray(TCP_BINARY_FRAME_HEADER_BYTES, TCP_BINARY_FRAME_HEADER_BYTES + metaLength).toString('utf8'));
1054
+ const payload = buffer.subarray(TCP_BINARY_FRAME_HEADER_BYTES + metaLength, packetLength);
1055
+ return { header, payload, packetLength };
1056
+ } catch (err) {
1057
+ return { invalid: true, reason: err?.message || 'invalid-tcp-binary-frame-header' };
1058
+ }
1059
+ }
1060
+
1006
1061
  class RemoteHubWebSocketAgentSocket {
1007
1062
  constructor(socket) {
1008
1063
  this.__remoteHubWebSocket = true;
@@ -3563,6 +3618,29 @@ export function createRemoteHub(options = {}) {
3563
3618
  continue;
3564
3619
  }
3565
3620
 
3621
+ if (state.authenticated && state.frameOnly && state.buffer.length > 0) {
3622
+ if (state.buffer.length < TCP_BINARY_FRAME_MAGIC.length && hasTcpBinaryFrameMagicPrefix(state.buffer)) {
3623
+ return;
3624
+ }
3625
+
3626
+ if (startsWithTcpBinaryFrameMagic(state.buffer)) {
3627
+ const packet = parseTcpBinaryFramePacket(state.buffer);
3628
+ if (packet?.incomplete) {
3629
+ return;
3630
+ }
3631
+ if (!packet || packet.invalid) {
3632
+ writeJsonLine(socket, { type: 'error', error: 'invalid-tcp-binary-frame' });
3633
+ logWarn('remote', `invalid tcp binary frame from agent: ${packet?.reason || 'bad-magic'}`);
3634
+ socket.destroy();
3635
+ return;
3636
+ }
3637
+
3638
+ state.buffer = state.buffer.subarray(packet.packetLength);
3639
+ enqueueAgentBinaryFrame(socket, state, packet.header, packet.payload);
3640
+ continue;
3641
+ }
3642
+ }
3643
+
3566
3644
  const newlineIndex = state.buffer.indexOf(0x0a);
3567
3645
  if (newlineIndex < 0) {
3568
3646
  if (state.buffer.length > MAX_LINE_CHARS) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livedesk",
3
- "version": "0.1.122",
3
+ "version": "0.1.124",
4
4
  "description": "LiveDesk Hub and client launcher",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,7 +30,7 @@
30
30
  "node": ">=20"
31
31
  },
32
32
  "dependencies": {
33
- "@livedesk/client": "0.1.85",
33
+ "@livedesk/client": "0.1.86",
34
34
  "cors": "^2.8.5",
35
35
  "express": "^4.21.2",
36
36
  "ws": "^8.18.3"