@slayzone/computer 0.36.0-beta.18 → 0.36.0-beta.19
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/bin.cjs +418 -349
- package/dist/bin.cjs.map +4 -4
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -85,103 +85,6 @@ var init_dirs = __esm({
|
|
|
85
85
|
}
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
// ../../../node_modules/ws/lib/stream.js
|
|
89
|
-
var require_stream = __commonJS({
|
|
90
|
-
"../../../node_modules/ws/lib/stream.js"(exports2, module2) {
|
|
91
|
-
"use strict";
|
|
92
|
-
var { Duplex } = require("stream");
|
|
93
|
-
function emitClose(stream) {
|
|
94
|
-
stream.emit("close");
|
|
95
|
-
}
|
|
96
|
-
function duplexOnEnd() {
|
|
97
|
-
if (!this.destroyed && this._writableState.finished) {
|
|
98
|
-
this.destroy();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
function duplexOnError(err) {
|
|
102
|
-
this.removeListener("error", duplexOnError);
|
|
103
|
-
this.destroy();
|
|
104
|
-
if (this.listenerCount("error") === 0) {
|
|
105
|
-
this.emit("error", err);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
function createWebSocketStream2(ws, options) {
|
|
109
|
-
let terminateOnDestroy = true;
|
|
110
|
-
const duplex = new Duplex({
|
|
111
|
-
...options,
|
|
112
|
-
autoDestroy: false,
|
|
113
|
-
emitClose: false,
|
|
114
|
-
objectMode: false,
|
|
115
|
-
writableObjectMode: false
|
|
116
|
-
});
|
|
117
|
-
ws.on("message", function message(msg, isBinary) {
|
|
118
|
-
const data = !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;
|
|
119
|
-
if (!duplex.push(data)) ws.pause();
|
|
120
|
-
});
|
|
121
|
-
ws.once("error", function error48(err) {
|
|
122
|
-
if (duplex.destroyed) return;
|
|
123
|
-
terminateOnDestroy = false;
|
|
124
|
-
duplex.destroy(err);
|
|
125
|
-
});
|
|
126
|
-
ws.once("close", function close() {
|
|
127
|
-
if (duplex.destroyed) return;
|
|
128
|
-
duplex.push(null);
|
|
129
|
-
});
|
|
130
|
-
duplex._destroy = function(err, callback) {
|
|
131
|
-
if (ws.readyState === ws.CLOSED) {
|
|
132
|
-
callback(err);
|
|
133
|
-
process.nextTick(emitClose, duplex);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
let called = false;
|
|
137
|
-
ws.once("error", function error48(err2) {
|
|
138
|
-
called = true;
|
|
139
|
-
callback(err2);
|
|
140
|
-
});
|
|
141
|
-
ws.once("close", function close() {
|
|
142
|
-
if (!called) callback(err);
|
|
143
|
-
process.nextTick(emitClose, duplex);
|
|
144
|
-
});
|
|
145
|
-
if (terminateOnDestroy) ws.terminate();
|
|
146
|
-
};
|
|
147
|
-
duplex._final = function(callback) {
|
|
148
|
-
if (ws.readyState === ws.CONNECTING) {
|
|
149
|
-
ws.once("open", function open2() {
|
|
150
|
-
duplex._final(callback);
|
|
151
|
-
});
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
if (ws._socket === null) return;
|
|
155
|
-
if (ws._socket._writableState.finished) {
|
|
156
|
-
callback();
|
|
157
|
-
if (duplex._readableState.endEmitted) duplex.destroy();
|
|
158
|
-
} else {
|
|
159
|
-
ws._socket.once("finish", function finish() {
|
|
160
|
-
callback();
|
|
161
|
-
});
|
|
162
|
-
ws.close();
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
duplex._read = function() {
|
|
166
|
-
if (ws.isPaused) ws.resume();
|
|
167
|
-
};
|
|
168
|
-
duplex._write = function(chunk, encoding, callback) {
|
|
169
|
-
if (ws.readyState === ws.CONNECTING) {
|
|
170
|
-
ws.once("open", function open2() {
|
|
171
|
-
duplex._write(chunk, encoding, callback);
|
|
172
|
-
});
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
ws.send(chunk, callback);
|
|
176
|
-
};
|
|
177
|
-
duplex.on("end", duplexOnEnd);
|
|
178
|
-
duplex.on("error", duplexOnError);
|
|
179
|
-
return duplex;
|
|
180
|
-
}
|
|
181
|
-
module2.exports = createWebSocketStream2;
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
|
|
185
88
|
// ../../../node_modules/ws/lib/constants.js
|
|
186
89
|
var require_constants = __commonJS({
|
|
187
90
|
"../../../node_modules/ws/lib/constants.js"(exports2, module2) {
|
|
@@ -191,6 +94,7 @@ var require_constants = __commonJS({
|
|
|
191
94
|
if (hasBlob) BINARY_TYPES.push("blob");
|
|
192
95
|
module2.exports = {
|
|
193
96
|
BINARY_TYPES,
|
|
97
|
+
CLOSE_TIMEOUT: 3e4,
|
|
194
98
|
EMPTY_BUFFER: Buffer.alloc(0),
|
|
195
99
|
GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
|
|
196
100
|
hasBlob,
|
|
@@ -345,7 +249,7 @@ var require_permessage_deflate = __commonJS({
|
|
|
345
249
|
var kBuffers = Symbol("buffers");
|
|
346
250
|
var kError = Symbol("error");
|
|
347
251
|
var zlibLimiter;
|
|
348
|
-
var
|
|
252
|
+
var PerMessageDeflate2 = class {
|
|
349
253
|
/**
|
|
350
254
|
* Creates a PerMessageDeflate instance.
|
|
351
255
|
*
|
|
@@ -356,6 +260,9 @@ var require_permessage_deflate = __commonJS({
|
|
|
356
260
|
* acknowledge disabling of client context takeover
|
|
357
261
|
* @param {Number} [options.concurrencyLimit=10] The number of concurrent
|
|
358
262
|
* calls to zlib
|
|
263
|
+
* @param {Boolean} [options.isServer=false] Create the instance in either
|
|
264
|
+
* server or client mode
|
|
265
|
+
* @param {Number} [options.maxPayload=0] The maximum allowed message length
|
|
359
266
|
* @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
|
|
360
267
|
* use of a custom server window size
|
|
361
268
|
* @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
|
|
@@ -366,15 +273,12 @@ var require_permessage_deflate = __commonJS({
|
|
|
366
273
|
* deflate
|
|
367
274
|
* @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
|
|
368
275
|
* inflate
|
|
369
|
-
* @param {Boolean} [isServer=false] Create the instance in either server or
|
|
370
|
-
* client mode
|
|
371
|
-
* @param {Number} [maxPayload=0] The maximum allowed message length
|
|
372
276
|
*/
|
|
373
|
-
constructor(options
|
|
374
|
-
this._maxPayload = maxPayload | 0;
|
|
277
|
+
constructor(options) {
|
|
375
278
|
this._options = options || {};
|
|
376
279
|
this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024;
|
|
377
|
-
this.
|
|
280
|
+
this._maxPayload = this._options.maxPayload | 0;
|
|
281
|
+
this._isServer = !!this._options.isServer;
|
|
378
282
|
this._deflate = null;
|
|
379
283
|
this._inflate = null;
|
|
380
284
|
this.params = null;
|
|
@@ -458,7 +362,7 @@ var require_permessage_deflate = __commonJS({
|
|
|
458
362
|
acceptAsServer(offers) {
|
|
459
363
|
const opts = this._options;
|
|
460
364
|
const accepted = offers.find((params) => {
|
|
461
|
-
if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && !params.client_max_window_bits) {
|
|
365
|
+
if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && (typeof params.client_max_window_bits === "number" ? opts.clientMaxWindowBits > params.client_max_window_bits : !params.client_max_window_bits)) {
|
|
462
366
|
return false;
|
|
463
367
|
}
|
|
464
368
|
return true;
|
|
@@ -683,7 +587,7 @@ var require_permessage_deflate = __commonJS({
|
|
|
683
587
|
});
|
|
684
588
|
}
|
|
685
589
|
};
|
|
686
|
-
module2.exports =
|
|
590
|
+
module2.exports = PerMessageDeflate2;
|
|
687
591
|
function deflateOnData(chunk) {
|
|
688
592
|
this[kBuffers].push(chunk);
|
|
689
593
|
this[kTotalLength] += chunk.length;
|
|
@@ -702,6 +606,10 @@ var require_permessage_deflate = __commonJS({
|
|
|
702
606
|
}
|
|
703
607
|
function inflateOnError(err) {
|
|
704
608
|
this[kPerMessageDeflate]._inflate = null;
|
|
609
|
+
if (this[kError]) {
|
|
610
|
+
this[kCallback](this[kError]);
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
705
613
|
err[kStatusCode] = 1007;
|
|
706
614
|
this[kCallback](err);
|
|
707
615
|
}
|
|
@@ -914,7 +822,7 @@ var require_receiver = __commonJS({
|
|
|
914
822
|
"../../../node_modules/ws/lib/receiver.js"(exports2, module2) {
|
|
915
823
|
"use strict";
|
|
916
824
|
var { Writable } = require("stream");
|
|
917
|
-
var
|
|
825
|
+
var PerMessageDeflate2 = require_permessage_deflate();
|
|
918
826
|
var {
|
|
919
827
|
BINARY_TYPES,
|
|
920
828
|
EMPTY_BUFFER,
|
|
@@ -944,6 +852,10 @@ var require_receiver = __commonJS({
|
|
|
944
852
|
* extensions
|
|
945
853
|
* @param {Boolean} [options.isServer=false] Specifies whether to operate in
|
|
946
854
|
* client or server mode
|
|
855
|
+
* @param {Number} [options.maxBufferedChunks=0] The maximum number of
|
|
856
|
+
* buffered data chunks
|
|
857
|
+
* @param {Number} [options.maxFragments=0] The maximum number of message
|
|
858
|
+
* fragments
|
|
947
859
|
* @param {Number} [options.maxPayload=0] The maximum allowed message length
|
|
948
860
|
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
|
|
949
861
|
* not to skip UTF-8 validation for text and close messages
|
|
@@ -954,6 +866,8 @@ var require_receiver = __commonJS({
|
|
|
954
866
|
this._binaryType = options.binaryType || BINARY_TYPES[0];
|
|
955
867
|
this._extensions = options.extensions || {};
|
|
956
868
|
this._isServer = !!options.isServer;
|
|
869
|
+
this._maxBufferedChunks = options.maxBufferedChunks | 0;
|
|
870
|
+
this._maxFragments = options.maxFragments | 0;
|
|
957
871
|
this._maxPayload = options.maxPayload | 0;
|
|
958
872
|
this._skipUTF8Validation = !!options.skipUTF8Validation;
|
|
959
873
|
this[kWebSocket] = void 0;
|
|
@@ -968,6 +882,7 @@ var require_receiver = __commonJS({
|
|
|
968
882
|
this._opcode = 0;
|
|
969
883
|
this._totalPayloadLength = 0;
|
|
970
884
|
this._messageLength = 0;
|
|
885
|
+
this._numFragments = 0;
|
|
971
886
|
this._fragments = [];
|
|
972
887
|
this._errored = false;
|
|
973
888
|
this._loop = false;
|
|
@@ -983,6 +898,18 @@ var require_receiver = __commonJS({
|
|
|
983
898
|
*/
|
|
984
899
|
_write(chunk, encoding, cb) {
|
|
985
900
|
if (this._opcode === 8 && this._state == GET_INFO) return cb();
|
|
901
|
+
if (this._maxBufferedChunks > 0 && this._buffers.length >= this._maxBufferedChunks) {
|
|
902
|
+
cb(
|
|
903
|
+
this.createError(
|
|
904
|
+
RangeError,
|
|
905
|
+
"Too many buffered chunks",
|
|
906
|
+
false,
|
|
907
|
+
1008,
|
|
908
|
+
"WS_ERR_TOO_MANY_BUFFERED_PARTS"
|
|
909
|
+
)
|
|
910
|
+
);
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
986
913
|
this._bufferedBytes += chunk.length;
|
|
987
914
|
this._buffers.push(chunk);
|
|
988
915
|
this.startLoop(cb);
|
|
@@ -1081,7 +1008,7 @@ var require_receiver = __commonJS({
|
|
|
1081
1008
|
return;
|
|
1082
1009
|
}
|
|
1083
1010
|
const compressed = (buf[0] & 64) === 64;
|
|
1084
|
-
if (compressed && !this._extensions[
|
|
1011
|
+
if (compressed && !this._extensions[PerMessageDeflate2.extensionName]) {
|
|
1085
1012
|
const error48 = this.createError(
|
|
1086
1013
|
RangeError,
|
|
1087
1014
|
"RSV1 must be clear",
|
|
@@ -1306,6 +1233,17 @@ var require_receiver = __commonJS({
|
|
|
1306
1233
|
this.controlMessage(data, cb);
|
|
1307
1234
|
return;
|
|
1308
1235
|
}
|
|
1236
|
+
if (this._maxFragments > 0 && ++this._numFragments > this._maxFragments) {
|
|
1237
|
+
const error48 = this.createError(
|
|
1238
|
+
RangeError,
|
|
1239
|
+
"Too many message fragments",
|
|
1240
|
+
false,
|
|
1241
|
+
1008,
|
|
1242
|
+
"WS_ERR_TOO_MANY_BUFFERED_PARTS"
|
|
1243
|
+
);
|
|
1244
|
+
cb(error48);
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1309
1247
|
if (this._compressed) {
|
|
1310
1248
|
this._state = INFLATING;
|
|
1311
1249
|
this.decompress(data, cb);
|
|
@@ -1325,7 +1263,7 @@ var require_receiver = __commonJS({
|
|
|
1325
1263
|
* @private
|
|
1326
1264
|
*/
|
|
1327
1265
|
decompress(data, cb) {
|
|
1328
|
-
const perMessageDeflate = this._extensions[
|
|
1266
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
|
|
1329
1267
|
perMessageDeflate.decompress(data, this._fin, (err, buf) => {
|
|
1330
1268
|
if (err) return cb(err);
|
|
1331
1269
|
if (buf.length) {
|
|
@@ -1363,6 +1301,7 @@ var require_receiver = __commonJS({
|
|
|
1363
1301
|
this._totalPayloadLength = 0;
|
|
1364
1302
|
this._messageLength = 0;
|
|
1365
1303
|
this._fragmented = 0;
|
|
1304
|
+
this._numFragments = 0;
|
|
1366
1305
|
this._fragments = [];
|
|
1367
1306
|
if (this._opcode === 2) {
|
|
1368
1307
|
let data;
|
|
@@ -1507,7 +1446,10 @@ var require_sender = __commonJS({
|
|
|
1507
1446
|
"use strict";
|
|
1508
1447
|
var { Duplex } = require("stream");
|
|
1509
1448
|
var { randomFillSync } = require("crypto");
|
|
1510
|
-
var
|
|
1449
|
+
var {
|
|
1450
|
+
types: { isUint8Array }
|
|
1451
|
+
} = require("util");
|
|
1452
|
+
var PerMessageDeflate2 = require_permessage_deflate();
|
|
1511
1453
|
var { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants();
|
|
1512
1454
|
var { isBlob, isValidStatusCode } = require_validation();
|
|
1513
1455
|
var { mask: applyMask, toBuffer } = require_buffer_util();
|
|
@@ -1660,8 +1602,10 @@ var require_sender = __commonJS({
|
|
|
1660
1602
|
buf.writeUInt16BE(code, 0);
|
|
1661
1603
|
if (typeof data === "string") {
|
|
1662
1604
|
buf.write(data, 2);
|
|
1663
|
-
} else {
|
|
1605
|
+
} else if (isUint8Array(data)) {
|
|
1664
1606
|
buf.set(data, 2);
|
|
1607
|
+
} else {
|
|
1608
|
+
throw new TypeError("Second argument must be a string or a Uint8Array");
|
|
1665
1609
|
}
|
|
1666
1610
|
}
|
|
1667
1611
|
const options = {
|
|
@@ -1791,7 +1735,7 @@ var require_sender = __commonJS({
|
|
|
1791
1735
|
* @public
|
|
1792
1736
|
*/
|
|
1793
1737
|
send(data, options, cb) {
|
|
1794
|
-
const perMessageDeflate = this._extensions[
|
|
1738
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
|
|
1795
1739
|
let opcode = options.binary ? 2 : 1;
|
|
1796
1740
|
let rsv1 = options.compress;
|
|
1797
1741
|
let byteLength;
|
|
@@ -1915,7 +1859,7 @@ var require_sender = __commonJS({
|
|
|
1915
1859
|
this.sendFrame(_Sender.frame(data, options), cb);
|
|
1916
1860
|
return;
|
|
1917
1861
|
}
|
|
1918
|
-
const perMessageDeflate = this._extensions[
|
|
1862
|
+
const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
|
|
1919
1863
|
this._bufferedBytes += options[kByteLength];
|
|
1920
1864
|
this._state = DEFLATING;
|
|
1921
1865
|
perMessageDeflate.compress(data, options.fin, (_, buf) => {
|
|
@@ -1958,7 +1902,7 @@ var require_sender = __commonJS({
|
|
|
1958
1902
|
/**
|
|
1959
1903
|
* Sends a frame.
|
|
1960
1904
|
*
|
|
1961
|
-
* @param {Buffer[]} list The frame to send
|
|
1905
|
+
* @param {(Buffer | String)[]} list The frame to send
|
|
1962
1906
|
* @param {Function} [cb] Callback
|
|
1963
1907
|
* @private
|
|
1964
1908
|
*/
|
|
@@ -2353,11 +2297,11 @@ var require_extension = __commonJS({
|
|
|
2353
2297
|
return offers;
|
|
2354
2298
|
}
|
|
2355
2299
|
function format(extensions) {
|
|
2356
|
-
return Object.keys(extensions).map((
|
|
2357
|
-
let configurations = extensions[
|
|
2300
|
+
return Object.keys(extensions).map((extension2) => {
|
|
2301
|
+
let configurations = extensions[extension2];
|
|
2358
2302
|
if (!Array.isArray(configurations)) configurations = [configurations];
|
|
2359
2303
|
return configurations.map((params) => {
|
|
2360
|
-
return [
|
|
2304
|
+
return [extension2].concat(
|
|
2361
2305
|
Object.keys(params).map((k) => {
|
|
2362
2306
|
let values = params[k];
|
|
2363
2307
|
if (!Array.isArray(values)) values = [values];
|
|
@@ -2380,15 +2324,16 @@ var require_websocket = __commonJS({
|
|
|
2380
2324
|
var http2 = require("http");
|
|
2381
2325
|
var net = require("net");
|
|
2382
2326
|
var tls = require("tls");
|
|
2383
|
-
var { randomBytes, createHash
|
|
2327
|
+
var { randomBytes, createHash } = require("crypto");
|
|
2384
2328
|
var { Duplex, Readable } = require("stream");
|
|
2385
2329
|
var { URL: URL2 } = require("url");
|
|
2386
|
-
var
|
|
2330
|
+
var PerMessageDeflate2 = require_permessage_deflate();
|
|
2387
2331
|
var Receiver2 = require_receiver();
|
|
2388
2332
|
var Sender2 = require_sender();
|
|
2389
2333
|
var { isBlob } = require_validation();
|
|
2390
2334
|
var {
|
|
2391
2335
|
BINARY_TYPES,
|
|
2336
|
+
CLOSE_TIMEOUT,
|
|
2392
2337
|
EMPTY_BUFFER,
|
|
2393
2338
|
GUID,
|
|
2394
2339
|
kForOnEventAttribute,
|
|
@@ -2402,7 +2347,6 @@ var require_websocket = __commonJS({
|
|
|
2402
2347
|
} = require_event_target();
|
|
2403
2348
|
var { format, parse: parse3 } = require_extension();
|
|
2404
2349
|
var { toBuffer } = require_buffer_util();
|
|
2405
|
-
var closeTimeout = 30 * 1e3;
|
|
2406
2350
|
var kAborted = Symbol("kAborted");
|
|
2407
2351
|
var protocolVersions = [8, 13];
|
|
2408
2352
|
var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
|
|
@@ -2448,6 +2392,7 @@ var require_websocket = __commonJS({
|
|
|
2448
2392
|
initAsClient(this, address, protocols, options);
|
|
2449
2393
|
} else {
|
|
2450
2394
|
this._autoPong = options.autoPong;
|
|
2395
|
+
this._closeTimeout = options.closeTimeout;
|
|
2451
2396
|
this._isServer = true;
|
|
2452
2397
|
}
|
|
2453
2398
|
}
|
|
@@ -2541,6 +2486,10 @@ var require_websocket = __commonJS({
|
|
|
2541
2486
|
* multiple times in the same tick
|
|
2542
2487
|
* @param {Function} [options.generateMask] The function used to generate the
|
|
2543
2488
|
* masking key
|
|
2489
|
+
* @param {Number} [options.maxBufferedChunks=0] The maximum number of
|
|
2490
|
+
* buffered data chunks
|
|
2491
|
+
* @param {Number} [options.maxFragments=0] The maximum number of message
|
|
2492
|
+
* fragments
|
|
2544
2493
|
* @param {Number} [options.maxPayload=0] The maximum allowed message size
|
|
2545
2494
|
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
|
|
2546
2495
|
* not to skip UTF-8 validation for text and close messages
|
|
@@ -2552,6 +2501,8 @@ var require_websocket = __commonJS({
|
|
|
2552
2501
|
binaryType: this.binaryType,
|
|
2553
2502
|
extensions: this._extensions,
|
|
2554
2503
|
isServer: this._isServer,
|
|
2504
|
+
maxBufferedChunks: options.maxBufferedChunks,
|
|
2505
|
+
maxFragments: options.maxFragments,
|
|
2555
2506
|
maxPayload: options.maxPayload,
|
|
2556
2507
|
skipUTF8Validation: options.skipUTF8Validation
|
|
2557
2508
|
});
|
|
@@ -2590,8 +2541,8 @@ var require_websocket = __commonJS({
|
|
|
2590
2541
|
this.emit("close", this._closeCode, this._closeMessage);
|
|
2591
2542
|
return;
|
|
2592
2543
|
}
|
|
2593
|
-
if (this._extensions[
|
|
2594
|
-
this._extensions[
|
|
2544
|
+
if (this._extensions[PerMessageDeflate2.extensionName]) {
|
|
2545
|
+
this._extensions[PerMessageDeflate2.extensionName].cleanup();
|
|
2595
2546
|
}
|
|
2596
2547
|
this._receiver.removeAllListeners();
|
|
2597
2548
|
this._readyState = _WebSocket.CLOSED;
|
|
@@ -2753,7 +2704,7 @@ var require_websocket = __commonJS({
|
|
|
2753
2704
|
fin: true,
|
|
2754
2705
|
...options
|
|
2755
2706
|
};
|
|
2756
|
-
if (!this._extensions[
|
|
2707
|
+
if (!this._extensions[PerMessageDeflate2.extensionName]) {
|
|
2757
2708
|
opts.compress = false;
|
|
2758
2709
|
}
|
|
2759
2710
|
this._sender.send(data || EMPTY_BUFFER, opts, cb);
|
|
@@ -2849,7 +2800,10 @@ var require_websocket = __commonJS({
|
|
|
2849
2800
|
const opts = {
|
|
2850
2801
|
allowSynchronousEvents: true,
|
|
2851
2802
|
autoPong: true,
|
|
2803
|
+
closeTimeout: CLOSE_TIMEOUT,
|
|
2852
2804
|
protocolVersion: protocolVersions[1],
|
|
2805
|
+
maxBufferedChunks: 256 * 1024,
|
|
2806
|
+
maxFragments: 16 * 1024,
|
|
2853
2807
|
maxPayload: 100 * 1024 * 1024,
|
|
2854
2808
|
skipUTF8Validation: false,
|
|
2855
2809
|
perMessageDeflate: true,
|
|
@@ -2866,6 +2820,7 @@ var require_websocket = __commonJS({
|
|
|
2866
2820
|
port: void 0
|
|
2867
2821
|
};
|
|
2868
2822
|
websocket._autoPong = opts.autoPong;
|
|
2823
|
+
websocket._closeTimeout = opts.closeTimeout;
|
|
2869
2824
|
if (!protocolVersions.includes(opts.protocolVersion)) {
|
|
2870
2825
|
throw new RangeError(
|
|
2871
2826
|
`Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})`
|
|
@@ -2877,7 +2832,7 @@ var require_websocket = __commonJS({
|
|
|
2877
2832
|
} else {
|
|
2878
2833
|
try {
|
|
2879
2834
|
parsedUrl = new URL2(address);
|
|
2880
|
-
} catch
|
|
2835
|
+
} catch {
|
|
2881
2836
|
throw new SyntaxError(`Invalid URL: ${address}`);
|
|
2882
2837
|
}
|
|
2883
2838
|
}
|
|
@@ -2891,7 +2846,7 @@ var require_websocket = __commonJS({
|
|
|
2891
2846
|
const isIpcUrl = parsedUrl.protocol === "ws+unix:";
|
|
2892
2847
|
let invalidUrlMessage;
|
|
2893
2848
|
if (parsedUrl.protocol !== "ws:" && !isSecure && !isIpcUrl) {
|
|
2894
|
-
invalidUrlMessage = `The URL's protocol must be one of "ws:", "wss:", "http:", "https", or "ws+unix:"`;
|
|
2849
|
+
invalidUrlMessage = `The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`;
|
|
2895
2850
|
} else if (isIpcUrl && !parsedUrl.pathname) {
|
|
2896
2851
|
invalidUrlMessage = "The URL's pathname is empty";
|
|
2897
2852
|
} else if (parsedUrl.hash) {
|
|
@@ -2925,13 +2880,13 @@ var require_websocket = __commonJS({
|
|
|
2925
2880
|
opts.path = parsedUrl.pathname + parsedUrl.search;
|
|
2926
2881
|
opts.timeout = opts.handshakeTimeout;
|
|
2927
2882
|
if (opts.perMessageDeflate) {
|
|
2928
|
-
perMessageDeflate = new
|
|
2929
|
-
opts.perMessageDeflate
|
|
2930
|
-
false,
|
|
2931
|
-
opts.maxPayload
|
|
2932
|
-
);
|
|
2883
|
+
perMessageDeflate = new PerMessageDeflate2({
|
|
2884
|
+
...opts.perMessageDeflate,
|
|
2885
|
+
isServer: false,
|
|
2886
|
+
maxPayload: opts.maxPayload
|
|
2887
|
+
});
|
|
2933
2888
|
opts.headers["Sec-WebSocket-Extensions"] = format({
|
|
2934
|
-
[
|
|
2889
|
+
[PerMessageDeflate2.extensionName]: perMessageDeflate.offer()
|
|
2935
2890
|
});
|
|
2936
2891
|
}
|
|
2937
2892
|
if (protocols.length) {
|
|
@@ -3037,7 +2992,7 @@ var require_websocket = __commonJS({
|
|
|
3037
2992
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
3038
2993
|
return;
|
|
3039
2994
|
}
|
|
3040
|
-
const digest =
|
|
2995
|
+
const digest = createHash("sha1").update(key + GUID).digest("base64");
|
|
3041
2996
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
3042
2997
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
3043
2998
|
return;
|
|
@@ -3074,23 +3029,25 @@ var require_websocket = __commonJS({
|
|
|
3074
3029
|
return;
|
|
3075
3030
|
}
|
|
3076
3031
|
const extensionNames = Object.keys(extensions);
|
|
3077
|
-
if (extensionNames.length !== 1 || extensionNames[0] !==
|
|
3032
|
+
if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate2.extensionName) {
|
|
3078
3033
|
const message = "Server indicated an extension that was not requested";
|
|
3079
3034
|
abortHandshake(websocket, socket, message);
|
|
3080
3035
|
return;
|
|
3081
3036
|
}
|
|
3082
3037
|
try {
|
|
3083
|
-
perMessageDeflate.accept(extensions[
|
|
3038
|
+
perMessageDeflate.accept(extensions[PerMessageDeflate2.extensionName]);
|
|
3084
3039
|
} catch (err) {
|
|
3085
3040
|
const message = "Invalid Sec-WebSocket-Extensions header";
|
|
3086
3041
|
abortHandshake(websocket, socket, message);
|
|
3087
3042
|
return;
|
|
3088
3043
|
}
|
|
3089
|
-
websocket._extensions[
|
|
3044
|
+
websocket._extensions[PerMessageDeflate2.extensionName] = perMessageDeflate;
|
|
3090
3045
|
}
|
|
3091
3046
|
websocket.setSocket(socket, head, {
|
|
3092
3047
|
allowSynchronousEvents: opts.allowSynchronousEvents,
|
|
3093
3048
|
generateMask: opts.generateMask,
|
|
3049
|
+
maxBufferedChunks: opts.maxBufferedChunks,
|
|
3050
|
+
maxFragments: opts.maxFragments,
|
|
3094
3051
|
maxPayload: opts.maxPayload,
|
|
3095
3052
|
skipUTF8Validation: opts.skipUTF8Validation
|
|
3096
3053
|
});
|
|
@@ -3208,7 +3165,7 @@ var require_websocket = __commonJS({
|
|
|
3208
3165
|
function setCloseTimer(websocket) {
|
|
3209
3166
|
websocket._closeTimer = setTimeout(
|
|
3210
3167
|
websocket._socket.destroy.bind(websocket._socket),
|
|
3211
|
-
|
|
3168
|
+
websocket._closeTimeout
|
|
3212
3169
|
);
|
|
3213
3170
|
}
|
|
3214
3171
|
function socketOnClose() {
|
|
@@ -3217,8 +3174,8 @@ var require_websocket = __commonJS({
|
|
|
3217
3174
|
this.removeListener("data", socketOnData);
|
|
3218
3175
|
this.removeListener("end", socketOnEnd);
|
|
3219
3176
|
websocket._readyState = WebSocket2.CLOSING;
|
|
3220
|
-
|
|
3221
|
-
|
|
3177
|
+
if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && this._readableState.length !== 0) {
|
|
3178
|
+
const chunk = this.read(this._readableState.length);
|
|
3222
3179
|
websocket._receiver.write(chunk);
|
|
3223
3180
|
}
|
|
3224
3181
|
websocket._receiver.end();
|
|
@@ -3254,6 +3211,104 @@ var require_websocket = __commonJS({
|
|
|
3254
3211
|
}
|
|
3255
3212
|
});
|
|
3256
3213
|
|
|
3214
|
+
// ../../../node_modules/ws/lib/stream.js
|
|
3215
|
+
var require_stream = __commonJS({
|
|
3216
|
+
"../../../node_modules/ws/lib/stream.js"(exports2, module2) {
|
|
3217
|
+
"use strict";
|
|
3218
|
+
var WebSocket2 = require_websocket();
|
|
3219
|
+
var { Duplex } = require("stream");
|
|
3220
|
+
function emitClose(stream) {
|
|
3221
|
+
stream.emit("close");
|
|
3222
|
+
}
|
|
3223
|
+
function duplexOnEnd() {
|
|
3224
|
+
if (!this.destroyed && this._writableState.finished) {
|
|
3225
|
+
this.destroy();
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
function duplexOnError(err) {
|
|
3229
|
+
this.removeListener("error", duplexOnError);
|
|
3230
|
+
this.destroy();
|
|
3231
|
+
if (this.listenerCount("error") === 0) {
|
|
3232
|
+
this.emit("error", err);
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
function createWebSocketStream2(ws, options) {
|
|
3236
|
+
let terminateOnDestroy = true;
|
|
3237
|
+
const duplex = new Duplex({
|
|
3238
|
+
...options,
|
|
3239
|
+
autoDestroy: false,
|
|
3240
|
+
emitClose: false,
|
|
3241
|
+
objectMode: false,
|
|
3242
|
+
writableObjectMode: false
|
|
3243
|
+
});
|
|
3244
|
+
ws.on("message", function message(msg, isBinary) {
|
|
3245
|
+
const data = !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;
|
|
3246
|
+
if (!duplex.push(data)) ws.pause();
|
|
3247
|
+
});
|
|
3248
|
+
ws.once("error", function error48(err) {
|
|
3249
|
+
if (duplex.destroyed) return;
|
|
3250
|
+
terminateOnDestroy = false;
|
|
3251
|
+
duplex.destroy(err);
|
|
3252
|
+
});
|
|
3253
|
+
ws.once("close", function close() {
|
|
3254
|
+
if (duplex.destroyed) return;
|
|
3255
|
+
duplex.push(null);
|
|
3256
|
+
});
|
|
3257
|
+
duplex._destroy = function(err, callback) {
|
|
3258
|
+
if (ws.readyState === ws.CLOSED) {
|
|
3259
|
+
callback(err);
|
|
3260
|
+
process.nextTick(emitClose, duplex);
|
|
3261
|
+
return;
|
|
3262
|
+
}
|
|
3263
|
+
let called = false;
|
|
3264
|
+
ws.once("error", function error48(err2) {
|
|
3265
|
+
called = true;
|
|
3266
|
+
callback(err2);
|
|
3267
|
+
});
|
|
3268
|
+
ws.once("close", function close() {
|
|
3269
|
+
if (!called) callback(err);
|
|
3270
|
+
process.nextTick(emitClose, duplex);
|
|
3271
|
+
});
|
|
3272
|
+
if (terminateOnDestroy) ws.terminate();
|
|
3273
|
+
};
|
|
3274
|
+
duplex._final = function(callback) {
|
|
3275
|
+
if (ws.readyState === ws.CONNECTING) {
|
|
3276
|
+
ws.once("open", function open2() {
|
|
3277
|
+
duplex._final(callback);
|
|
3278
|
+
});
|
|
3279
|
+
return;
|
|
3280
|
+
}
|
|
3281
|
+
if (ws._socket === null) return;
|
|
3282
|
+
if (ws._socket._writableState.finished) {
|
|
3283
|
+
callback();
|
|
3284
|
+
if (duplex._readableState.endEmitted) duplex.destroy();
|
|
3285
|
+
} else {
|
|
3286
|
+
ws._socket.once("finish", function finish() {
|
|
3287
|
+
callback();
|
|
3288
|
+
});
|
|
3289
|
+
ws.close();
|
|
3290
|
+
}
|
|
3291
|
+
};
|
|
3292
|
+
duplex._read = function() {
|
|
3293
|
+
if (ws.isPaused) ws.resume();
|
|
3294
|
+
};
|
|
3295
|
+
duplex._write = function(chunk, encoding, callback) {
|
|
3296
|
+
if (ws.readyState === ws.CONNECTING) {
|
|
3297
|
+
ws.once("open", function open2() {
|
|
3298
|
+
duplex._write(chunk, encoding, callback);
|
|
3299
|
+
});
|
|
3300
|
+
return;
|
|
3301
|
+
}
|
|
3302
|
+
ws.send(chunk, callback);
|
|
3303
|
+
};
|
|
3304
|
+
duplex.on("end", duplexOnEnd);
|
|
3305
|
+
duplex.on("error", duplexOnError);
|
|
3306
|
+
return duplex;
|
|
3307
|
+
}
|
|
3308
|
+
module2.exports = createWebSocketStream2;
|
|
3309
|
+
}
|
|
3310
|
+
});
|
|
3311
|
+
|
|
3257
3312
|
// ../../../node_modules/ws/lib/subprotocol.js
|
|
3258
3313
|
var require_subprotocol = __commonJS({
|
|
3259
3314
|
"../../../node_modules/ws/lib/subprotocol.js"(exports2, module2) {
|
|
@@ -3306,12 +3361,12 @@ var require_websocket_server = __commonJS({
|
|
|
3306
3361
|
var EventEmitter = require("events");
|
|
3307
3362
|
var http2 = require("http");
|
|
3308
3363
|
var { Duplex } = require("stream");
|
|
3309
|
-
var { createHash
|
|
3310
|
-
var
|
|
3311
|
-
var
|
|
3312
|
-
var
|
|
3364
|
+
var { createHash } = require("crypto");
|
|
3365
|
+
var extension2 = require_extension();
|
|
3366
|
+
var PerMessageDeflate2 = require_permessage_deflate();
|
|
3367
|
+
var subprotocol2 = require_subprotocol();
|
|
3313
3368
|
var WebSocket2 = require_websocket();
|
|
3314
|
-
var { GUID, kWebSocket } = require_constants();
|
|
3369
|
+
var { CLOSE_TIMEOUT, GUID, kWebSocket } = require_constants();
|
|
3315
3370
|
var keyRegex = /^[+/0-9A-Za-z]{22}==$/;
|
|
3316
3371
|
var RUNNING = 0;
|
|
3317
3372
|
var CLOSING = 1;
|
|
@@ -3330,8 +3385,15 @@ var require_websocket_server = __commonJS({
|
|
|
3330
3385
|
* pending connections
|
|
3331
3386
|
* @param {Boolean} [options.clientTracking=true] Specifies whether or not to
|
|
3332
3387
|
* track clients
|
|
3388
|
+
* @param {Number} [options.closeTimeout=30000] Duration in milliseconds to
|
|
3389
|
+
* wait for the closing handshake to finish after `websocket.close()` is
|
|
3390
|
+
* called
|
|
3333
3391
|
* @param {Function} [options.handleProtocols] A hook to handle protocols
|
|
3334
3392
|
* @param {String} [options.host] The hostname where to bind the server
|
|
3393
|
+
* @param {Number} [options.maxBufferedChunks=262144] The maximum number of
|
|
3394
|
+
* buffered data chunks
|
|
3395
|
+
* @param {Number} [options.maxFragments=16384] The maximum number of message
|
|
3396
|
+
* fragments
|
|
3335
3397
|
* @param {Number} [options.maxPayload=104857600] The maximum allowed message
|
|
3336
3398
|
* size
|
|
3337
3399
|
* @param {Boolean} [options.noServer=false] Enable no server mode
|
|
@@ -3353,11 +3415,14 @@ var require_websocket_server = __commonJS({
|
|
|
3353
3415
|
options = {
|
|
3354
3416
|
allowSynchronousEvents: true,
|
|
3355
3417
|
autoPong: true,
|
|
3418
|
+
maxBufferedChunks: 256 * 1024,
|
|
3419
|
+
maxFragments: 16 * 1024,
|
|
3356
3420
|
maxPayload: 100 * 1024 * 1024,
|
|
3357
3421
|
skipUTF8Validation: false,
|
|
3358
3422
|
perMessageDeflate: false,
|
|
3359
3423
|
handleProtocols: null,
|
|
3360
3424
|
clientTracking: true,
|
|
3425
|
+
closeTimeout: CLOSE_TIMEOUT,
|
|
3361
3426
|
verifyClient: null,
|
|
3362
3427
|
noServer: false,
|
|
3363
3428
|
backlog: null,
|
|
@@ -3513,9 +3578,11 @@ var require_websocket_server = __commonJS({
|
|
|
3513
3578
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
|
|
3514
3579
|
return;
|
|
3515
3580
|
}
|
|
3516
|
-
if (version2 !==
|
|
3581
|
+
if (version2 !== 13 && version2 !== 8) {
|
|
3517
3582
|
const message = "Missing or invalid Sec-WebSocket-Version header";
|
|
3518
|
-
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message
|
|
3583
|
+
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {
|
|
3584
|
+
"Sec-WebSocket-Version": "13, 8"
|
|
3585
|
+
});
|
|
3519
3586
|
return;
|
|
3520
3587
|
}
|
|
3521
3588
|
if (!this.shouldHandle(req)) {
|
|
@@ -3526,7 +3593,7 @@ var require_websocket_server = __commonJS({
|
|
|
3526
3593
|
let protocols = /* @__PURE__ */ new Set();
|
|
3527
3594
|
if (secWebSocketProtocol !== void 0) {
|
|
3528
3595
|
try {
|
|
3529
|
-
protocols =
|
|
3596
|
+
protocols = subprotocol2.parse(secWebSocketProtocol);
|
|
3530
3597
|
} catch (err) {
|
|
3531
3598
|
const message = "Invalid Sec-WebSocket-Protocol header";
|
|
3532
3599
|
abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
|
|
@@ -3536,16 +3603,16 @@ var require_websocket_server = __commonJS({
|
|
|
3536
3603
|
const secWebSocketExtensions = req.headers["sec-websocket-extensions"];
|
|
3537
3604
|
const extensions = {};
|
|
3538
3605
|
if (this.options.perMessageDeflate && secWebSocketExtensions !== void 0) {
|
|
3539
|
-
const perMessageDeflate = new
|
|
3540
|
-
this.options.perMessageDeflate,
|
|
3541
|
-
true,
|
|
3542
|
-
this.options.maxPayload
|
|
3543
|
-
);
|
|
3606
|
+
const perMessageDeflate = new PerMessageDeflate2({
|
|
3607
|
+
...this.options.perMessageDeflate,
|
|
3608
|
+
isServer: true,
|
|
3609
|
+
maxPayload: this.options.maxPayload
|
|
3610
|
+
});
|
|
3544
3611
|
try {
|
|
3545
|
-
const offers =
|
|
3546
|
-
if (offers[
|
|
3547
|
-
perMessageDeflate.accept(offers[
|
|
3548
|
-
extensions[
|
|
3612
|
+
const offers = extension2.parse(secWebSocketExtensions);
|
|
3613
|
+
if (offers[PerMessageDeflate2.extensionName]) {
|
|
3614
|
+
perMessageDeflate.accept(offers[PerMessageDeflate2.extensionName]);
|
|
3615
|
+
extensions[PerMessageDeflate2.extensionName] = perMessageDeflate;
|
|
3549
3616
|
}
|
|
3550
3617
|
} catch (err) {
|
|
3551
3618
|
const message = "Invalid or unacceptable Sec-WebSocket-Extensions header";
|
|
@@ -3601,7 +3668,7 @@ var require_websocket_server = __commonJS({
|
|
|
3601
3668
|
);
|
|
3602
3669
|
}
|
|
3603
3670
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
3604
|
-
const digest =
|
|
3671
|
+
const digest = createHash("sha1").update(key + GUID).digest("base64");
|
|
3605
3672
|
const headers = [
|
|
3606
3673
|
"HTTP/1.1 101 Switching Protocols",
|
|
3607
3674
|
"Upgrade: websocket",
|
|
@@ -3616,10 +3683,10 @@ var require_websocket_server = __commonJS({
|
|
|
3616
3683
|
ws._protocol = protocol;
|
|
3617
3684
|
}
|
|
3618
3685
|
}
|
|
3619
|
-
if (extensions[
|
|
3620
|
-
const params = extensions[
|
|
3621
|
-
const value =
|
|
3622
|
-
[
|
|
3686
|
+
if (extensions[PerMessageDeflate2.extensionName]) {
|
|
3687
|
+
const params = extensions[PerMessageDeflate2.extensionName].params;
|
|
3688
|
+
const value = extension2.format({
|
|
3689
|
+
[PerMessageDeflate2.extensionName]: [params]
|
|
3623
3690
|
});
|
|
3624
3691
|
headers.push(`Sec-WebSocket-Extensions: ${value}`);
|
|
3625
3692
|
ws._extensions = extensions;
|
|
@@ -3629,6 +3696,8 @@ var require_websocket_server = __commonJS({
|
|
|
3629
3696
|
socket.removeListener("error", socketOnError);
|
|
3630
3697
|
ws.setSocket(socket, head, {
|
|
3631
3698
|
allowSynchronousEvents: this.options.allowSynchronousEvents,
|
|
3699
|
+
maxBufferedChunks: this.options.maxBufferedChunks,
|
|
3700
|
+
maxFragments: this.options.maxFragments,
|
|
3632
3701
|
maxPayload: this.options.maxPayload,
|
|
3633
3702
|
skipUTF8Validation: this.options.skipUTF8Validation
|
|
3634
3703
|
});
|
|
@@ -3674,13 +3743,13 @@ var require_websocket_server = __commonJS({
|
|
|
3674
3743
|
` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message
|
|
3675
3744
|
);
|
|
3676
3745
|
}
|
|
3677
|
-
function abortHandshakeOrEmitwsClientError(server, req, socket, code, message) {
|
|
3746
|
+
function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) {
|
|
3678
3747
|
if (server.listenerCount("wsClientError")) {
|
|
3679
3748
|
const err = new Error(message);
|
|
3680
3749
|
Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);
|
|
3681
3750
|
server.emit("wsClientError", err, socket, req);
|
|
3682
3751
|
} else {
|
|
3683
|
-
abortHandshake(socket, code, message);
|
|
3752
|
+
abortHandshake(socket, code, message, headers);
|
|
3684
3753
|
}
|
|
3685
3754
|
}
|
|
3686
3755
|
}
|
|
@@ -4709,10 +4778,10 @@ var init_agent_hooks = __esm({
|
|
|
4709
4778
|
}
|
|
4710
4779
|
});
|
|
4711
4780
|
|
|
4712
|
-
// raw-import:/tmp/slz-publish-wt.
|
|
4781
|
+
// raw-import:/tmp/slz-publish-wt.A7COkR/packages/shared/hooks/src/notify.sh
|
|
4713
4782
|
var notify_default;
|
|
4714
4783
|
var init_notify = __esm({
|
|
4715
|
-
"raw-import:/tmp/slz-publish-wt.
|
|
4784
|
+
"raw-import:/tmp/slz-publish-wt.A7COkR/packages/shared/hooks/src/notify.sh"() {
|
|
4716
4785
|
notify_default = `#!/bin/sh
|
|
4717
4786
|
# SlayZone agent lifecycle hook \u2014 BENIGN DUMB FORWARDER.
|
|
4718
4787
|
#
|
|
@@ -4874,10 +4943,10 @@ exit 0
|
|
|
4874
4943
|
}
|
|
4875
4944
|
});
|
|
4876
4945
|
|
|
4877
|
-
// raw-import:/tmp/slz-publish-wt.
|
|
4946
|
+
// raw-import:/tmp/slz-publish-wt.A7COkR/packages/shared/hooks/src/opencode-plugin.js
|
|
4878
4947
|
var opencode_plugin_default;
|
|
4879
4948
|
var init_opencode_plugin = __esm({
|
|
4880
|
-
"raw-import:/tmp/slz-publish-wt.
|
|
4949
|
+
"raw-import:/tmp/slz-publish-wt.A7COkR/packages/shared/hooks/src/opencode-plugin.js"() {
|
|
4881
4950
|
opencode_plugin_default = "// SlayZone opencode plugin v1\n//\n// Forwards OpenCode SDK session lifecycle events to the SlayZone agent-hook\n// notify script over a local shell exec. Plugin is loaded by OpenCode from\n// ${XDG_CONFIG_HOME:-~/.config}/opencode/plugin/slayzone-notify.js\n//\n// The {{NOTIFY_PATH}} placeholder is substituted by the SlayZone installer\n// (packages/apps/app/src/main/agent-hooks/opencode-plugin-installer.ts) at\n// install time with the absolute path to `~/.slayzone/hooks/notify.sh`.\n//\n// Behavior:\n// - No-op when SLAYZONE_TASK_ID is unset (plugin only fires inside SlayZone PTYs).\n// - Subagent (child session) events are suppressed \u2014 oh-my-opencode + similar\n// tools spawn many child sessions and would otherwise flap Start/Stop.\n// - On client.session.list() error, sessions are assumed CHILD (safer to\n// suppress than emit a false-positive Start/Stop).\n// - Handles both modern (session.status w/ nested type) and legacy\n// (session.busy / session.idle) event shapes for forward compat.\n// - Singleton guard prevents double-load if OpenCode re-imports the plugin.\n\nexport const SlayzoneNotifyPlugin = async ({ $, client }) => {\n if (globalThis.__slayzoneOpencodePluginV1) return {}\n globalThis.__slayzoneOpencodePluginV1 = true\n if (!process?.env?.SLAYZONE_TASK_ID) return {}\n\n const notifyPath = '{{NOTIFY_PATH}}'\n let currentState = 'idle' // 'idle' | 'busy'\n let rootSessionID = null // first non-child session we see\n let stopSent = false // dedup Stop emits\n const childSessionCache = new Map() // sessionID -> isChild bool\n\n const notify = async (eventName) => {\n const payload = JSON.stringify({ hook_event_name: eventName })\n try {\n await $`bash ${notifyPath} ${payload}`\n } catch {\n // Hook failures must never bubble into the OpenCode TUI.\n }\n }\n\n const isChildSession = async (sessionID) => {\n if (!sessionID) return true\n if (!client?.session?.list) return true\n if (childSessionCache.has(sessionID)) return childSessionCache.get(sessionID)\n try {\n const sessions = await client.session.list()\n const session = sessions.data?.find((s) => s.id === sessionID)\n const isChild = !!session?.parentID\n childSessionCache.set(sessionID, isChild)\n return isChild\n } catch {\n // On error, assume CHILD \u2014 safer than emitting a false-positive Start/Stop.\n return true\n }\n }\n\n const handleBusy = async (sessionID) => {\n if (!rootSessionID) rootSessionID = sessionID\n if (sessionID !== rootSessionID) return\n if (currentState === 'idle') {\n currentState = 'busy'\n stopSent = false\n await notify('Start')\n }\n }\n\n const handleStop = async (sessionID) => {\n if (rootSessionID && sessionID !== rootSessionID) return\n if (currentState === 'busy' && !stopSent) {\n currentState = 'idle'\n stopSent = true\n await notify('Stop')\n rootSessionID = null // reset for next session\n }\n }\n\n return {\n event: async ({ event }) => {\n const sessionID = event.properties?.sessionID ?? event.properties?.info?.id ?? null\n\n if (event.type === 'session.created') {\n const isChild = Boolean(event.properties?.info?.parentID)\n if (sessionID) childSessionCache.set(sessionID, isChild)\n if (!isChild) await notify('SessionStart')\n return\n }\n\n if (event.type === 'session.deleted') {\n const cached = sessionID ? childSessionCache.get(sessionID) : undefined\n const isChild = cached !== undefined ? cached : await isChildSession(sessionID)\n if (!isChild) await notify('SessionEnd')\n if (sessionID) childSessionCache.delete(sessionID)\n return\n }\n\n if (await isChildSession(sessionID)) return\n\n if (event.type === 'session.status') {\n const status = event.properties?.status\n if (status?.type === 'busy') await handleBusy(sessionID)\n else if (status?.type === 'idle') await handleStop(sessionID)\n }\n // Backwards-compat: some OpenCode versions emit busy/idle as top-level events.\n if (event.type === 'session.busy') await handleBusy(sessionID)\n if (event.type === 'session.idle') await handleStop(sessionID)\n if (event.type === 'session.error') await handleStop(sessionID)\n },\n 'permission.ask': async (_permission, output) => {\n if (output.status === 'ask') await notify('PermissionRequest')\n }\n }\n}\n";
|
|
4882
4951
|
}
|
|
4883
4952
|
});
|
|
@@ -4937,6 +5006,7 @@ init_dirs();
|
|
|
4937
5006
|
var DEFAULT_LOCAL_COMPUTER_NAME = "local-computer";
|
|
4938
5007
|
|
|
4939
5008
|
// ../../shared/platform/src/slayzone-config.ts
|
|
5009
|
+
var IGNORED_COMPUTER_CONFIG_KEYS = ["pinnedCertSha256"];
|
|
4940
5010
|
function getComputerConfigFilePath() {
|
|
4941
5011
|
return (0, import_node_path.join)(getSlayzoneHomeDir(), "computer.config.json");
|
|
4942
5012
|
}
|
|
@@ -4953,8 +5023,6 @@ function coerceComputerConfig(raw) {
|
|
|
4953
5023
|
const roots = raw.allowedRoots.filter((r) => typeof r === "string" && r.length > 0);
|
|
4954
5024
|
if (roots.length > 0) cfg.allowedRoots = roots;
|
|
4955
5025
|
}
|
|
4956
|
-
if (typeof raw.pinnedCertSha256 === "string" && raw.pinnedCertSha256.length > 0)
|
|
4957
|
-
cfg.pinnedCertSha256 = raw.pinnedCertSha256;
|
|
4958
5026
|
return cfg;
|
|
4959
5027
|
}
|
|
4960
5028
|
function readJsonObject(path8) {
|
|
@@ -5005,6 +5073,11 @@ function loadComputerConfigFile(path8 = getComputerConfigFilePath()) {
|
|
|
5005
5073
|
const legacy = readJsonObject(legacyConfigFilePathFor(path8));
|
|
5006
5074
|
return legacy ? coerceComputerConfig(legacy) : {};
|
|
5007
5075
|
}
|
|
5076
|
+
function ignoredComputerConfigKeys(path8 = getComputerConfigFilePath()) {
|
|
5077
|
+
const raw = readJsonObject(path8) ?? readJsonObject(legacyConfigFilePathFor(path8));
|
|
5078
|
+
if (!raw) return [];
|
|
5079
|
+
return IGNORED_COMPUTER_CONFIG_KEYS.filter((key) => raw[key] !== void 0);
|
|
5080
|
+
}
|
|
5008
5081
|
function saveComputerConfigFile(cfg, path8 = getComputerConfigFilePath()) {
|
|
5009
5082
|
writeJsonAtomic(path8, cfg);
|
|
5010
5083
|
}
|
|
@@ -19435,7 +19508,11 @@ var gitCreateWorktreeParamsSchema = external_exports.object({
|
|
|
19435
19508
|
});
|
|
19436
19509
|
var gitRemoveWorktreeParamsSchema = external_exports.object({
|
|
19437
19510
|
projectPath: external_exports.string().min(1),
|
|
19438
|
-
worktreePath: external_exports.string().min(1)
|
|
19511
|
+
worktreePath: external_exports.string().min(1),
|
|
19512
|
+
/** Also force-delete the worktree's branch (`git branch -D`). OFF unless asked: the
|
|
19513
|
+
* hub's archive / delete / purge paths remove only the worktree, and unmerged,
|
|
19514
|
+
* unpushed commits on the branch would otherwise be left dangling. */
|
|
19515
|
+
deleteBranch: external_exports.boolean().optional()
|
|
19439
19516
|
});
|
|
19440
19517
|
var gitRemoveWorktreeResultSchema = external_exports.object({
|
|
19441
19518
|
branchDeleted: external_exports.boolean().optional(),
|
|
@@ -19690,23 +19767,6 @@ var procListResultSchema = external_exports.object({
|
|
|
19690
19767
|
)
|
|
19691
19768
|
});
|
|
19692
19769
|
|
|
19693
|
-
// ../../domains/computer-transport/src/shared/pinning.ts
|
|
19694
|
-
var import_node_crypto = require("node:crypto");
|
|
19695
|
-
var FINGERPRINT_RE = /^[0-9a-f]{64}$/;
|
|
19696
|
-
function normalizeCertSha256Fingerprint(input) {
|
|
19697
|
-
const normalized = input.replace(/[:\s]/g, "").toLowerCase();
|
|
19698
|
-
if (!FINGERPRINT_RE.test(normalized)) {
|
|
19699
|
-
throw new Error(`invalid sha256 certificate fingerprint: '${input}'`);
|
|
19700
|
-
}
|
|
19701
|
-
return normalized;
|
|
19702
|
-
}
|
|
19703
|
-
function certSha256FingerprintFromDer(der) {
|
|
19704
|
-
return (0, import_node_crypto.createHash)("sha256").update(der).digest("hex");
|
|
19705
|
-
}
|
|
19706
|
-
function certMatchesFingerprint(expected, presentedDer) {
|
|
19707
|
-
return normalizeCertSha256Fingerprint(expected) === certSha256FingerprintFromDer(presentedDer);
|
|
19708
|
-
}
|
|
19709
|
-
|
|
19710
19770
|
// ../../domains/computer-transport/src/shared/events.ts
|
|
19711
19771
|
var TypedEventEmitter = class {
|
|
19712
19772
|
listeners = /* @__PURE__ */ new Map();
|
|
@@ -19789,9 +19849,7 @@ function slayzoneRootDir() {
|
|
|
19789
19849
|
}
|
|
19790
19850
|
var storedComputerCredentialsSchema = external_exports.object({
|
|
19791
19851
|
computerId: external_exports.string().min(1),
|
|
19792
|
-
apiKey: external_exports.string().min(1)
|
|
19793
|
-
/** Pin recorded at enroll time (lowercase hex sha256 of the hub leaf DER). */
|
|
19794
|
-
pinnedFingerprint: external_exports.string().optional()
|
|
19852
|
+
apiKey: external_exports.string().min(1)
|
|
19795
19853
|
});
|
|
19796
19854
|
var credentialsMapSchema = external_exports.record(external_exports.string(), storedComputerCredentialsSchema);
|
|
19797
19855
|
function hubHostFromUrl(url2) {
|
|
@@ -19869,25 +19927,27 @@ function createFileCredentialStore(hubHost, options = {}) {
|
|
|
19869
19927
|
}
|
|
19870
19928
|
|
|
19871
19929
|
// ../../domains/computer-transport/src/client/hub-dialer.ts
|
|
19872
|
-
var
|
|
19930
|
+
var import_node_crypto = require("node:crypto");
|
|
19873
19931
|
|
|
19874
19932
|
// ../../../node_modules/ws/wrapper.mjs
|
|
19875
19933
|
var import_stream = __toESM(require_stream(), 1);
|
|
19934
|
+
var import_extension = __toESM(require_extension(), 1);
|
|
19935
|
+
var import_permessage_deflate = __toESM(require_permessage_deflate(), 1);
|
|
19876
19936
|
var import_receiver = __toESM(require_receiver(), 1);
|
|
19877
19937
|
var import_sender = __toESM(require_sender(), 1);
|
|
19938
|
+
var import_subprotocol = __toESM(require_subprotocol(), 1);
|
|
19878
19939
|
var import_websocket = __toESM(require_websocket(), 1);
|
|
19879
19940
|
var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
19880
19941
|
var wrapper_default = import_websocket.default;
|
|
19881
19942
|
|
|
19882
19943
|
// ../../domains/computer-transport/src/client/hub-dialer.ts
|
|
19883
|
-
var PROCESS_EPOCH = (0,
|
|
19944
|
+
var PROCESS_EPOCH = (0, import_node_crypto.randomUUID)();
|
|
19884
19945
|
var DEFAULT_HEARTBEAT_INTERVAL_MS = 15e3;
|
|
19885
19946
|
var DEFAULT_HEARTBEAT_TIMEOUT_MS = 1e4;
|
|
19886
19947
|
var HubDialer = class {
|
|
19887
19948
|
events;
|
|
19888
19949
|
opts;
|
|
19889
19950
|
log;
|
|
19890
|
-
pinnedFingerprint;
|
|
19891
19951
|
stateValue = "stopped";
|
|
19892
19952
|
current = null;
|
|
19893
19953
|
retryTimer = null;
|
|
@@ -19911,14 +19971,6 @@ var HubDialer = class {
|
|
|
19911
19971
|
if (protocol !== "ws:" && protocol !== "wss:") {
|
|
19912
19972
|
throw new Error(`hub url must be ws:// or wss://, got '${opts.url}'`);
|
|
19913
19973
|
}
|
|
19914
|
-
if (opts.pinnedCertSha256 !== void 0) {
|
|
19915
|
-
if (protocol !== "wss:") {
|
|
19916
|
-
throw new Error("pinnedCertSha256 requires a wss:// hub url");
|
|
19917
|
-
}
|
|
19918
|
-
this.pinnedFingerprint = normalizeCertSha256Fingerprint(opts.pinnedCertSha256);
|
|
19919
|
-
} else {
|
|
19920
|
-
this.pinnedFingerprint = null;
|
|
19921
|
-
}
|
|
19922
19974
|
}
|
|
19923
19975
|
get state() {
|
|
19924
19976
|
return this.stateValue;
|
|
@@ -19981,55 +20033,11 @@ var HubDialer = class {
|
|
|
19981
20033
|
this.stateValue = state;
|
|
19982
20034
|
this.events.emit("state-change", { state });
|
|
19983
20035
|
}
|
|
19984
|
-
buildWsOptions() {
|
|
19985
|
-
if (!this.pinnedFingerprint) return {};
|
|
19986
|
-
const expected = this.pinnedFingerprint;
|
|
19987
|
-
const tlsOptions = {
|
|
19988
|
-
// The pin *replaces* CA-chain trust — hubs present self-signed certs.
|
|
19989
|
-
// NOTE: with rejectUnauthorized:false node records a checkServerIdentity
|
|
19990
|
-
// failure in socket.authorizationError but does NOT abort the handshake,
|
|
19991
|
-
// so the pin is ENFORCED in verifyPinnedCert() (ws 'upgrade' event) —
|
|
19992
|
-
// this override only makes the failure observable early.
|
|
19993
|
-
rejectUnauthorized: false,
|
|
19994
|
-
checkServerIdentity: (_host, cert) => {
|
|
19995
|
-
if (!cert?.raw) return new Error("hub presented no certificate");
|
|
19996
|
-
if (!certMatchesFingerprint(expected, cert.raw)) {
|
|
19997
|
-
const actual = certSha256FingerprintFromDer(cert.raw);
|
|
19998
|
-
return new Error(
|
|
19999
|
-
`hub certificate fingerprint mismatch: expected ${expected}, got ${actual}`
|
|
20000
|
-
);
|
|
20001
|
-
}
|
|
20002
|
-
return void 0;
|
|
20003
|
-
}
|
|
20004
|
-
};
|
|
20005
|
-
return tlsOptions;
|
|
20006
|
-
}
|
|
20007
|
-
/**
|
|
20008
|
-
* Hard pin enforcement. Runs on the ws 'upgrade' event — after the TLS
|
|
20009
|
-
* handshake and the (secret-free) HTTP upgrade request, but before 'open',
|
|
20010
|
-
* so no computer frame (hello/enroll credentials) is ever sent to an unpinned
|
|
20011
|
-
* peer. Returns false and tears the socket down on mismatch.
|
|
20012
|
-
*/
|
|
20013
|
-
verifyPinnedCert(ws, tlsSocket) {
|
|
20014
|
-
const expected = this.pinnedFingerprint;
|
|
20015
|
-
if (!expected) return true;
|
|
20016
|
-
const cert = typeof tlsSocket.getPeerCertificate === "function" ? tlsSocket.getPeerCertificate() : null;
|
|
20017
|
-
const raw = cert && cert.raw ? cert.raw : null;
|
|
20018
|
-
if (raw && certMatchesFingerprint(expected, raw)) return true;
|
|
20019
|
-
const actual = raw ? certSha256FingerprintFromDer(raw) : "no certificate";
|
|
20020
|
-
const error48 = new Error(
|
|
20021
|
-
`hub certificate fingerprint mismatch: expected ${expected}, got ${actual}`
|
|
20022
|
-
);
|
|
20023
|
-
this.log("computer dialer rejected hub certificate", { error: error48.message });
|
|
20024
|
-
this.events.emit("error", { error: error48, fatal: false });
|
|
20025
|
-
ws.terminate();
|
|
20026
|
-
return false;
|
|
20027
|
-
}
|
|
20028
20036
|
connect() {
|
|
20029
20037
|
this.retryTimer = null;
|
|
20030
20038
|
this.triedTokenRefresh = false;
|
|
20031
20039
|
this.setState("connecting");
|
|
20032
|
-
const ws = new wrapper_default(this.opts.url
|
|
20040
|
+
const ws = new wrapper_default(this.opts.url);
|
|
20033
20041
|
const conn = {
|
|
20034
20042
|
ws,
|
|
20035
20043
|
rpc: null,
|
|
@@ -20050,11 +20058,6 @@ var HubDialer = class {
|
|
|
20050
20058
|
}
|
|
20051
20059
|
});
|
|
20052
20060
|
this.current = conn;
|
|
20053
|
-
if (this.pinnedFingerprint) {
|
|
20054
|
-
ws.on("upgrade", (response) => {
|
|
20055
|
-
this.verifyPinnedCert(ws, response.socket);
|
|
20056
|
-
});
|
|
20057
|
-
}
|
|
20058
20061
|
ws.on("open", () => {
|
|
20059
20062
|
if (this.current === conn && !this.stopping) void this.authenticate(conn);
|
|
20060
20063
|
});
|
|
@@ -20181,8 +20184,7 @@ var HubDialer = class {
|
|
|
20181
20184
|
try {
|
|
20182
20185
|
await this.opts.credentialStore.save({
|
|
20183
20186
|
computerId: result.computerId,
|
|
20184
|
-
apiKey: result.apiKey
|
|
20185
|
-
...this.pinnedFingerprint ? { pinnedFingerprint: this.pinnedFingerprint } : {}
|
|
20187
|
+
apiKey: result.apiKey
|
|
20186
20188
|
});
|
|
20187
20189
|
} catch (err) {
|
|
20188
20190
|
const error48 = new Error(
|
|
@@ -20297,7 +20299,8 @@ var import_node_path3 = require("node:path");
|
|
|
20297
20299
|
|
|
20298
20300
|
// ../../shared/platform/src/join-token.ts
|
|
20299
20301
|
var JOIN_TOKEN_PREFIX = "szjt1";
|
|
20300
|
-
|
|
20302
|
+
var JOIN_TOKEN_MAX_TTL_MS = 60 * 6e4;
|
|
20303
|
+
function parseJoinTokenBody(token) {
|
|
20301
20304
|
const dot = token.indexOf(".");
|
|
20302
20305
|
if (dot === -1 || token.slice(0, dot) !== JOIN_TOKEN_PREFIX) return null;
|
|
20303
20306
|
const body = token.slice(dot + 1);
|
|
@@ -20305,15 +20308,23 @@ function decodeJoinToken(token) {
|
|
|
20305
20308
|
try {
|
|
20306
20309
|
const parsed = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
|
|
20307
20310
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
20308
|
-
|
|
20309
|
-
if (typeof hubUrl !== "string" || typeof certFingerprint !== "string" || typeof secret !== "string") {
|
|
20310
|
-
return null;
|
|
20311
|
-
}
|
|
20312
|
-
return { hubUrl, certFingerprint, secret };
|
|
20311
|
+
return parsed;
|
|
20313
20312
|
} catch {
|
|
20314
20313
|
return null;
|
|
20315
20314
|
}
|
|
20316
20315
|
}
|
|
20316
|
+
function decodeJoinToken(token) {
|
|
20317
|
+
const parsed = parseJoinTokenBody(token);
|
|
20318
|
+
if (!parsed) return null;
|
|
20319
|
+
const { hubUrl, secret } = parsed;
|
|
20320
|
+
if (typeof hubUrl !== "string" || typeof secret !== "string") return null;
|
|
20321
|
+
return { hubUrl, secret };
|
|
20322
|
+
}
|
|
20323
|
+
function joinTokenCarriesCertPin(token) {
|
|
20324
|
+
if (!decodeJoinToken(token)) return false;
|
|
20325
|
+
const pin = parseJoinTokenBody(token)?.certFingerprint;
|
|
20326
|
+
return typeof pin === "string" && pin !== "";
|
|
20327
|
+
}
|
|
20317
20328
|
|
|
20318
20329
|
// src/config.ts
|
|
20319
20330
|
var computerConfigSchema = external_exports.object({
|
|
@@ -20344,9 +20355,7 @@ var computerConfigSchema = external_exports.object({
|
|
|
20344
20355
|
/** Filesystem roots this computer may operate under (fs./git. commands). */
|
|
20345
20356
|
allowedRoots: external_exports.array(external_exports.string().min(1)),
|
|
20346
20357
|
/** Capability tags advertised at enrollment. */
|
|
20347
|
-
capabilities: external_exports.array(external_exports.string().min(1))
|
|
20348
|
-
/** sha256 pin of the hub TLS leaf cert (lowercase hex; colons tolerated). */
|
|
20349
|
-
pinnedCertSha256: external_exports.string().min(1).optional()
|
|
20358
|
+
capabilities: external_exports.array(external_exports.string().min(1))
|
|
20350
20359
|
});
|
|
20351
20360
|
var ENV_VARS = {
|
|
20352
20361
|
// Authority ONLY — `host[:port]`, no scheme, no path. The dial scheme
|
|
@@ -20358,8 +20367,8 @@ var ENV_VARS = {
|
|
|
20358
20367
|
// into terminals, so outside the collision).
|
|
20359
20368
|
hubAddress: "SLAYZONE_HUB_ADDRESS",
|
|
20360
20369
|
// HUB_-prefixed because the token is hub-scoped BY VALUE, not by reader: the hub
|
|
20361
|
-
// mints it and it embeds the hub's `wss://…/computers` url
|
|
20362
|
-
//
|
|
20370
|
+
// mints it and it embeds the hub's `wss://…/computers` url and a secret checked
|
|
20371
|
+
// against the hub's `join_tokens` row.
|
|
20363
20372
|
// `mintJoinToken` binds it to NO computer (computer_id is NULL until redemption), so
|
|
20364
20373
|
// any computer can redeem any unused token — the old `SLAYZONE_RUNNER_JOIN_TOKEN`
|
|
20365
20374
|
// named its CONSUMER, which is what CLAUDE.md rule 2 forbids. `_TOKEN` suffix +
|
|
@@ -20377,9 +20386,8 @@ var ENV_VARS = {
|
|
|
20377
20386
|
// <ROOT>/computer.config.json `allowedRoots` (+ the ROOT default in bin.ts). The
|
|
20378
20387
|
// computer NAME likewise has no env channel — it derives from SUPERVISED (→
|
|
20379
20388
|
// DEFAULT_LOCAL_COMPUTER_NAME) or computer.config.json `computerName`, else the hostname.
|
|
20380
|
-
//
|
|
20381
|
-
//
|
|
20382
|
-
// Never a bare env var — a fingerprint is never fished out of ambient env.
|
|
20389
|
+
// There is no certificate pin on any channel: a wss:// hub's front end is verified
|
|
20390
|
+
// the normal way (see ignoredCertPinNotices).
|
|
20383
20391
|
};
|
|
20384
20392
|
var DEFAULT_CAPABILITIES = ["pty", "git", "fs", "proc"];
|
|
20385
20393
|
function realpathBoundary(target) {
|
|
@@ -20428,7 +20436,6 @@ function fromSharedConfig(shared) {
|
|
|
20428
20436
|
if (shared.joinToken !== void 0) out.joinToken = shared.joinToken;
|
|
20429
20437
|
if (shared.computerName !== void 0) out.name = shared.computerName;
|
|
20430
20438
|
if (shared.allowedRoots !== void 0) out.allowedRoots = shared.allowedRoots;
|
|
20431
|
-
if (shared.pinnedCertSha256 !== void 0) out.pinnedCertSha256 = shared.pinnedCertSha256;
|
|
20432
20439
|
return out;
|
|
20433
20440
|
}
|
|
20434
20441
|
function loadComputerConfig(env = process.env, shared = env === process.env && env.SLAYZONE_SUPERVISED !== "1" ? loadComputerConfigFile() : {}) {
|
|
@@ -20449,15 +20456,7 @@ function loadComputerConfig(env = process.env, shared = env === process.env && e
|
|
|
20449
20456
|
// fallback in bin.ts. No env channel either way.
|
|
20450
20457
|
allowedRoots: env.SLAYZONE_SUPERVISED === "1" ? [(0, import_node_os2.homedir)()] : [],
|
|
20451
20458
|
capabilities: [...DEFAULT_CAPABILITIES],
|
|
20452
|
-
...fromToken ? {
|
|
20453
|
-
hubUrl: fromToken.hubUrl,
|
|
20454
|
-
// A token minted by the current hub carries an EMPTY fingerprint: the hub
|
|
20455
|
-
// no longer presents a certificate of its own, so there is nothing to pin
|
|
20456
|
-
// and the front end's certificate is verified the normal way. An empty
|
|
20457
|
-
// string must read as "no pin", never reach the schema (min(1)) and fail
|
|
20458
|
-
// the whole config. A token from an older hub still carries a real pin.
|
|
20459
|
-
...fromToken.certFingerprint !== "" ? { pinnedCertSha256: fromToken.certFingerprint } : {}
|
|
20460
|
-
} : {},
|
|
20459
|
+
...fromToken ? { hubUrl: fromToken.hubUrl } : {},
|
|
20461
20460
|
// <ROOT>/computer.config.json — base under env (spread after). The single config file.
|
|
20462
20461
|
...fromShared,
|
|
20463
20462
|
...hubUrlFromEnv !== void 0 ? { hubUrl: hubUrlFromEnv } : {},
|
|
@@ -20470,12 +20469,6 @@ function loadComputerConfig(env = process.env, shared = env === process.env && e
|
|
|
20470
20469
|
`invalid computer configuration (${issues}). Set ${ENV_VARS.hubAddress} (and ${ENV_VARS.joinToken} for first contact) or a <ROOT>/computer.config.json.`
|
|
20471
20470
|
);
|
|
20472
20471
|
}
|
|
20473
|
-
const explicitPin = fromShared.pinnedCertSha256;
|
|
20474
|
-
if (explicitPin !== void 0 && urlProtocol(result.data.hubUrl) === "ws:") {
|
|
20475
|
-
throw new Error(
|
|
20476
|
-
`config pinnedCertSha256 requires a wss:// hub url; got '${result.data.hubUrl}'. Pinning has no effect without TLS \u2014 use a wss:// url or drop the pin.`
|
|
20477
|
-
);
|
|
20478
|
-
}
|
|
20479
20472
|
for (const url2 of effectiveHubUrls(result.data)) {
|
|
20480
20473
|
if (urlProtocol(url2) === "ws:" && !isLoopbackComputerUrl(url2)) {
|
|
20481
20474
|
throw new Error(
|
|
@@ -20485,6 +20478,21 @@ function loadComputerConfig(env = process.env, shared = env === process.env && e
|
|
|
20485
20478
|
}
|
|
20486
20479
|
return result.data;
|
|
20487
20480
|
}
|
|
20481
|
+
function ignoredCertPinNotices(env = process.env, shared = env === process.env && env.SLAYZONE_SUPERVISED !== "1" ? loadComputerConfigFile() : {}, ignoredFileKeys = env === process.env && env.SLAYZONE_SUPERVISED !== "1" ? ignoredComputerConfigKeys() : []) {
|
|
20482
|
+
const notices = [];
|
|
20483
|
+
const joinToken = env[ENV_VARS.joinToken] ?? shared.joinToken;
|
|
20484
|
+
if (joinToken && joinTokenCarriesCertPin(joinToken)) {
|
|
20485
|
+
notices.push(
|
|
20486
|
+
"ignoring the certificate pin in the join token (minted by an older hub): the hub's certificate is verified against the trusted CAs instead"
|
|
20487
|
+
);
|
|
20488
|
+
}
|
|
20489
|
+
if (ignoredFileKeys.includes("pinnedCertSha256")) {
|
|
20490
|
+
notices.push(
|
|
20491
|
+
"ignoring 'pinnedCertSha256' in computer.config.json: certificate pinning was removed and the hub's certificate is verified against the trusted CAs instead \u2014 delete the key"
|
|
20492
|
+
);
|
|
20493
|
+
}
|
|
20494
|
+
return notices;
|
|
20495
|
+
}
|
|
20488
20496
|
function urlProtocol(url2) {
|
|
20489
20497
|
try {
|
|
20490
20498
|
return new URL(url2).protocol;
|
|
@@ -20498,7 +20506,7 @@ function effectiveHubUrls(config2) {
|
|
|
20498
20506
|
}
|
|
20499
20507
|
|
|
20500
20508
|
// src/host-id.ts
|
|
20501
|
-
var
|
|
20509
|
+
var import_node_crypto2 = require("node:crypto");
|
|
20502
20510
|
var import_promises3 = require("node:fs/promises");
|
|
20503
20511
|
var import_node_os3 = require("node:os");
|
|
20504
20512
|
var import_node_path4 = require("node:path");
|
|
@@ -20508,6 +20516,9 @@ function slayzoneRootDir2() {
|
|
|
20508
20516
|
return (0, import_node_path4.join)(home, ".slayzone");
|
|
20509
20517
|
}
|
|
20510
20518
|
function hostIdFilePath(baseDir) {
|
|
20519
|
+
return (0, import_node_path4.join)(baseDir ?? slayzoneRootDir2(), "computer.host.json");
|
|
20520
|
+
}
|
|
20521
|
+
function legacyHostIdFilePath(baseDir) {
|
|
20511
20522
|
return (0, import_node_path4.join)(baseDir ?? slayzoneRootDir2(), "computer.host-id.json");
|
|
20512
20523
|
}
|
|
20513
20524
|
function sharedHostIdPath() {
|
|
@@ -20571,13 +20582,20 @@ async function reconcileHostId(options = {}) {
|
|
|
20571
20582
|
const sharedPath = options.sharedPath === void 0 ? sharedHostIdPath() : options.sharedPath;
|
|
20572
20583
|
const log = options.log ?? (() => void 0);
|
|
20573
20584
|
let durable = await readDurable(filePath);
|
|
20585
|
+
if (!durable) {
|
|
20586
|
+
const legacy = await readDurable(legacyHostIdFilePath(options.baseDir));
|
|
20587
|
+
if (legacy) {
|
|
20588
|
+
durable = legacy;
|
|
20589
|
+
await writeDurable(filePath, durable);
|
|
20590
|
+
}
|
|
20591
|
+
}
|
|
20574
20592
|
const shared = sharedPath ? await readShared(sharedPath) : null;
|
|
20575
20593
|
if (shared && durable && shared !== durable) {
|
|
20576
20594
|
log("host id adopted from the shared file", { from: durable, to: shared });
|
|
20577
20595
|
durable = shared;
|
|
20578
20596
|
await writeDurable(filePath, durable);
|
|
20579
20597
|
} else if (!durable) {
|
|
20580
|
-
durable = shared ?? (0,
|
|
20598
|
+
durable = shared ?? (0, import_node_crypto2.randomUUID)();
|
|
20581
20599
|
await writeDurable(filePath, durable);
|
|
20582
20600
|
}
|
|
20583
20601
|
if (sharedPath && shared !== durable) {
|
|
@@ -20970,7 +20988,7 @@ function subscribeFileWatcher(rootPath, listener) {
|
|
|
20970
20988
|
const watcher = fs2.watch(root, { recursive: true }, (_eventType, filename) => {
|
|
20971
20989
|
if (!filename) return;
|
|
20972
20990
|
const relPath = filename.replace(/\\/g, "/");
|
|
20973
|
-
if (
|
|
20991
|
+
if (ignoredSafely(root, relPath)) return;
|
|
20974
20992
|
if (path3.basename(relPath) === ".gitignore") {
|
|
20975
20993
|
invalidateIgnoreCache(root);
|
|
20976
20994
|
}
|
|
@@ -20991,6 +21009,9 @@ function subscribeFileWatcher(rootPath, listener) {
|
|
|
20991
21009
|
}, 100)
|
|
20992
21010
|
);
|
|
20993
21011
|
});
|
|
21012
|
+
watcher.on("error", (err) => {
|
|
21013
|
+
console.warn(`[file-editor] watcher on ${root}: ${err.message}`);
|
|
21014
|
+
});
|
|
20994
21015
|
watchers.set(root, { watcher, listeners, debounceMap });
|
|
20995
21016
|
return () => unsubscribe(root, listener);
|
|
20996
21017
|
} catch {
|
|
@@ -20998,6 +21019,13 @@ function subscribeFileWatcher(rootPath, listener) {
|
|
|
20998
21019
|
};
|
|
20999
21020
|
}
|
|
21000
21021
|
}
|
|
21022
|
+
function ignoredSafely(root, relPath) {
|
|
21023
|
+
try {
|
|
21024
|
+
return isIgnored(root, relPath, false);
|
|
21025
|
+
} catch {
|
|
21026
|
+
return false;
|
|
21027
|
+
}
|
|
21028
|
+
}
|
|
21001
21029
|
function unsubscribe(root, listener) {
|
|
21002
21030
|
const entry = watchers.get(root);
|
|
21003
21031
|
if (!entry) return;
|
|
@@ -21140,6 +21168,75 @@ async function discoverRepos(rootPath, maxDepth = DEFAULT_REPO_SCAN_DEPTH) {
|
|
|
21140
21168
|
return entries;
|
|
21141
21169
|
}
|
|
21142
21170
|
|
|
21171
|
+
// ../../shared/platform/src/hub-switches.ts
|
|
21172
|
+
var HUB_SWITCH_ENV = {
|
|
21173
|
+
requireLogin: "SLAYZONE_HUB_REQUIRE_LOGIN",
|
|
21174
|
+
enablePassword: "SLAYZONE_HUB_ENABLE_PASSWORD",
|
|
21175
|
+
enableSso: "SLAYZONE_HUB_ENABLE_SSO",
|
|
21176
|
+
enableProcesses: "SLAYZONE_HUB_ENABLE_PROCESSES",
|
|
21177
|
+
enableIntegrations: "SLAYZONE_HUB_ENABLE_INTEGRATIONS"
|
|
21178
|
+
};
|
|
21179
|
+
var HUB_SSO_ENV = {
|
|
21180
|
+
tenantId: "SLAYZONE_HUB_SSO_TENANT_ID",
|
|
21181
|
+
clientId: "SLAYZONE_HUB_SSO_CLIENT_ID",
|
|
21182
|
+
/** PEM certificate registered on the Entra app (its SHA-256 thumbprint goes in each assertion). Env only. */
|
|
21183
|
+
certPath: "SLAYZONE_HUB_SSO_CERT_PATH",
|
|
21184
|
+
/** PEM private key of that certificate (RSA, unencrypted). Env only. */
|
|
21185
|
+
keyPath: "SLAYZONE_HUB_SSO_KEY_PATH",
|
|
21186
|
+
/** `0|1`, default `1`: refuse a sign-in whose ID token's `amr` does not contain `mfa`. */
|
|
21187
|
+
requireMfa: "SLAYZONE_HUB_SSO_REQUIRE_MFA"
|
|
21188
|
+
};
|
|
21189
|
+
var RETIRED_HUB_SSO_CLIENT_SECRET_ENV = "SLAYZONE_HUB_SSO_CLIENT_SECRET";
|
|
21190
|
+
var HUB_ADDRESS_ENV = {
|
|
21191
|
+
/** Where the hub LISTENS. Renamed from `SLAYZONE_HUB_ADDRESS`, which now only
|
|
21192
|
+
* means "the hub to connect to" on a computer / `slay`. */
|
|
21193
|
+
listen: "SLAYZONE_HUB_LISTEN_ADDRESS",
|
|
21194
|
+
/** How OTHER machines reach the hub (`host[:port]`, no scheme). */
|
|
21195
|
+
public: "SLAYZONE_HUB_PUBLIC_ADDRESS",
|
|
21196
|
+
/** Signing key of hub-auth. */
|
|
21197
|
+
authSecret: "SLAYZONE_HUB_AUTH_SECRET"
|
|
21198
|
+
};
|
|
21199
|
+
var LEGACY_HUB_LISTEN_ENV = "SLAYZONE_HUB_ADDRESS";
|
|
21200
|
+
var HUB_SESSION_RETENTION_DAYS_ENV = "SLAYZONE_HUB_SESSION_RETENTION_DAYS";
|
|
21201
|
+
var HUB_ALLOWED_WEB_ORIGINS_ENV = "SLAYZONE_HUB_ALLOWED_WEB_ORIGINS";
|
|
21202
|
+
var HUB_TRUSTED_PROXIES_ENV = "SLAYZONE_HUB_TRUSTED_PROXIES";
|
|
21203
|
+
var HUB_CONVEX_ADDRESS_ENV = "SLAYZONE_HUB_CONVEX_ADDRESS";
|
|
21204
|
+
var HUB_PROCESS_ENV = [
|
|
21205
|
+
...Object.values(HUB_SWITCH_ENV),
|
|
21206
|
+
...Object.values(HUB_SSO_ENV),
|
|
21207
|
+
RETIRED_HUB_SSO_CLIENT_SECRET_ENV,
|
|
21208
|
+
...Object.values(HUB_ADDRESS_ENV),
|
|
21209
|
+
LEGACY_HUB_LISTEN_ENV,
|
|
21210
|
+
HUB_ALLOWED_WEB_ORIGINS_ENV,
|
|
21211
|
+
HUB_TRUSTED_PROXIES_ENV,
|
|
21212
|
+
HUB_SESSION_RETENTION_DAYS_ENV,
|
|
21213
|
+
HUB_CONVEX_ADDRESS_ENV
|
|
21214
|
+
];
|
|
21215
|
+
|
|
21216
|
+
// ../../shared/platform/src/security-log.ts
|
|
21217
|
+
var import_node_async_hooks = require("node:async_hooks");
|
|
21218
|
+
var LINE_SEPARATOR = String.fromCharCode(8232);
|
|
21219
|
+
var PARAGRAPH_SEPARATOR = String.fromCharCode(8233);
|
|
21220
|
+
var contextStore = new import_node_async_hooks.AsyncLocalStorage();
|
|
21221
|
+
|
|
21222
|
+
// ../../shared/platform/src/hub-switch-refusal.ts
|
|
21223
|
+
var MESSAGES = {
|
|
21224
|
+
HUB_PROCESSES_DISABLED: `This hub does not run processes, automation commands, terminals or agents itself (${HUB_SWITCH_ENV.enableProcesses}=0).`,
|
|
21225
|
+
HUB_INTEGRATIONS_DISABLED: `Integrations are switched off on this hub (${HUB_SWITCH_ENV.enableIntegrations}=0).`,
|
|
21226
|
+
NO_COMPUTER_CONNECTED: `Connect a computer: this hub does not read project files or run git, gh or other commands itself (${HUB_SWITCH_ENV.enableProcesses}=0).`,
|
|
21227
|
+
HUB_PASSWORD_DISABLED: `Password sign-in is switched off on this hub (${HUB_SWITCH_ENV.enablePassword}=0).`,
|
|
21228
|
+
HUB_CONVEX_NOT_CONFIGURED: `GitHub sign-in is off on this hub: no Convex deployment is configured (${HUB_CONVEX_ADDRESS_ENV}).`,
|
|
21229
|
+
HUB_CONVEX_MISMATCH: `This hub starts GitHub sign-in only against its own Convex deployment (${HUB_CONVEX_ADDRESS_ENV}); the request named another.`
|
|
21230
|
+
};
|
|
21231
|
+
var VARIABLES = {
|
|
21232
|
+
HUB_PROCESSES_DISABLED: HUB_SWITCH_ENV.enableProcesses,
|
|
21233
|
+
HUB_INTEGRATIONS_DISABLED: HUB_SWITCH_ENV.enableIntegrations,
|
|
21234
|
+
NO_COMPUTER_CONNECTED: HUB_SWITCH_ENV.enableProcesses,
|
|
21235
|
+
HUB_PASSWORD_DISABLED: HUB_SWITCH_ENV.enablePassword,
|
|
21236
|
+
HUB_CONVEX_NOT_CONFIGURED: HUB_CONVEX_ADDRESS_ENV,
|
|
21237
|
+
HUB_CONVEX_MISMATCH: HUB_CONVEX_ADDRESS_ENV
|
|
21238
|
+
};
|
|
21239
|
+
|
|
21143
21240
|
// src/handlers/fs.ts
|
|
21144
21241
|
var BROWSE_ALWAYS_HIDDEN = /* @__PURE__ */ new Set([".git", ".DS_Store", "node_modules"]);
|
|
21145
21242
|
function createFsHandlers(ctx) {
|
|
@@ -21381,14 +21478,16 @@ var ENV_MANIFEST = {
|
|
|
21381
21478
|
// (name by what the value IS). `_SECRET` = a key you HOLD and sign with, vs
|
|
21382
21479
|
// `_TOKEN` = a bearer you PRESENT (SLAYZONE_HUB_TOKEN above).
|
|
21383
21480
|
SLAYZONE_HUB_AUTH_SECRET: "secret",
|
|
21384
|
-
// Hub-scoped by VALUE: the hub mints it, and it embeds the hub's url
|
|
21385
|
-
//
|
|
21481
|
+
// Hub-scoped by VALUE: the hub mints it, and it embeds the hub's url and a
|
|
21482
|
+
// secret verified against the hub's `join_tokens`
|
|
21386
21483
|
// row. `mintJoinToken` binds it to NO computer (computer_id stays NULL until
|
|
21387
21484
|
// redemption), so any computer can redeem any unused token — there is no computer in
|
|
21388
21485
|
// the value to name. Rule 2 (name by what the value IS, not who reads it).
|
|
21389
21486
|
SLAYZONE_HUB_JOIN_TOKEN: "secret",
|
|
21390
|
-
//
|
|
21391
|
-
//
|
|
21487
|
+
// Retired before it was ever read: Entra sign-in authenticates with a certificate
|
|
21488
|
+
// (SLAYZONE_HUB_SSO_CERT_PATH / _KEY_PATH below), and boot refuses a hub that still
|
|
21489
|
+
// sets this (B7). Still classified `secret` so a leftover value never reaches a
|
|
21490
|
+
// terminal or a log.
|
|
21392
21491
|
SLAYZONE_HUB_SSO_CLIENT_SECRET: "secret",
|
|
21393
21492
|
// Per-boot bearer the desktop's `/cap` listener requires on every connection
|
|
21394
21493
|
// (desktop-bridge-server.ts `verifyClient`). Loopback is NOT trusted there —
|
|
@@ -21411,6 +21510,9 @@ var ENV_MANIFEST = {
|
|
|
21411
21510
|
// hub-only; where the hub listens
|
|
21412
21511
|
SLAYZONE_HUB_PUBLIC_ADDRESS: "infra",
|
|
21413
21512
|
// hub-only; how other machines reach it, written into join tokens
|
|
21513
|
+
// Hub-only; the front ends (IPs/CIDRs, comma-separated) whose X-Forwarded-For names
|
|
21514
|
+
// the client (client-address.ts). Not `_ADDRESS`: these are networks, not an authority.
|
|
21515
|
+
SLAYZONE_HUB_TRUSTED_PROXIES: "infra",
|
|
21414
21516
|
// Per-hub switches (0|1) replacing SLAYZONE_MODE. Infra: they describe THIS hub
|
|
21415
21517
|
// process, so a task terminal must not inherit them (a hub started from one would
|
|
21416
21518
|
// otherwise pick up its parent's switches by accident).
|
|
@@ -21421,10 +21523,23 @@ var ENV_MANIFEST = {
|
|
|
21421
21523
|
SLAYZONE_HUB_ENABLE_INTEGRATIONS: "infra",
|
|
21422
21524
|
SLAYZONE_HUB_SSO_TENANT_ID: "infra",
|
|
21423
21525
|
SLAYZONE_HUB_SSO_CLIENT_ID: "infra",
|
|
21526
|
+
// Paths to the Entra client certificate and its private key, and the MFA switch.
|
|
21527
|
+
// Infra, not secret: a path is not the key (the file's own permissions protect it),
|
|
21528
|
+
// but a task terminal must still never inherit a hub's SSO wiring.
|
|
21529
|
+
SLAYZONE_HUB_SSO_CERT_PATH: "infra",
|
|
21530
|
+
SLAYZONE_HUB_SSO_KEY_PATH: "infra",
|
|
21531
|
+
SLAYZONE_HUB_SSO_REQUIRE_MFA: "infra",
|
|
21424
21532
|
// Operator-facing hub name (`slay hub ls`/`stop` address a hub by it). Infra,
|
|
21425
21533
|
// not global: it identifies THIS hub process, so inheriting it into a task
|
|
21426
21534
|
// terminal — which may target a different hub entirely — would mislabel.
|
|
21427
21535
|
SLAYZONE_HUB_NAME: "infra",
|
|
21536
|
+
// Days THIS hub keeps session content (T-23, hub session-retention.ts); 0 = off, the
|
|
21537
|
+
// default. Infra like the switches: a hub started from a task terminal must not
|
|
21538
|
+
// inherit its parent's period and start deleting.
|
|
21539
|
+
SLAYZONE_HUB_SESSION_RETENTION_DAYS: "infra",
|
|
21540
|
+
// The Convex deployment (host[:port]) the hub starts GitHub sign-in against — never
|
|
21541
|
+
// a client-named one (T-99). Hub process config, set by the desktop app for its hub.
|
|
21542
|
+
SLAYZONE_HUB_CONVEX_ADDRESS: "infra",
|
|
21428
21543
|
SLAYZONE_DESKTOP_BRIDGE_ADDRESS: "infra",
|
|
21429
21544
|
// sidecar→desktop capability bridge + REST proxy
|
|
21430
21545
|
SLAYZONE_SUPERVISED: "infra",
|
|
@@ -21461,7 +21576,8 @@ var ENV_MANIFEST = {
|
|
|
21461
21576
|
// --- identity: per-task/agent; overlay re-adds the correct value per spawn ---
|
|
21462
21577
|
SLAYZONE_TASK_ID: "identity",
|
|
21463
21578
|
SLAYZONE_PROJECT_ID: "identity",
|
|
21464
|
-
SLAYZONE_SESSION_ID
|
|
21579
|
+
// `SLAYZONE_SESSION_ID` (a warm agent's pre-task identity) is RETIRED and
|
|
21580
|
+
// deliberately unlisted: warm agents boot with SLAYZONE_TASK_ID now.
|
|
21465
21581
|
SLAYZONE_AGENT_ID: "identity",
|
|
21466
21582
|
SLAYZONE_AGENT_HOOK_URL: "identity",
|
|
21467
21583
|
// Pairs with _HOOK_URL (where to post / who is posting). The pre-v4 name
|
|
@@ -21608,6 +21724,7 @@ function createGitHandlers(ctx) {
|
|
|
21608
21724
|
throw err;
|
|
21609
21725
|
}
|
|
21610
21726
|
}
|
|
21727
|
+
if (params.deleteBranch !== true) return {};
|
|
21611
21728
|
if (removedBranch === null) return {};
|
|
21612
21729
|
const branch = removedBranch.replace(/^refs\/heads\//, "").trim();
|
|
21613
21730
|
if (!branch) return {};
|
|
@@ -21730,39 +21847,6 @@ init_dirs();
|
|
|
21730
21847
|
// ../../shared/platform/src/paths.ts
|
|
21731
21848
|
init_dirs();
|
|
21732
21849
|
|
|
21733
|
-
// ../../shared/platform/src/hub-switches.ts
|
|
21734
|
-
var HUB_SWITCH_ENV = {
|
|
21735
|
-
requireLogin: "SLAYZONE_HUB_REQUIRE_LOGIN",
|
|
21736
|
-
enablePassword: "SLAYZONE_HUB_ENABLE_PASSWORD",
|
|
21737
|
-
enableSso: "SLAYZONE_HUB_ENABLE_SSO",
|
|
21738
|
-
enableProcesses: "SLAYZONE_HUB_ENABLE_PROCESSES",
|
|
21739
|
-
enableIntegrations: "SLAYZONE_HUB_ENABLE_INTEGRATIONS"
|
|
21740
|
-
};
|
|
21741
|
-
var HUB_SSO_ENV = {
|
|
21742
|
-
tenantId: "SLAYZONE_HUB_SSO_TENANT_ID",
|
|
21743
|
-
clientId: "SLAYZONE_HUB_SSO_CLIENT_ID",
|
|
21744
|
-
/** Secret — env only, never read from `hub.config.json`, never logged. */
|
|
21745
|
-
clientSecret: "SLAYZONE_HUB_SSO_CLIENT_SECRET"
|
|
21746
|
-
};
|
|
21747
|
-
var HUB_ADDRESS_ENV = {
|
|
21748
|
-
/** Where the hub LISTENS. Renamed from `SLAYZONE_HUB_ADDRESS`, which now only
|
|
21749
|
-
* means "the hub to connect to" on a computer / `slay`. */
|
|
21750
|
-
listen: "SLAYZONE_HUB_LISTEN_ADDRESS",
|
|
21751
|
-
/** How OTHER machines reach the hub (`host[:port]`, no scheme). */
|
|
21752
|
-
public: "SLAYZONE_HUB_PUBLIC_ADDRESS",
|
|
21753
|
-
/** Signing key of hub-auth. */
|
|
21754
|
-
authSecret: "SLAYZONE_HUB_AUTH_SECRET"
|
|
21755
|
-
};
|
|
21756
|
-
var LEGACY_HUB_LISTEN_ENV = "SLAYZONE_HUB_ADDRESS";
|
|
21757
|
-
var HUB_ALLOWED_WEB_ORIGINS_ENV = "SLAYZONE_HUB_ALLOWED_WEB_ORIGINS";
|
|
21758
|
-
var HUB_PROCESS_ENV = [
|
|
21759
|
-
...Object.values(HUB_SWITCH_ENV),
|
|
21760
|
-
...Object.values(HUB_SSO_ENV),
|
|
21761
|
-
...Object.values(HUB_ADDRESS_ENV),
|
|
21762
|
-
LEGACY_HUB_LISTEN_ENV,
|
|
21763
|
-
HUB_ALLOWED_WEB_ORIGINS_ENV
|
|
21764
|
-
];
|
|
21765
|
-
|
|
21766
21850
|
// ../../shared/platform/src/index.ts
|
|
21767
21851
|
init_fs_utils();
|
|
21768
21852
|
|
|
@@ -21773,6 +21857,16 @@ init_dirs();
|
|
|
21773
21857
|
var import_child_process = require("child_process");
|
|
21774
21858
|
var import_util3 = require("util");
|
|
21775
21859
|
var execFileAsync = (0, import_util3.promisify)(import_child_process.execFile);
|
|
21860
|
+
var WINDOWS_SHIM = [
|
|
21861
|
+
"@echo off",
|
|
21862
|
+
`for /f "tokens=1 delims=." %%v in ('node -e "process.stdout.write(process.versions.node)"') do set NODE_MAJOR=%%v`,
|
|
21863
|
+
"if %NODE_MAJOR% LEQ 22 (",
|
|
21864
|
+
' node --experimental-sqlite --no-warnings "%~dp0slay.js" %*',
|
|
21865
|
+
") else (",
|
|
21866
|
+
' node --no-warnings "%~dp0slay.js" %*',
|
|
21867
|
+
")",
|
|
21868
|
+
""
|
|
21869
|
+
].join("\r\n");
|
|
21776
21870
|
|
|
21777
21871
|
// ../../shared/platform/src/shell.ts
|
|
21778
21872
|
var import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
@@ -21814,15 +21908,6 @@ function buildShellInvocation(command) {
|
|
|
21814
21908
|
var SLZ_FILE_HOST = "app";
|
|
21815
21909
|
var SLZ_FILE_PREFIX = `slz-file://${SLZ_FILE_HOST}`;
|
|
21816
21910
|
|
|
21817
|
-
// ../../shared/platform/src/html-theme-css.ts
|
|
21818
|
-
var FORCED_HTML_THEME_CSS = {
|
|
21819
|
-
dark: [
|
|
21820
|
-
"html{filter:invert(90%) hue-rotate(180deg)!important}",
|
|
21821
|
-
"img,video,canvas,svg,iframe{filter:invert(90%) hue-rotate(180deg)!important}"
|
|
21822
|
-
].join(""),
|
|
21823
|
-
light: ":root{color-scheme:light!important}"
|
|
21824
|
-
};
|
|
21825
|
-
|
|
21826
21911
|
// ../../shared/platform/src/ipc-dedup.ts
|
|
21827
21912
|
var UNCHANGED = Object.freeze({ __ipc_unchanged__: true });
|
|
21828
21913
|
|
|
@@ -22484,29 +22569,12 @@ function startComputer(config2, deps = {}) {
|
|
|
22484
22569
|
let handle;
|
|
22485
22570
|
const connectHub = (hubUrl, isPrimary) => {
|
|
22486
22571
|
const credentialStore = (isPrimary ? deps.credentialStore : void 0) ?? createFileCredentialStore(hubHostFromUrl(hubUrl));
|
|
22487
|
-
const isSecureUrl = (() => {
|
|
22488
|
-
try {
|
|
22489
|
-
return new URL(hubUrl).protocol === "wss:";
|
|
22490
|
-
} catch {
|
|
22491
|
-
return false;
|
|
22492
|
-
}
|
|
22493
|
-
})();
|
|
22494
|
-
const pinnedCertSha256 = config2.pinnedCertSha256 && isSecureUrl ? config2.pinnedCertSha256 : void 0;
|
|
22495
|
-
if (config2.pinnedCertSha256 && !isSecureUrl) {
|
|
22496
|
-
log(
|
|
22497
|
-
"ignoring token-decoded cert fingerprint on a non-wss hub url (pinning requires wss://)",
|
|
22498
|
-
{
|
|
22499
|
-
hubUrl
|
|
22500
|
-
}
|
|
22501
|
-
);
|
|
22502
|
-
}
|
|
22503
22572
|
let dispatch;
|
|
22504
22573
|
const dialer = new HubDialer({
|
|
22505
22574
|
url: hubUrl,
|
|
22506
22575
|
identity,
|
|
22507
22576
|
credentialStore,
|
|
22508
22577
|
...config2.joinToken && isPrimary ? { joinToken: config2.joinToken } : {},
|
|
22509
|
-
...pinnedCertSha256 ? { pinnedCertSha256 } : {},
|
|
22510
22578
|
onHubRequest: (method, params) => dispatch.handle(method, params),
|
|
22511
22579
|
log
|
|
22512
22580
|
});
|
|
@@ -22671,6 +22739,7 @@ async function main() {
|
|
|
22671
22739
|
process.stdout.write(`[computer] ${message}${suffix}
|
|
22672
22740
|
`);
|
|
22673
22741
|
};
|
|
22742
|
+
for (const notice of ignoredCertPinNotices()) log(notice);
|
|
22674
22743
|
if (process.env.SLAYZONE_SUPERVISED !== "1") {
|
|
22675
22744
|
const { installAgentHooks: installAgentHooks2 } = await Promise.resolve().then(() => (init_agent_hooks2(), agent_hooks_exports));
|
|
22676
22745
|
await installAgentHooks2(log);
|