@swf2es/desktop 0.1.14 → 0.1.16
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/README.md +48 -12
- package/dist/launch/launch.js +4 -1
- package/dist/launch/launch.js.map +1 -1
- package/dist/main/main.js +102 -14
- package/dist/main/main.js.map +1 -1
- package/dist/main/netlog.d.ts +21 -0
- package/dist/main/netlog.d.ts.map +1 -0
- package/dist/main/netlog.js +90 -0
- package/dist/main/netlog.js.map +1 -0
- package/dist/main/sockets.d.ts +4 -2
- package/dist/main/sockets.d.ts.map +1 -1
- package/dist/main/sockets.js +15 -2
- package/dist/main/sockets.js.map +1 -1
- package/dist/main/websocket-connections.d.ts +62 -0
- package/dist/main/websocket-connections.d.ts.map +1 -0
- package/dist/main/websocket-connections.js +198 -0
- package/dist/main/websocket-connections.js.map +1 -0
- package/dist/main/websockets.d.ts +11 -0
- package/dist/main/websockets.d.ts.map +1 -0
- package/dist/main/websockets.js +93 -0
- package/dist/main/websockets.js.map +1 -0
- package/dist/preload/preload.cjs +20 -0
- package/dist/preload/preload.cjs.map +1 -1
- package/dist/renderer/air.d.ts.map +1 -1
- package/dist/renderer/air.js +1 -0
- package/dist/renderer/air.js.map +1 -1
- package/dist/renderer/full-screen.d.ts +4 -0
- package/dist/renderer/full-screen.d.ts.map +1 -0
- package/dist/renderer/full-screen.js +32 -0
- package/dist/renderer/full-screen.js.map +1 -0
- package/dist/renderer/index.d.ts.map +1 -1
- package/dist/renderer/index.js +4 -0
- package/dist/renderer/index.js.map +1 -1
- package/dist/renderer/websockets.d.ts +4 -0
- package/dist/renderer/websockets.d.ts.map +1 -0
- package/dist/renderer/websockets.js +36 -0
- package/dist/renderer/websockets.js.map +1 -0
- package/dist/shared/api.d.ts +53 -0
- package/dist/shared/api.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/launch/launch.ts +5 -2
- package/src/main/main.ts +128 -15
- package/src/main/netlog.ts +108 -0
- package/src/main/sockets.ts +17 -1
- package/src/main/websocket-connections.ts +264 -0
- package/src/main/websockets.ts +115 -0
- package/src/preload/preload.cts +23 -0
- package/src/renderer/air.ts +1 -0
- package/src/renderer/full-screen.ts +44 -0
- package/src/renderer/index.ts +4 -0
- package/src/renderer/websockets.ts +43 -0
- package/src/shared/api.ts +40 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// --log-network's lines: what a SWF asked of the network, as the terminal
|
|
2
|
+
// shows it. The page has no network of its own, so its DevTools' Network
|
|
3
|
+
// tab shows none of this; the main process, which sends the requests, says
|
|
4
|
+
// them here instead. Apart from Electron, so that node tests it.
|
|
5
|
+
/** A size as a person reads it: bytes, then kB and MB to one decimal. */
|
|
6
|
+
function size(bytes) {
|
|
7
|
+
if (bytes < 1024) {
|
|
8
|
+
return `${bytes} B`;
|
|
9
|
+
}
|
|
10
|
+
return bytes < 1024 * 1024
|
|
11
|
+
? `${(bytes / 1024).toFixed(1)} kB`
|
|
12
|
+
: `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
13
|
+
}
|
|
14
|
+
/** A URL short enough for a line, and with nothing a terminal would act on. */
|
|
15
|
+
function shown(url) {
|
|
16
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what is taken out
|
|
17
|
+
return url.slice(0, 2048).replace(/[\u0000-\u001f\u007f]/g, "?");
|
|
18
|
+
}
|
|
19
|
+
/** A request answered: its method, URL, status, body's size and how long it took. */
|
|
20
|
+
export function requestLine(method, url, status, bytes, ms) {
|
|
21
|
+
const body = bytes === null ? "no body" : size(bytes);
|
|
22
|
+
return `swf2es: net ${method} ${shown(url)} ${status} ${body} ${Math.round(ms)} ms`;
|
|
23
|
+
}
|
|
24
|
+
/** A request that got no answer: refused, failed or aborted, and why. */
|
|
25
|
+
export function failureLine(method, url, why, ms) {
|
|
26
|
+
return `swf2es: net ${method} ${shown(url)} ${why} ${Math.round(ms)} ms`;
|
|
27
|
+
}
|
|
28
|
+
/** A socket's connection asked for, opened, refused or closed. */
|
|
29
|
+
export function socketLine(id, what) {
|
|
30
|
+
return `swf2es: socket #${id} ${shown(what)}`;
|
|
31
|
+
}
|
|
32
|
+
/** How much of a message --log-sockets shows. */
|
|
33
|
+
const PREVIEW = 512;
|
|
34
|
+
/** The start of `bytes`: as text where it is text, bytes that are no printable ASCII as dots, else in hex. */
|
|
35
|
+
function preview(bytes) {
|
|
36
|
+
const shownBytes = bytes.subarray(0, PREVIEW);
|
|
37
|
+
let printable = 0;
|
|
38
|
+
for (let i = 0; i < shownBytes.length; i++) {
|
|
39
|
+
const b = shownBytes[i];
|
|
40
|
+
if ((b >= 32 && b < 127) || b === 9 || b === 10 || b === 13 || b === 0) {
|
|
41
|
+
printable++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
let text = "";
|
|
45
|
+
// Mostly text, as a line protocol's messages are, a NUL ending each: shown as text.
|
|
46
|
+
if (printable * 10 >= shownBytes.length * 9) {
|
|
47
|
+
for (let i = 0; i < shownBytes.length; i++) {
|
|
48
|
+
const b = shownBytes[i];
|
|
49
|
+
text += b >= 32 && b < 127 ? String.fromCharCode(b) : ".";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
for (let i = 0; i < shownBytes.length; i++) {
|
|
54
|
+
text += (i > 0 ? " " : "") + shownBytes[i].toString(16).padStart(2, "0");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return text + (bytes.length > PREVIEW ? "…" : "");
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* What a socket sent (">") or received ("<"): its size and its start, as
|
|
61
|
+
* text where it is text, bytes that are no printable ASCII as dots, else
|
|
62
|
+
* in hex. A message past PREVIEW bytes ends in an ellipsis.
|
|
63
|
+
*/
|
|
64
|
+
export function socketDataLine(id, sent, bytes) {
|
|
65
|
+
return `swf2es: socket #${id} ${sent ? ">" : "<"} ${bytes.length} B ${preview(bytes)}`;
|
|
66
|
+
}
|
|
67
|
+
/** A WebSocket's connection asked for, opened, refused, failed or closed. */
|
|
68
|
+
export function webSocketLine(id, what) {
|
|
69
|
+
return `swf2es: websocket #${id} ${shown(what)}`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* What a WebSocket sent (">") or received ("<"): a text message's size
|
|
73
|
+
* in UTF-8 and its first PREVIEW characters, control characters as dots;
|
|
74
|
+
* a binary one's as a socket's.
|
|
75
|
+
*/
|
|
76
|
+
export function webSocketDataLine(id, sent, data) {
|
|
77
|
+
const head = `swf2es: websocket #${id} ${sent ? ">" : "<"}`;
|
|
78
|
+
if (typeof data !== "string") {
|
|
79
|
+
return `${head} binary ${data.length} B ${preview(data)}`;
|
|
80
|
+
}
|
|
81
|
+
// By code point, so that no pair is cut in two.
|
|
82
|
+
const characters = Array.from(data.slice(0, PREVIEW * 2)).slice(0, PREVIEW);
|
|
83
|
+
const text = characters
|
|
84
|
+
.join("")
|
|
85
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what is taken out
|
|
86
|
+
.replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/g, ".");
|
|
87
|
+
const more = text.length < data.length ? "…" : "";
|
|
88
|
+
return `${head} text ${Buffer.byteLength(data)} B ${text}${more}`;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=netlog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"netlog.js","sourceRoot":"","sources":["../../src/main/netlog.ts"],"names":[],"mappings":"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"}
|
package/dist/main/sockets.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ import { type IpcMainEvent } from "electron";
|
|
|
2
2
|
/**
|
|
3
3
|
* Carry socket messages from pages that `trusted` accepts, each connection
|
|
4
4
|
* made only as `permit` allows it, to the address it gives where it gives
|
|
5
|
-
* one; null refuses it.
|
|
5
|
+
* one; null refuses it. `log`, where given, is told each connection asked
|
|
6
|
+
* for, opened, refused, failed and closed (--log-network), and with
|
|
7
|
+
* `data` what each sends and receives too (--log-sockets).
|
|
6
8
|
*/
|
|
7
9
|
export declare function bridgeSockets(trusted: (event: IpcMainEvent) => boolean, permit: (host: string, port: number) => Promise<{
|
|
8
10
|
address?: string;
|
|
9
|
-
} | null
|
|
11
|
+
} | null>, log?: ((line: string) => void) | null, data?: boolean): void;
|
|
10
12
|
//# sourceMappingURL=sockets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sockets.d.ts","sourceRoot":"","sources":["../../src/main/sockets.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAA6B,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"sockets.d.ts","sourceRoot":"","sources":["../../src/main/sockets.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAA6B,MAAM,UAAU,CAAC;AAIxE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,EACzC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,EAC5E,GAAG,GAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAW,EAC3C,IAAI,UAAQ,GACX,IAAI,CA6EN"}
|
package/dist/main/sockets.js
CHANGED
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
// connections (connections.ts) close as it navigates, reloads or goes.
|
|
4
4
|
import { ipcMain } from "electron";
|
|
5
5
|
import { Connections, validEndpoint } from "./connections.js";
|
|
6
|
+
import { socketDataLine, socketLine } from "./netlog.js";
|
|
6
7
|
/**
|
|
7
8
|
* Carry socket messages from pages that `trusted` accepts, each connection
|
|
8
9
|
* made only as `permit` allows it, to the address it gives where it gives
|
|
9
|
-
* one; null refuses it.
|
|
10
|
+
* one; null refuses it. `log`, where given, is told each connection asked
|
|
11
|
+
* for, opened, refused, failed and closed (--log-network), and with
|
|
12
|
+
* `data` what each sends and receives too (--log-sockets).
|
|
10
13
|
*/
|
|
11
|
-
export function bridgeSockets(trusted, permit) {
|
|
14
|
+
export function bridgeSockets(trusted, permit, log = null, data = false) {
|
|
12
15
|
const pages = new Map();
|
|
13
16
|
const connectionsOf = (contents) => {
|
|
14
17
|
const known = pages.get(contents);
|
|
@@ -16,6 +19,12 @@ export function bridgeSockets(trusted, permit) {
|
|
|
16
19
|
return known;
|
|
17
20
|
}
|
|
18
21
|
const connections = new Connections((id, event) => {
|
|
22
|
+
if (log && event.type !== "data") {
|
|
23
|
+
log(socketLine(id, event.type === "error" ? `error: ${event.message}` : event.type));
|
|
24
|
+
}
|
|
25
|
+
else if (log && data && event.type === "data") {
|
|
26
|
+
log(socketDataLine(id, false, event.bytes));
|
|
27
|
+
}
|
|
19
28
|
if (!contents.isDestroyed()) {
|
|
20
29
|
contents.send("socket:event", id, event);
|
|
21
30
|
}
|
|
@@ -49,6 +58,7 @@ export function bridgeSockets(trusted, permit) {
|
|
|
49
58
|
if (connections.generation !== generation) {
|
|
50
59
|
return;
|
|
51
60
|
}
|
|
61
|
+
log?.(socketLine(id, `${allowed ? "connecting to" : "refused"} ${host}:${port}`));
|
|
52
62
|
if (allowed) {
|
|
53
63
|
connections.connect(id, host, port, allowed.address);
|
|
54
64
|
}
|
|
@@ -59,6 +69,9 @@ export function bridgeSockets(trusted, permit) {
|
|
|
59
69
|
});
|
|
60
70
|
ipcMain.on("socket:send", (event, id, bytes) => {
|
|
61
71
|
if (trusted(event) && typeof id === "number" && bytes instanceof Uint8Array) {
|
|
72
|
+
if (log && data) {
|
|
73
|
+
log(socketDataLine(id, true, bytes));
|
|
74
|
+
}
|
|
62
75
|
pages.get(event.sender)?.send(id, bytes);
|
|
63
76
|
}
|
|
64
77
|
});
|
package/dist/main/sockets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sockets.js","sourceRoot":"","sources":["../../src/main/sockets.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,wEAAwE;AACxE,uEAAuE;AACvE,OAAO,EAAqB,OAAO,EAAoB,MAAM,UAAU,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"sockets.js","sourceRoot":"","sources":["../../src/main/sockets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { WebSocketEvent } from "../shared/api.js";
|
|
2
|
+
/**
|
|
3
|
+
* The bytes a connection may hold unsent, as a socket's (connections.ts)
|
|
4
|
+
* but for whole messages, which are larger than a socket's writes: a peer
|
|
5
|
+
* that stops reading would otherwise have the main process buffer all an
|
|
6
|
+
* application sends. Past this the connection fails.
|
|
7
|
+
*/
|
|
8
|
+
export declare const MAX_BUFFERED: number;
|
|
9
|
+
/** Opens a client; throws as the WebSocket constructor does. */
|
|
10
|
+
export type Opener = (url: string, protocols: string[]) => unknown;
|
|
11
|
+
/** Whether this Node has the WHATWG WebSocket (22 and later, Electron's among them). */
|
|
12
|
+
export declare function hasWebSocket(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* What sends a client's requests with no certificate verified, for
|
|
15
|
+
* --ignore-certificate-errors; null where this Node gives no way to make
|
|
16
|
+
* one. The WHATWG WebSocket has no option for it: Node's is undici's,
|
|
17
|
+
* which takes a dispatcher, and Node exports no class of one, so it is
|
|
18
|
+
* made from the class of the dispatcher undici keeps for everything else.
|
|
19
|
+
*/
|
|
20
|
+
export declare function unverifiedDispatcher(): unknown;
|
|
21
|
+
/**
|
|
22
|
+
* An opener that leaves a wss: server's certificate unverified where
|
|
23
|
+
* `unverified` says so of its host, through `dispatcher`
|
|
24
|
+
* (unverifiedDispatcher's); any other connection is the global's as it is.
|
|
25
|
+
*/
|
|
26
|
+
export declare function webSocketOpener(unverified: (host: string) => boolean, dispatcher: unknown): Opener;
|
|
27
|
+
/** Whether the page asked for a ws: or wss: URL with a host, of a length a server takes. */
|
|
28
|
+
export declare function validWebSocketUrl(url: unknown): url is string;
|
|
29
|
+
export declare function validProtocols(protocols: unknown): protocols is string[];
|
|
30
|
+
export declare class WebSocketConnections {
|
|
31
|
+
private readonly clients;
|
|
32
|
+
private readonly tell;
|
|
33
|
+
private readonly open;
|
|
34
|
+
/** `tell` carries each connection's events to its page; `open` makes a client, the global's by default. */
|
|
35
|
+
constructor(tell: (id: number, event: WebSocketEvent) => void, open?: Opener);
|
|
36
|
+
get size(): number;
|
|
37
|
+
/** Counts closeAll's: a connection decided on before one belongs to a page that is gone. */
|
|
38
|
+
generation: number;
|
|
39
|
+
/**
|
|
40
|
+
* Connect `id` to `url`, offering `protocols`, each checked, as the page
|
|
41
|
+
* asks; a refusal, a URL or protocols the client throws for among them,
|
|
42
|
+
* is an error, then a close.
|
|
43
|
+
*/
|
|
44
|
+
connect(id: number, url: unknown, protocols: unknown): void;
|
|
45
|
+
/**
|
|
46
|
+
* Send a text message for a string, a binary one for bytes, once the
|
|
47
|
+
* connection is open, unless the peer has left more than MAX_BUFFERED
|
|
48
|
+
* unread: then the connection fails.
|
|
49
|
+
*/
|
|
50
|
+
send(id: number, data: string | Uint8Array): void;
|
|
51
|
+
/** Refuse `id`, as a server that took no connection: an error, then a close with no frame. */
|
|
52
|
+
refuse(id: number): void;
|
|
53
|
+
/** A close frame with `code` where the client sends it, 1000 or 3000 to 4999, else with none. */
|
|
54
|
+
close(id: number, code?: unknown): void;
|
|
55
|
+
/**
|
|
56
|
+
* Close every connection without a word: the page that held them is
|
|
57
|
+
* gone, and the next numbers its own from 1.
|
|
58
|
+
*/
|
|
59
|
+
closeAll(): void;
|
|
60
|
+
private silence;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=websocket-connections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-connections.d.ts","sourceRoot":"","sources":["../../src/main/websocket-connections.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAUvD;;;;;GAKG;AACH,eAAO,MAAM,YAAY,QAAmB,CAAC;AAwB7C,gEAAgE;AAChE,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;AAKnE,wFAAwF;AACxF,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAoB9C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,EACrC,UAAU,EAAE,OAAO,GAClB,MAAM,CASR;AAED,4FAA4F;AAC5F,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAW7D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,IAAI,MAAM,EAAE,CAMxE;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8C;IACnE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAE9B,2GAA2G;IAC3G,YACE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,KAAK,IAAI,EACjD,IAAI,GAAE,MAAsF,EAI7F;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,4FAA4F;IAC5F,UAAU,SAAK;IAEf;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAqC1D;IAED;;;;OAIG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAkBhD;IAED,8FAA8F;IAC9F,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAGvB;IAED,iGAAiG;IACjG,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAWtC;IAED;;;OAGG;IACH,QAAQ,IAAI,IAAI,CAOf;IAED,OAAO,CAAC,OAAO;CAWhB"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/** As many as a page may hold open at once; past it a connection is refused. */
|
|
2
|
+
const MAX_OPEN = 64;
|
|
3
|
+
/** The longest URL, and the most and longest subprotocols, a page may ask for. */
|
|
4
|
+
const MAX_URL = 8192;
|
|
5
|
+
const MAX_PROTOCOLS = 32;
|
|
6
|
+
const MAX_PROTOCOL = 256;
|
|
7
|
+
/**
|
|
8
|
+
* The bytes a connection may hold unsent, as a socket's (connections.ts)
|
|
9
|
+
* but for whole messages, which are larger than a socket's writes: a peer
|
|
10
|
+
* that stops reading would otherwise have the main process buffer all an
|
|
11
|
+
* application sends. Past this the connection fails.
|
|
12
|
+
*/
|
|
13
|
+
export const MAX_BUFFERED = 16 * 1024 * 1024;
|
|
14
|
+
const OPEN = 1;
|
|
15
|
+
const globalClient = () => globalThis.WebSocket;
|
|
16
|
+
/** Whether this Node has the WHATWG WebSocket (22 and later, Electron's among them). */
|
|
17
|
+
export function hasWebSocket() {
|
|
18
|
+
return typeof globalClient() === "function";
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* What sends a client's requests with no certificate verified, for
|
|
22
|
+
* --ignore-certificate-errors; null where this Node gives no way to make
|
|
23
|
+
* one. The WHATWG WebSocket has no option for it: Node's is undici's,
|
|
24
|
+
* which takes a dispatcher, and Node exports no class of one, so it is
|
|
25
|
+
* made from the class of the dispatcher undici keeps for everything else.
|
|
26
|
+
*/
|
|
27
|
+
export function unverifiedDispatcher() {
|
|
28
|
+
// Naming the global loads undici, which then sets its dispatcher.
|
|
29
|
+
if (!hasWebSocket()) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const shared = globalThis[Symbol.for("undici.globalDispatcher.1")];
|
|
33
|
+
const Agent = shared?.constructor;
|
|
34
|
+
if (typeof Agent !== "function" || Agent.name !== "Agent") {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const agent = new Agent({
|
|
39
|
+
connect: { rejectUnauthorized: false },
|
|
40
|
+
});
|
|
41
|
+
return typeof agent.dispatch === "function" ? agent : null;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* An opener that leaves a wss: server's certificate unverified where
|
|
49
|
+
* `unverified` says so of its host, through `dispatcher`
|
|
50
|
+
* (unverifiedDispatcher's); any other connection is the global's as it is.
|
|
51
|
+
*/
|
|
52
|
+
export function webSocketOpener(unverified, dispatcher) {
|
|
53
|
+
return (url, protocols) => {
|
|
54
|
+
const Client = globalClient();
|
|
55
|
+
const parsed = new URL(url);
|
|
56
|
+
const host = parsed.hostname.replace(/^\[(.*)\]$/, "$1").toLowerCase();
|
|
57
|
+
return dispatcher && parsed.protocol === "wss:" && unverified(host)
|
|
58
|
+
? new Client(url, { protocols, dispatcher })
|
|
59
|
+
: new Client(url, protocols);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** Whether the page asked for a ws: or wss: URL with a host, of a length a server takes. */
|
|
63
|
+
export function validWebSocketUrl(url) {
|
|
64
|
+
if (typeof url !== "string" || url.length > MAX_URL) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const parsed = new URL(url);
|
|
69
|
+
return (parsed.protocol === "ws:" || parsed.protocol === "wss:") && parsed.hostname !== "";
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function validProtocols(protocols) {
|
|
76
|
+
return (Array.isArray(protocols) &&
|
|
77
|
+
protocols.length <= MAX_PROTOCOLS &&
|
|
78
|
+
protocols.every((p) => typeof p === "string" && p.length <= MAX_PROTOCOL));
|
|
79
|
+
}
|
|
80
|
+
/** The close codes the WHATWG WebSocket sends; any other throws. */
|
|
81
|
+
const sendable = (code) => code === 1000 || (typeof code === "number" && code >= 3000 && code <= 4999);
|
|
82
|
+
export class WebSocketConnections {
|
|
83
|
+
clients = new Map();
|
|
84
|
+
tell;
|
|
85
|
+
open;
|
|
86
|
+
/** `tell` carries each connection's events to its page; `open` makes a client, the global's by default. */
|
|
87
|
+
constructor(tell, open = (url, protocols) => new (globalClient())(url, protocols)) {
|
|
88
|
+
this.tell = tell;
|
|
89
|
+
this.open = open;
|
|
90
|
+
}
|
|
91
|
+
get size() {
|
|
92
|
+
return this.clients.size;
|
|
93
|
+
}
|
|
94
|
+
/** Counts closeAll's: a connection decided on before one belongs to a page that is gone. */
|
|
95
|
+
generation = 0;
|
|
96
|
+
/**
|
|
97
|
+
* Connect `id` to `url`, offering `protocols`, each checked, as the page
|
|
98
|
+
* asks; a refusal, a URL or protocols the client throws for among them,
|
|
99
|
+
* is an error, then a close.
|
|
100
|
+
*/
|
|
101
|
+
connect(id, url, protocols) {
|
|
102
|
+
if (!validWebSocketUrl(url) ||
|
|
103
|
+
!validProtocols(protocols) ||
|
|
104
|
+
this.clients.has(id) ||
|
|
105
|
+
this.clients.size >= MAX_OPEN ||
|
|
106
|
+
!hasWebSocket()) {
|
|
107
|
+
this.refuse(id);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
let client;
|
|
111
|
+
try {
|
|
112
|
+
client = this.open(url, protocols);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
this.refuse(id);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
client.binaryType = "arraybuffer";
|
|
119
|
+
this.clients.set(id, client);
|
|
120
|
+
client.onopen = () => this.tell(id, { type: "open", protocol: client.protocol });
|
|
121
|
+
client.onmessage = ({ data }) => this.tell(id, {
|
|
122
|
+
type: "message",
|
|
123
|
+
data: typeof data === "string" ? data : new Uint8Array(data),
|
|
124
|
+
});
|
|
125
|
+
client.onerror = () => this.tell(id, { type: "error" });
|
|
126
|
+
client.onclose = ({ code }) => {
|
|
127
|
+
// Only the client under this id: a page that reused it has another by now.
|
|
128
|
+
if (this.clients.get(id) === client) {
|
|
129
|
+
this.clients.delete(id);
|
|
130
|
+
}
|
|
131
|
+
this.tell(id, { type: "close", code });
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Send a text message for a string, a binary one for bytes, once the
|
|
136
|
+
* connection is open, unless the peer has left more than MAX_BUFFERED
|
|
137
|
+
* unread: then the connection fails.
|
|
138
|
+
*/
|
|
139
|
+
send(id, data) {
|
|
140
|
+
const client = this.clients.get(id);
|
|
141
|
+
if (!client || client.readyState !== OPEN) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const size = typeof data === "string" ? Buffer.byteLength(data) : data.length;
|
|
145
|
+
if (client.bufferedAmount + size > MAX_BUFFERED) {
|
|
146
|
+
// The client has no way to drop a connection: its close waits behind
|
|
147
|
+
// what is buffered, so the page is told now and the client left to it.
|
|
148
|
+
this.silence(client);
|
|
149
|
+
this.clients.delete(id);
|
|
150
|
+
this.tell(id, { type: "error" });
|
|
151
|
+
this.tell(id, { type: "close", code: 1006 });
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
client.send(data);
|
|
155
|
+
}
|
|
156
|
+
/** Refuse `id`, as a server that took no connection: an error, then a close with no frame. */
|
|
157
|
+
refuse(id) {
|
|
158
|
+
this.tell(id, { type: "error" });
|
|
159
|
+
this.tell(id, { type: "close", code: 1006 });
|
|
160
|
+
}
|
|
161
|
+
/** A close frame with `code` where the client sends it, 1000 or 3000 to 4999, else with none. */
|
|
162
|
+
close(id, code) {
|
|
163
|
+
const client = this.clients.get(id);
|
|
164
|
+
if (!client) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
client.close(sendable(code) ? code : undefined);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Already closing.
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Close every connection without a word: the page that held them is
|
|
176
|
+
* gone, and the next numbers its own from 1.
|
|
177
|
+
*/
|
|
178
|
+
closeAll() {
|
|
179
|
+
for (const client of this.clients.values()) {
|
|
180
|
+
this.silence(client);
|
|
181
|
+
}
|
|
182
|
+
this.clients.clear();
|
|
183
|
+
this.generation++;
|
|
184
|
+
}
|
|
185
|
+
silence(client) {
|
|
186
|
+
client.onopen = null;
|
|
187
|
+
client.onmessage = null;
|
|
188
|
+
client.onerror = null;
|
|
189
|
+
client.onclose = null;
|
|
190
|
+
try {
|
|
191
|
+
client.close();
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Already closing.
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=websocket-connections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-connections.js","sourceRoot":"","sources":["../../src/main/websocket-connections.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type IpcMainEvent } from "electron";
|
|
2
|
+
import { type Opener } from "./websocket-connections.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Carry WebSocket messages from pages that `trusted` accepts, each
|
|
5
|
+
* connection made only where `permit` allows its URL, with `open` if
|
|
6
|
+
* given. `log`, where given, is told each connection asked for, opened,
|
|
7
|
+
* refused, failed and closed (--log-network), and with `data` what each
|
|
8
|
+
* sends and receives too (--log-sockets).
|
|
9
|
+
*/
|
|
10
|
+
export declare function bridgeWebSockets(trusted: (event: IpcMainEvent) => boolean, permit: (url: string) => boolean, open: Opener | undefined, log?: ((line: string) => void) | null, data?: boolean): void;
|
|
11
|
+
//# sourceMappingURL=websockets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websockets.d.ts","sourceRoot":"","sources":["../../src/main/websockets.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAA6B,MAAM,UAAU,CAAC;AAExE,OAAO,EACL,KAAK,MAAM,EAIZ,MAAM,4BAA4B,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,EACzC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAChC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,GAAG,GAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAW,EAC3C,IAAI,UAAQ,GACX,IAAI,CAwFN"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// air.net.WebSocket's connections, made here for the page, which has no
|
|
2
|
+
// network of its own, and carried over IPC as flash.net.Socket's are
|
|
3
|
+
// (sockets.ts). Each page's connections (websocket-connections.ts) close
|
|
4
|
+
// as it navigates, reloads or goes.
|
|
5
|
+
import { ipcMain } from "electron";
|
|
6
|
+
import { webSocketDataLine, webSocketLine } from "./netlog.js";
|
|
7
|
+
import { validProtocols, validWebSocketUrl, WebSocketConnections, } from "./websocket-connections.js";
|
|
8
|
+
/**
|
|
9
|
+
* Carry WebSocket messages from pages that `trusted` accepts, each
|
|
10
|
+
* connection made only where `permit` allows its URL, with `open` if
|
|
11
|
+
* given. `log`, where given, is told each connection asked for, opened,
|
|
12
|
+
* refused, failed and closed (--log-network), and with `data` what each
|
|
13
|
+
* sends and receives too (--log-sockets).
|
|
14
|
+
*/
|
|
15
|
+
export function bridgeWebSockets(trusted, permit, open, log = null, data = false) {
|
|
16
|
+
const pages = new Map();
|
|
17
|
+
const connectionsOf = (contents) => {
|
|
18
|
+
const known = pages.get(contents);
|
|
19
|
+
if (known) {
|
|
20
|
+
return known;
|
|
21
|
+
}
|
|
22
|
+
const connections = new WebSocketConnections((id, event) => {
|
|
23
|
+
if (log) {
|
|
24
|
+
switch (event.type) {
|
|
25
|
+
case "open":
|
|
26
|
+
log(webSocketLine(id, event.protocol === "" ? "open" : `open ${event.protocol}`));
|
|
27
|
+
break;
|
|
28
|
+
case "message":
|
|
29
|
+
if (data) {
|
|
30
|
+
log(webSocketDataLine(id, false, event.data));
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
case "close":
|
|
34
|
+
log(webSocketLine(id, `close ${event.code}`));
|
|
35
|
+
break;
|
|
36
|
+
case "error":
|
|
37
|
+
log(webSocketLine(id, "error"));
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (!contents.isDestroyed()) {
|
|
42
|
+
contents.send("websocket:event", id, event);
|
|
43
|
+
}
|
|
44
|
+
}, open);
|
|
45
|
+
pages.set(contents, connections);
|
|
46
|
+
contents.on("did-start-navigation", (details) => {
|
|
47
|
+
if (details.isMainFrame && !details.isSameDocument) {
|
|
48
|
+
connections.closeAll();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
contents.once("destroyed", () => {
|
|
52
|
+
connections.closeAll();
|
|
53
|
+
pages.delete(contents);
|
|
54
|
+
});
|
|
55
|
+
return connections;
|
|
56
|
+
};
|
|
57
|
+
ipcMain.on("websocket:connect", (event, id, url, protocols) => {
|
|
58
|
+
if (!trusted(event) || typeof id !== "number") {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const connections = connectionsOf(event.sender);
|
|
62
|
+
if (!validWebSocketUrl(url) || !validProtocols(protocols)) {
|
|
63
|
+
connections.refuse(id);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// As the client will read it: what is said of it has nothing a terminal would act on.
|
|
67
|
+
const href = new URL(url).href;
|
|
68
|
+
const allowed = permit(href);
|
|
69
|
+
log?.(webSocketLine(id, `${allowed ? "connecting to" : "refused"} ${href}`));
|
|
70
|
+
if (allowed) {
|
|
71
|
+
connections.connect(id, href, protocols);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
connections.refuse(id);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
ipcMain.on("websocket:send", (event, id, message) => {
|
|
78
|
+
if (trusted(event) &&
|
|
79
|
+
typeof id === "number" &&
|
|
80
|
+
(typeof message === "string" || message instanceof Uint8Array)) {
|
|
81
|
+
if (log && data) {
|
|
82
|
+
log(webSocketDataLine(id, true, message));
|
|
83
|
+
}
|
|
84
|
+
pages.get(event.sender)?.send(id, message);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
ipcMain.on("websocket:close", (event, id, code) => {
|
|
88
|
+
if (trusted(event) && typeof id === "number") {
|
|
89
|
+
pages.get(event.sender)?.close(id, code);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=websockets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websockets.js","sourceRoot":"","sources":["../../src/main/websockets.ts"],"names":[],"mappings":"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"}
|
package/dist/preload/preload.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const { contextBridge, ipcRenderer, webUtils } = require("electron");
|
|
4
4
|
let nextSocket = 1;
|
|
5
|
+
let nextWebSocket = 1;
|
|
5
6
|
let nextRequest = 1;
|
|
6
7
|
/** The requests waiting for their response, by number. */
|
|
7
8
|
const responses = new Map();
|
|
@@ -14,6 +15,12 @@ const api = {
|
|
|
14
15
|
write: (id, bytes) => ipcRenderer.invoke("files:write", id, bytes),
|
|
15
16
|
release: (id) => ipcRenderer.send("files:release", id),
|
|
16
17
|
},
|
|
18
|
+
fullScreen: {
|
|
19
|
+
set: (fullScreen) => ipcRenderer.send("desktop:full-screen", fullScreen === true),
|
|
20
|
+
onChange: (listener) => {
|
|
21
|
+
ipcRenderer.on("desktop:full-screen", (_event, fullScreen) => listener(fullScreen));
|
|
22
|
+
},
|
|
23
|
+
},
|
|
17
24
|
start: () => ipcRenderer.invoke("desktop:start"),
|
|
18
25
|
onOpen: (listener) => {
|
|
19
26
|
ipcRenderer.on("desktop:open", (_event, movie) => listener(movie));
|
|
@@ -38,6 +45,18 @@ const api = {
|
|
|
38
45
|
ipcRenderer.on("socket:event", (_event, id, event) => listener(id, event));
|
|
39
46
|
},
|
|
40
47
|
},
|
|
48
|
+
webSockets: {
|
|
49
|
+
connect: (url, protocols) => {
|
|
50
|
+
const id = nextWebSocket++;
|
|
51
|
+
ipcRenderer.send("websocket:connect", id, String(url), Array.from(protocols, String));
|
|
52
|
+
return id;
|
|
53
|
+
},
|
|
54
|
+
send: (id, data) => ipcRenderer.send("websocket:send", id, data),
|
|
55
|
+
close: (id, code) => ipcRenderer.send("websocket:close", id, code),
|
|
56
|
+
onEvent: (listener) => {
|
|
57
|
+
ipcRenderer.on("websocket:event", (_event, id, event) => listener(id, event));
|
|
58
|
+
},
|
|
59
|
+
},
|
|
41
60
|
network: {
|
|
42
61
|
fetch: (request, cancel) => {
|
|
43
62
|
const id = nextRequest++;
|
|
@@ -76,6 +95,7 @@ const api = {
|
|
|
76
95
|
remove: (path) => ipcRenderer.sendSync("air:remove", String(path)),
|
|
77
96
|
move: (from, to) => ipcRenderer.sendSync("air:move", String(from), String(to)),
|
|
78
97
|
window: () => ipcRenderer.sendSync("air:window"),
|
|
98
|
+
screens: () => ipcRenderer.sendSync("air:screens"),
|
|
79
99
|
setBounds: (bounds) => ipcRenderer.send("air:set-bounds", bounds),
|
|
80
100
|
setTitle: (title) => ipcRenderer.send("air:set-title", String(title)),
|
|
81
101
|
minimize: () => ipcRenderer.send("air:window-do", "minimize"),
|