ftown-bridge 0.13.5 → 0.15.0

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.
@@ -1,8 +1,10 @@
1
1
  import type { Command, CommandResponse, Loop, Session } from './types.js';
2
+ import { type DirectCommandMessage, type SignalMessage } from './direct-transport/contract.js';
2
3
  type TerminalInputHandler = (sessionId: string, data: string) => void;
3
4
  type TerminalResizeHandler = (sessionId: string, cols: number, rows: number) => void;
4
5
  type TerminalInitHandler = (sessionId: string) => void;
5
6
  type CommandHandler = (command: Command) => void;
7
+ type DirectCommandHandler = (msg: DirectCommandMessage) => void;
6
8
  export declare class CentrifugoClient {
7
9
  private readonly client;
8
10
  private readonly subscriptions;
@@ -21,10 +23,12 @@ export declare class CentrifugoClient {
21
23
  publishLoopRemoved(userId: string, loopId: string): Promise<void>;
22
24
  publishTerminalData(userId: string, sessionId: string, data: string): Promise<void>;
23
25
  subscribeToTerminalInput(userId: string, sessionId: string, onInput: TerminalInputHandler, onResize: TerminalResizeHandler, onInit?: TerminalInitHandler): void;
24
- subscribeToCommands(userId: string, handler: CommandHandler): void;
26
+ subscribeToCommands(userId: string, handler: CommandHandler, onDirectCommand?: DirectCommandHandler): void;
25
27
  joinBridgesChannel(userId: string, bridgeId: string): void;
26
28
  publishTerminalScreen(userId: string, sessionId: string, raw: string): Promise<void>;
27
29
  publishHookEvent(userId: string, sessionId: string, event: Record<string, unknown>): Promise<void>;
30
+ /** Publishes a bridge-originated WebRTC signaling message on the commands channel. */
31
+ publishSignal(userId: string, msg: SignalMessage): Promise<void>;
28
32
  publishCommandResponse(userId: string, response: CommandResponse): Promise<void>;
29
33
  }
30
34
  export {};
@@ -2,6 +2,7 @@ import { Centrifuge } from 'centrifuge';
2
2
  import WebSocket from 'ws';
3
3
  import { hostname } from 'node:os';
4
4
  import { toWireSession } from './session-wire.js';
5
+ import { isSignalMessage, isWatchMessage, } from './direct-transport/contract.js';
5
6
  const MAX_PUBLISH_BYTES = 460_000;
6
7
  function byteLen(str) {
7
8
  return Buffer.byteLength(str, 'utf8');
@@ -168,7 +169,7 @@ export class CentrifugoClient {
168
169
  sub.subscribe();
169
170
  this.subscriptions.set(channel, sub);
170
171
  }
171
- subscribeToCommands(userId, handler) {
172
+ subscribeToCommands(userId, handler, onDirectCommand) {
172
173
  const channel = `commands:rpc#${userId}`;
173
174
  const existingSub = this.subscriptions.get(channel);
174
175
  if (existingSub) {
@@ -181,6 +182,15 @@ export class CentrifugoClient {
181
182
  if (data.type === 'command_response') {
182
183
  return;
183
184
  }
185
+ if (onDirectCommand && (isSignalMessage(data) || isWatchMessage(data))) {
186
+ try {
187
+ onDirectCommand(data);
188
+ }
189
+ catch (err) {
190
+ console.error(`[Centrifugo] Direct command handler failed on ${channel}:`, err);
191
+ }
192
+ return;
193
+ }
184
194
  const command = data;
185
195
  if (!command.type || !command.requestId) {
186
196
  return;
@@ -202,6 +212,9 @@ export class CentrifugoClient {
202
212
  sub.subscribe();
203
213
  this.subscriptions.set(channel, sub);
204
214
  }
215
+ // The loopback rung advert (localPort/localNonce) rides the connection JWT's
216
+ // `info` claim, not subscription data — Centrifugo ignores subscribe data
217
+ // without a subscribe proxy; presence exposes conn_info only.
205
218
  joinBridgesChannel(userId, bridgeId) {
206
219
  const channel = `bridges:presence#${userId}`;
207
220
  const presenceInfo = {
@@ -251,6 +264,16 @@ export class CentrifugoClient {
251
264
  console.error(`[Centrifugo] Failed to publish hook event to ${channel}:`, err);
252
265
  }
253
266
  }
267
+ /** Publishes a bridge-originated WebRTC signaling message on the commands channel. */
268
+ async publishSignal(userId, msg) {
269
+ const channel = `commands:rpc#${userId}`;
270
+ try {
271
+ await this.client.publish(channel, msg);
272
+ }
273
+ catch (err) {
274
+ console.error(`[Centrifugo] Failed to publish signal to ${channel}:`, err);
275
+ }
276
+ }
254
277
  async publishCommandResponse(userId, response) {
255
278
  const channel = `commands:rpc#${userId}`;
256
279
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"centrifugo-client.js","sourceRoot":"","sources":["../src/centrifugo-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"centrifugo-client.js","sourceRoot":"","sources":["../src/centrifugo-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Direct Transport wire contract — FROZEN.
3
+ * Identical copy lives at ui/src/lib/direct-transport/contract.ts.
4
+ * See docs/plans/direct-transport-contract.md. Do not modify.
5
+ */
6
+ export declare const DIRECT_PROTOCOL_VERSION = 1;
7
+ export declare const DATA_CHANNEL_LABEL = "ftown";
8
+ export declare const STUN_SERVERS: string[];
9
+ export declare const PAIR_TIMEOUT_MS = 4000;
10
+ export declare const PING_INTERVAL_MS = 15000;
11
+ export declare const WATCH_HEARTBEAT_MS = 20000;
12
+ export declare const WATCH_TTL_MS = 60000;
13
+ /** Signaling + watch messages, published on the commands:rpc#{userId} channel. */
14
+ export type SignalType = 'webrtc_offer' | 'webrtc_answer' | 'webrtc_ice' | 'webrtc_close';
15
+ export interface SignalMessage {
16
+ type: SignalType;
17
+ /** Unique per connection attempt. */
18
+ pairId: string;
19
+ bridgeId: string;
20
+ /** Unique per browser tab (uuid). */
21
+ clientId: string;
22
+ /** SDP (offer/answer) or JSON-serialized ICE candidate; empty for webrtc_close. */
23
+ payload: string;
24
+ }
25
+ export interface WatchMessage {
26
+ type: 'terminal_watch' | 'terminal_unwatch';
27
+ sessionId: string;
28
+ clientId: string;
29
+ }
30
+ export type DirectCommandMessage = SignalMessage | WatchMessage;
31
+ export declare function isSignalMessage(msg: {
32
+ type?: string;
33
+ }): msg is SignalMessage;
34
+ export declare function isWatchMessage(msg: {
35
+ type?: string;
36
+ }): msg is WatchMessage;
37
+ /** JSON text frames on the `ftown` DataChannel (ordered, reliable). */
38
+ export type DirectMessage = {
39
+ kind: 'hello';
40
+ clientId: string;
41
+ protocolVersion: number;
42
+ } | {
43
+ kind: 'hello_ack';
44
+ bridgeId: string;
45
+ protocolVersion: number;
46
+ } | {
47
+ kind: 'attach';
48
+ sessionId: string;
49
+ } | {
50
+ kind: 'detach';
51
+ sessionId: string;
52
+ }
53
+ /** Full serialized screen; resets the output stream for the session. */
54
+ | {
55
+ kind: 'screen';
56
+ sessionId: string;
57
+ data: string;
58
+ seq: number;
59
+ } | {
60
+ kind: 'output';
61
+ sessionId: string;
62
+ data: string;
63
+ seq: number;
64
+ } | {
65
+ kind: 'input';
66
+ sessionId: string;
67
+ data: string;
68
+ } | {
69
+ kind: 'resize';
70
+ sessionId: string;
71
+ cols: number;
72
+ rows: number;
73
+ } | {
74
+ kind: 'ping';
75
+ } | {
76
+ kind: 'pong';
77
+ };
78
+ export type TerminalTransportMode = 'direct' | 'centrifugo' | 'connecting';
79
+ export interface TerminalDataHandlers {
80
+ /** Incremental output chunk. */
81
+ onOutput: (data: string) => void;
82
+ /** Full screen resync; replaces terminal contents. */
83
+ onScreen: (data: string) => void;
84
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Direct Transport wire contract — FROZEN.
3
+ * Identical copy lives at ui/src/lib/direct-transport/contract.ts.
4
+ * See docs/plans/direct-transport-contract.md. Do not modify.
5
+ */
6
+ export const DIRECT_PROTOCOL_VERSION = 1;
7
+ export const DATA_CHANNEL_LABEL = 'ftown';
8
+ export const STUN_SERVERS = ['stun:stun.l.google.com:19302'];
9
+ export const PAIR_TIMEOUT_MS = 4_000;
10
+ export const PING_INTERVAL_MS = 15_000;
11
+ export const WATCH_HEARTBEAT_MS = 20_000;
12
+ export const WATCH_TTL_MS = 60_000;
13
+ export function isSignalMessage(msg) {
14
+ return (msg.type === 'webrtc_offer' ||
15
+ msg.type === 'webrtc_answer' ||
16
+ msg.type === 'webrtc_ice' ||
17
+ msg.type === 'webrtc_close');
18
+ }
19
+ export function isWatchMessage(msg) {
20
+ return msg.type === 'terminal_watch' || msg.type === 'terminal_unwatch';
21
+ }
22
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/direct-transport/contract.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAC1C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAE7D,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AACrC,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AACzC,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAwBnC,MAAM,UAAU,eAAe,CAAC,GAAsB;IACpD,OAAO,CACL,GAAG,CAAC,IAAI,KAAK,cAAc;QAC3B,GAAG,CAAC,IAAI,KAAK,eAAe;QAC5B,GAAG,CAAC,IAAI,KAAK,YAAY;QACzB,GAAG,CAAC,IAAI,KAAK,cAAc,CAC5B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAsB;IACnD,OAAO,GAAG,CAAC,IAAI,KAAK,gBAAgB,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,76 @@
1
+ import { WebSocket } from 'ws';
2
+ import type { Server as HttpServer } from 'node:http';
3
+ export interface LoopbackPeerServerOptions {
4
+ /** This bridge's identity (as advertised on bridges:presence). */
5
+ bridgeId: string;
6
+ /** Per-process nonce; upgrade requires `?nonce=` to match this exactly. */
7
+ nonce: string;
8
+ /** Exact non-localhost origins allowed to upgrade (typically the api-url origin). */
9
+ allowedOrigins: string[];
10
+ /** `input` frames feed here (same sink as terminal-input / DataChannel). */
11
+ onInput: (sessionId: string, data: string) => void;
12
+ /** `resize` frames feed here (same sink as terminal-input / DataChannel). */
13
+ onResize: (sessionId: string, cols: number, rows: number) => void;
14
+ /** Returns the current full serialized screen for a session on attach. */
15
+ onAttach: (sessionId: string) => string;
16
+ }
17
+ /**
18
+ * One browser WebSocket (one tab). Owns hello gating, per-session monotonic seq,
19
+ * attach set, and app-level ping/pong keepalive — mirrors DirectPeer semantics
20
+ * over a `ws` socket instead of a node-datachannel DataChannel.
21
+ */
22
+ declare class LoopbackPeer {
23
+ private readonly server;
24
+ private readonly ws;
25
+ private helloOk;
26
+ private closed;
27
+ private readonly attached;
28
+ private readonly seq;
29
+ private pingTimer?;
30
+ private missedPings;
31
+ constructor(server: LoopbackPeerServer, ws: WebSocket);
32
+ hasAttached(sessionId: string): boolean;
33
+ sendScreen(sessionId: string, data: string): void;
34
+ sendOutput(sessionId: string, data: string): void;
35
+ close(): void;
36
+ private decode;
37
+ private startKeepalive;
38
+ private handleFrame;
39
+ private send;
40
+ }
41
+ /**
42
+ * Loopback WebSocket rung. Attaches an `upgrade` handler to the existing
43
+ * 127.0.0.1 local API http.Server, gating upgrades on nonce + Origin + loopback
44
+ * host (L1), then speaks the DirectMessage wire protocol (L3) over each socket.
45
+ * Multiple concurrent sockets (tabs) are allowed; output/screen fan to all
46
+ * attached sockets.
47
+ */
48
+ export declare class LoopbackPeerServer {
49
+ readonly bridgeId: string;
50
+ private readonly nonce;
51
+ private readonly allowedOrigins;
52
+ private readonly onInputCb;
53
+ private readonly onResizeCb;
54
+ private readonly onAttachCb;
55
+ private readonly wss;
56
+ private readonly peers;
57
+ private httpServer?;
58
+ private upgradeHandler?;
59
+ constructor(options: LoopbackPeerServerOptions);
60
+ /** Binds the loopback WS upgrade handler onto the running local API server. */
61
+ attach(server: HttpServer): void;
62
+ sendOutput(sessionId: string, data: string): void;
63
+ sendScreen(sessionId: string, data: string): void;
64
+ hasAttachedPeers(sessionId: string): boolean;
65
+ closeAll(): void;
66
+ /** Internal: drops a peer and closes its socket (called on close/error/death). */
67
+ remove(peer: LoopbackPeer): void;
68
+ getScreen(sessionId: string): string;
69
+ deliverInput(sessionId: string, data: string): void;
70
+ deliverResize(sessionId: string, cols: number, rows: number): void;
71
+ private handleUpgrade;
72
+ private originAllowed;
73
+ private nonceMatches;
74
+ private reject;
75
+ }
76
+ export {};
@@ -0,0 +1,321 @@
1
+ import { timingSafeEqual } from 'node:crypto';
2
+ import { WebSocket, WebSocketServer } from 'ws';
3
+ import { DIRECT_PROTOCOL_VERSION, PING_INTERVAL_MS, } from './contract.js';
4
+ /** WebSocket upgrade path on the loopback local API server. */
5
+ const WS_PATH = '/ws';
6
+ const MAX_MISSED_PINGS = 2;
7
+ /**
8
+ * Max chars per frame `data` field — mirrors peer-manager's discipline so the
9
+ * loopback rung chunks screens/output identically: one `screen` frame (stream
10
+ * reset) followed by `output` continuations, receivers apply them in order.
11
+ */
12
+ const MAX_FRAME_DATA_CHARS = 32_000;
13
+ function chunkData(data) {
14
+ if (data.length <= MAX_FRAME_DATA_CHARS)
15
+ return [data];
16
+ const chunks = [];
17
+ for (let i = 0; i < data.length; i += MAX_FRAME_DATA_CHARS) {
18
+ chunks.push(data.slice(i, i + MAX_FRAME_DATA_CHARS));
19
+ }
20
+ return chunks;
21
+ }
22
+ function constantTimeEq(a, b) {
23
+ const bufA = Buffer.from(a, 'utf-8');
24
+ const bufB = Buffer.from(b, 'utf-8');
25
+ if (bufA.length !== bufB.length)
26
+ return false;
27
+ return timingSafeEqual(bufA, bufB);
28
+ }
29
+ /** Same loopback host guard the HTTP handler applies (defense in depth). */
30
+ function isLoopbackHost(hostHeader) {
31
+ if (!hostHeader)
32
+ return false;
33
+ const host = hostHeader.split(':')[0];
34
+ return host === '127.0.0.1' || host === 'localhost' || host === '[::1]';
35
+ }
36
+ function isLocalhostOrigin(origin) {
37
+ return /^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])(:|$)/.test(origin);
38
+ }
39
+ /**
40
+ * One browser WebSocket (one tab). Owns hello gating, per-session monotonic seq,
41
+ * attach set, and app-level ping/pong keepalive — mirrors DirectPeer semantics
42
+ * over a `ws` socket instead of a node-datachannel DataChannel.
43
+ */
44
+ class LoopbackPeer {
45
+ server;
46
+ ws;
47
+ helloOk = false;
48
+ closed = false;
49
+ attached = new Set();
50
+ seq = new Map();
51
+ pingTimer;
52
+ missedPings = 0;
53
+ constructor(server, ws) {
54
+ this.server = server;
55
+ this.ws = ws;
56
+ ws.on('message', (data, isBinary) => {
57
+ if (isBinary)
58
+ return;
59
+ this.handleFrame(this.decode(data));
60
+ });
61
+ ws.on('close', () => this.server.remove(this));
62
+ ws.on('error', () => this.server.remove(this));
63
+ this.startKeepalive();
64
+ }
65
+ hasAttached(sessionId) {
66
+ return this.attached.has(sessionId);
67
+ }
68
+ sendScreen(sessionId, data) {
69
+ if (!this.attached.has(sessionId))
70
+ return;
71
+ const chunks = chunkData(data);
72
+ this.seq.set(sessionId, chunks.length - 1);
73
+ this.send({ kind: 'screen', sessionId, data: chunks[0], seq: 0 });
74
+ for (let i = 1; i < chunks.length; i++) {
75
+ this.send({ kind: 'output', sessionId, data: chunks[i], seq: i });
76
+ }
77
+ }
78
+ sendOutput(sessionId, data) {
79
+ if (!this.attached.has(sessionId))
80
+ return;
81
+ for (const chunk of chunkData(data)) {
82
+ const next = (this.seq.get(sessionId) ?? 0) + 1;
83
+ this.seq.set(sessionId, next);
84
+ this.send({ kind: 'output', sessionId, data: chunk, seq: next });
85
+ }
86
+ }
87
+ close() {
88
+ if (this.closed)
89
+ return;
90
+ this.closed = true;
91
+ if (this.pingTimer)
92
+ clearInterval(this.pingTimer);
93
+ this.attached.clear();
94
+ this.seq.clear();
95
+ try {
96
+ this.ws.close();
97
+ }
98
+ catch { /* already gone */ }
99
+ try {
100
+ this.ws.terminate();
101
+ }
102
+ catch { /* already gone */ }
103
+ }
104
+ decode(data) {
105
+ if (typeof data === 'string')
106
+ return data;
107
+ if (Array.isArray(data))
108
+ return Buffer.concat(data).toString('utf-8');
109
+ return Buffer.from(data).toString('utf-8');
110
+ }
111
+ startKeepalive() {
112
+ if (this.pingTimer)
113
+ return;
114
+ this.missedPings = 0;
115
+ this.pingTimer = setInterval(() => {
116
+ if (this.missedPings >= MAX_MISSED_PINGS) {
117
+ this.server.remove(this);
118
+ return;
119
+ }
120
+ this.missedPings += 1;
121
+ this.send({ kind: 'ping' });
122
+ }, PING_INTERVAL_MS);
123
+ this.pingTimer.unref?.();
124
+ }
125
+ handleFrame(raw) {
126
+ let msg;
127
+ try {
128
+ msg = JSON.parse(raw);
129
+ }
130
+ catch {
131
+ return;
132
+ }
133
+ switch (msg.kind) {
134
+ case 'hello': {
135
+ if (msg.protocolVersion !== DIRECT_PROTOCOL_VERSION) {
136
+ this.server.remove(this);
137
+ return;
138
+ }
139
+ this.helloOk = true;
140
+ this.send({ kind: 'hello_ack', bridgeId: this.server.bridgeId, protocolVersion: DIRECT_PROTOCOL_VERSION });
141
+ return;
142
+ }
143
+ case 'attach': {
144
+ if (!this.helloOk)
145
+ return;
146
+ this.attached.add(msg.sessionId);
147
+ this.sendScreen(msg.sessionId, this.server.getScreen(msg.sessionId));
148
+ return;
149
+ }
150
+ case 'detach': {
151
+ this.attached.delete(msg.sessionId);
152
+ this.seq.delete(msg.sessionId);
153
+ return;
154
+ }
155
+ case 'input': {
156
+ if (!this.helloOk)
157
+ return;
158
+ this.server.deliverInput(msg.sessionId, msg.data);
159
+ return;
160
+ }
161
+ case 'resize': {
162
+ if (!this.helloOk)
163
+ return;
164
+ this.server.deliverResize(msg.sessionId, msg.cols, msg.rows);
165
+ return;
166
+ }
167
+ case 'ping': {
168
+ this.send({ kind: 'pong' });
169
+ return;
170
+ }
171
+ case 'pong': {
172
+ this.missedPings = 0;
173
+ return;
174
+ }
175
+ default:
176
+ // Unknown kind ⇒ ignore.
177
+ return;
178
+ }
179
+ }
180
+ send(msg) {
181
+ if (this.closed || this.ws.readyState !== WebSocket.OPEN)
182
+ return;
183
+ try {
184
+ this.ws.send(JSON.stringify(msg));
185
+ }
186
+ catch {
187
+ // Drop the frame rather than kill the socket; a genuinely dead socket is
188
+ // caught by close/error or missed pings. One socket's failure must never
189
+ // touch another.
190
+ }
191
+ }
192
+ }
193
+ /**
194
+ * Loopback WebSocket rung. Attaches an `upgrade` handler to the existing
195
+ * 127.0.0.1 local API http.Server, gating upgrades on nonce + Origin + loopback
196
+ * host (L1), then speaks the DirectMessage wire protocol (L3) over each socket.
197
+ * Multiple concurrent sockets (tabs) are allowed; output/screen fan to all
198
+ * attached sockets.
199
+ */
200
+ export class LoopbackPeerServer {
201
+ bridgeId;
202
+ nonce;
203
+ allowedOrigins;
204
+ onInputCb;
205
+ onResizeCb;
206
+ onAttachCb;
207
+ wss;
208
+ peers = new Set();
209
+ httpServer;
210
+ upgradeHandler;
211
+ constructor(options) {
212
+ this.bridgeId = options.bridgeId;
213
+ this.nonce = options.nonce;
214
+ this.allowedOrigins = options.allowedOrigins;
215
+ this.onInputCb = options.onInput;
216
+ this.onResizeCb = options.onResize;
217
+ this.onAttachCb = options.onAttach;
218
+ this.wss = new WebSocketServer({ noServer: true });
219
+ }
220
+ /** Binds the loopback WS upgrade handler onto the running local API server. */
221
+ attach(server) {
222
+ this.httpServer = server;
223
+ this.upgradeHandler = (req, socket, head) => this.handleUpgrade(req, socket, head);
224
+ server.on('upgrade', this.upgradeHandler);
225
+ }
226
+ sendOutput(sessionId, data) {
227
+ for (const peer of this.peers)
228
+ peer.sendOutput(sessionId, data);
229
+ }
230
+ sendScreen(sessionId, data) {
231
+ for (const peer of this.peers)
232
+ peer.sendScreen(sessionId, data);
233
+ }
234
+ hasAttachedPeers(sessionId) {
235
+ for (const peer of this.peers) {
236
+ if (peer.hasAttached(sessionId))
237
+ return true;
238
+ }
239
+ return false;
240
+ }
241
+ closeAll() {
242
+ if (this.httpServer && this.upgradeHandler) {
243
+ this.httpServer.removeListener('upgrade', this.upgradeHandler);
244
+ this.upgradeHandler = undefined;
245
+ }
246
+ for (const peer of this.peers)
247
+ peer.close();
248
+ this.peers.clear();
249
+ try {
250
+ this.wss.close();
251
+ }
252
+ catch { /* already closed */ }
253
+ }
254
+ /** Internal: drops a peer and closes its socket (called on close/error/death). */
255
+ remove(peer) {
256
+ this.peers.delete(peer);
257
+ peer.close();
258
+ }
259
+ getScreen(sessionId) {
260
+ return this.onAttachCb(sessionId);
261
+ }
262
+ deliverInput(sessionId, data) {
263
+ this.onInputCb(sessionId, data);
264
+ }
265
+ deliverResize(sessionId, cols, rows) {
266
+ this.onResizeCb(sessionId, cols, rows);
267
+ }
268
+ handleUpgrade(req, socket, head) {
269
+ let url;
270
+ try {
271
+ url = new URL(req.url ?? '/', `http://${req.headers.host ?? '127.0.0.1'}`);
272
+ }
273
+ catch {
274
+ this.reject(socket, 400, 'Bad Request');
275
+ return;
276
+ }
277
+ // Not our path and no other upgrade listener exists on the local API
278
+ // server: reject rather than leave the socket dangling (fd leak).
279
+ if (url.pathname !== WS_PATH) {
280
+ this.reject(socket, 404, 'Not Found');
281
+ return;
282
+ }
283
+ if (!isLoopbackHost(req.headers.host)) {
284
+ this.reject(socket, 421, 'Misdirected Request');
285
+ return;
286
+ }
287
+ if (!this.originAllowed(req.headers.origin)) {
288
+ this.reject(socket, 403, 'Forbidden');
289
+ return;
290
+ }
291
+ if (!this.nonceMatches(url.searchParams.get('nonce'))) {
292
+ this.reject(socket, 403, 'Forbidden');
293
+ return;
294
+ }
295
+ this.wss.handleUpgrade(req, socket, head, (ws) => {
296
+ this.peers.add(new LoopbackPeer(this, ws));
297
+ });
298
+ }
299
+ originAllowed(origin) {
300
+ if (typeof origin !== 'string' || origin === '')
301
+ return false;
302
+ if (isLocalhostOrigin(origin))
303
+ return true;
304
+ return this.allowedOrigins.includes(origin);
305
+ }
306
+ nonceMatches(nonce) {
307
+ if (typeof nonce !== 'string' || nonce === '')
308
+ return false;
309
+ return constantTimeEq(nonce, this.nonce);
310
+ }
311
+ reject(socket, code, reason) {
312
+ try {
313
+ socket.write(`HTTP/1.1 ${code} ${reason}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`);
314
+ }
315
+ catch {
316
+ // Socket already gone; destroy below is still safe.
317
+ }
318
+ socket.destroy();
319
+ }
320
+ }
321
+ //# sourceMappingURL=loopback-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback-server.js","sourceRoot":"","sources":["../../src/direct-transport/loopback-server.ts"],"names":[],"mappings":"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"}