ai-remote 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{src/index.ts → dist/index.d.ts} +0 -1
- package/dist/index.js +0 -1
- package/dist/protocols/index.d.ts +31 -0
- package/dist/protocols/index.js +0 -1
- package/dist/protocols/rdp/buffer.d.ts +38 -0
- package/dist/protocols/rdp/buffer.js +0 -1
- package/dist/protocols/rdp/caps.d.ts +49 -0
- package/dist/protocols/rdp/caps.js +0 -1
- package/dist/protocols/rdp/cert.d.ts +18 -0
- package/dist/protocols/rdp/cert.js +0 -1
- package/dist/protocols/rdp/client.d.ts +56 -0
- package/dist/protocols/rdp/client.js +0 -1
- package/dist/protocols/rdp/cliprdr.d.ts +27 -0
- package/dist/protocols/rdp/cliprdr.js +0 -1
- package/dist/protocols/rdp/credssp.d.ts +34 -0
- package/dist/protocols/rdp/credssp.js +0 -1
- package/dist/protocols/rdp/crypto.d.ts +63 -0
- package/dist/protocols/rdp/crypto.js +0 -1
- package/dist/protocols/rdp/display.d.ts +38 -0
- package/dist/protocols/rdp/display.js +0 -1
- package/dist/protocols/rdp/gcc.d.ts +23 -0
- package/dist/protocols/rdp/gcc.js +0 -1
- package/dist/protocols/rdp/keymap.d.ts +9 -0
- package/dist/protocols/rdp/keymap.js +0 -1
- package/dist/protocols/rdp/mcs.d.ts +40 -0
- package/dist/protocols/rdp/mcs.js +0 -1
- package/dist/protocols/rdp/ntlm.d.ts +61 -0
- package/dist/protocols/rdp/ntlm.js +0 -1
- package/dist/protocols/rdp/pdu.d.ts +155 -0
- package/dist/protocols/rdp/pdu.js +0 -1
- package/dist/protocols/rdp/rail.d.ts +119 -0
- package/dist/protocols/rdp/rail.js +0 -1
- package/dist/protocols/rdp/rle.d.ts +13 -0
- package/dist/protocols/rdp/rle.js +0 -1
- package/dist/protocols/rdp/sec.d.ts +59 -0
- package/dist/protocols/rdp/sec.js +0 -1
- package/dist/protocols/rdp/session.d.ts +62 -0
- package/dist/protocols/rdp/session.js +0 -1
- package/dist/protocols/rdp/tls.d.ts +18 -0
- package/dist/protocols/rdp/tls.js +0 -1
- package/dist/protocols/rdp/vchannel.d.ts +28 -0
- package/dist/protocols/rdp/vchannel.js +0 -1
- package/dist/protocols/rdp/x224.d.ts +40 -0
- package/dist/protocols/rdp/x224.js +0 -1
- package/dist/protocols/ssh/kex.d.ts +97 -0
- package/dist/protocols/ssh/kex.js +0 -1
- package/dist/protocols/ssh/messages.d.ts +50 -0
- package/dist/protocols/ssh/messages.js +0 -1
- package/dist/protocols/ssh/session.d.ts +66 -0
- package/dist/protocols/ssh/session.js +0 -1
- package/dist/protocols/ssh/terminal.d.ts +46 -0
- package/dist/protocols/ssh/terminal.js +0 -1
- package/dist/protocols/ssh/transport.d.ts +62 -0
- package/dist/protocols/ssh/transport.js +0 -1
- package/dist/protocols/ssh/wire.d.ts +52 -0
- package/dist/protocols/ssh/wire.js +0 -1
- package/dist/protocols/types.d.ts +127 -0
- package/dist/protocols/types.js +0 -1
- package/dist/protocols/vnc/input.d.ts +5 -0
- package/dist/protocols/vnc/input.js +0 -1
- package/dist/protocols/vnc/session.d.ts +12 -0
- package/dist/protocols/vnc/session.js +0 -1
- package/dist/shared/connection.d.ts +81 -0
- package/dist/shared/connection.js +0 -1
- package/dist/shared/device.d.ts +26 -0
- package/dist/shared/device.js +0 -1
- package/dist/shared/hosts.d.ts +63 -0
- package/dist/shared/hosts.js +0 -1
- package/dist/shared/icons.d.ts +46 -0
- package/dist/shared/icons.js +0 -1
- package/dist/shared/protocol.d.ts +28 -0
- package/dist/shared/protocol.js +0 -1
- package/dist/shared/signals.d.ts +37 -0
- package/dist/shared/signals.js +0 -1
- package/package.json +10 -11
- package/dist/index.js.map +0 -7
- package/dist/protocols/index.js.map +0 -7
- package/dist/protocols/rdp/buffer.js.map +0 -7
- package/dist/protocols/rdp/caps.js.map +0 -7
- package/dist/protocols/rdp/cert.js.map +0 -7
- package/dist/protocols/rdp/client.js.map +0 -7
- package/dist/protocols/rdp/cliprdr.js.map +0 -7
- package/dist/protocols/rdp/credssp.js.map +0 -7
- package/dist/protocols/rdp/crypto.js.map +0 -7
- package/dist/protocols/rdp/display.js.map +0 -7
- package/dist/protocols/rdp/gcc.js.map +0 -7
- package/dist/protocols/rdp/keymap.js.map +0 -7
- package/dist/protocols/rdp/mcs.js.map +0 -7
- package/dist/protocols/rdp/ntlm.js.map +0 -7
- package/dist/protocols/rdp/pdu.js.map +0 -7
- package/dist/protocols/rdp/rail.js.map +0 -7
- package/dist/protocols/rdp/rle.js.map +0 -7
- package/dist/protocols/rdp/sec.js.map +0 -7
- package/dist/protocols/rdp/session.js.map +0 -7
- package/dist/protocols/rdp/tls.js.map +0 -7
- package/dist/protocols/rdp/vchannel.js.map +0 -7
- package/dist/protocols/rdp/x224.js.map +0 -7
- package/dist/protocols/ssh/kex.js.map +0 -7
- package/dist/protocols/ssh/messages.js.map +0 -7
- package/dist/protocols/ssh/session.js.map +0 -7
- package/dist/protocols/ssh/terminal.js.map +0 -7
- package/dist/protocols/ssh/transport.js.map +0 -7
- package/dist/protocols/ssh/wire.js.map +0 -7
- package/dist/protocols/types.js.map +0 -7
- package/dist/protocols/vnc/input.js.map +0 -7
- package/dist/protocols/vnc/session.js.map +0 -7
- package/dist/shared/connection.js.map +0 -7
- package/dist/shared/device.js.map +0 -7
- package/dist/shared/hosts.js.map +0 -7
- package/dist/shared/icons.js.map +0 -7
- package/dist/shared/protocol.js.map +0 -7
- package/dist/shared/signals.js.map +0 -7
- package/src/cli/cli.ts +0 -462
- package/src/cli/daemon.ts +0 -306
- package/src/cli/framebuffer.ts +0 -115
- package/src/cli/generated/viewer-bundle.ts +0 -5
- package/src/cli/ipc.ts +0 -78
- package/src/cli/native/window.swift +0 -151
- package/src/cli/paths.ts +0 -28
- package/src/cli/png.ts +0 -106
- package/src/cli/session.ts +0 -263
- package/src/cli/shell.ts +0 -184
- package/src/cli/transport.ts +0 -86
- package/src/cli/viewer-client/assets.d.ts +0 -4
- package/src/cli/viewer-client/main.ts +0 -323
- package/src/cli/viewer-page.ts +0 -138
- package/src/cli/viewer.ts +0 -296
- package/src/cli/window.ts +0 -140
- package/src/cli/wsserver.ts +0 -144
- package/src/protocols/index.ts +0 -72
- package/src/protocols/rdp/buffer.ts +0 -204
- package/src/protocols/rdp/caps.ts +0 -304
- package/src/protocols/rdp/cert.ts +0 -190
- package/src/protocols/rdp/client.ts +0 -1371
- package/src/protocols/rdp/cliprdr.ts +0 -344
- package/src/protocols/rdp/credssp.ts +0 -319
- package/src/protocols/rdp/crypto.ts +0 -416
- package/src/protocols/rdp/display.ts +0 -750
- package/src/protocols/rdp/gcc.ts +0 -162
- package/src/protocols/rdp/keymap.ts +0 -68
- package/src/protocols/rdp/mcs.ts +0 -283
- package/src/protocols/rdp/ntlm.ts +0 -380
- package/src/protocols/rdp/pdu.ts +0 -497
- package/src/protocols/rdp/rail.ts +0 -480
- package/src/protocols/rdp/rle.ts +0 -343
- package/src/protocols/rdp/sec.ts +0 -184
- package/src/protocols/rdp/session.ts +0 -393
- package/src/protocols/rdp/tls.ts +0 -452
- package/src/protocols/rdp/vchannel.ts +0 -89
- package/src/protocols/rdp/x224.ts +0 -139
- package/src/protocols/ssh/kex.ts +0 -227
- package/src/protocols/ssh/messages.ts +0 -54
- package/src/protocols/ssh/session.ts +0 -879
- package/src/protocols/ssh/terminal.ts +0 -242
- package/src/protocols/ssh/transport.ts +0 -745
- package/src/protocols/ssh/wire.ts +0 -220
- package/src/protocols/types.ts +0 -146
- package/src/protocols/vnc/input.ts +0 -13
- package/src/protocols/vnc/novnc.d.ts +0 -75
- package/src/protocols/vnc/session.ts +0 -367
- package/src/shared/connection.ts +0 -206
- package/src/shared/device.ts +0 -28
- package/src/shared/hosts.ts +0 -240
- package/src/shared/icons.ts +0 -49
- package/src/shared/protocol.ts +0 -55
- package/src/shared/signals.ts +0 -67
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export declare const MSG: {
|
|
2
|
+
DISCONNECT: number;
|
|
3
|
+
IGNORE: number;
|
|
4
|
+
UNIMPLEMENTED: number;
|
|
5
|
+
DEBUG: number;
|
|
6
|
+
SERVICE_REQUEST: number;
|
|
7
|
+
SERVICE_ACCEPT: number;
|
|
8
|
+
EXT_INFO: number;
|
|
9
|
+
KEXINIT: number;
|
|
10
|
+
NEWKEYS: number;
|
|
11
|
+
KEX_ECDH_INIT: number;
|
|
12
|
+
KEX_ECDH_REPLY: number;
|
|
13
|
+
USERAUTH_REQUEST: number;
|
|
14
|
+
USERAUTH_FAILURE: number;
|
|
15
|
+
USERAUTH_SUCCESS: number;
|
|
16
|
+
USERAUTH_BANNER: number;
|
|
17
|
+
USERAUTH_INFO_REQUEST: number;
|
|
18
|
+
USERAUTH_INFO_RESPONSE: number;
|
|
19
|
+
GLOBAL_REQUEST: number;
|
|
20
|
+
REQUEST_SUCCESS: number;
|
|
21
|
+
REQUEST_FAILURE: number;
|
|
22
|
+
CHANNEL_OPEN: number;
|
|
23
|
+
CHANNEL_OPEN_CONFIRMATION: number;
|
|
24
|
+
CHANNEL_OPEN_FAILURE: number;
|
|
25
|
+
CHANNEL_WINDOW_ADJUST: number;
|
|
26
|
+
CHANNEL_DATA: number;
|
|
27
|
+
CHANNEL_EXTENDED_DATA: number;
|
|
28
|
+
CHANNEL_EOF: number;
|
|
29
|
+
CHANNEL_CLOSE: number;
|
|
30
|
+
CHANNEL_REQUEST: number;
|
|
31
|
+
CHANNEL_SUCCESS: number;
|
|
32
|
+
CHANNEL_FAILURE: number;
|
|
33
|
+
};
|
|
34
|
+
/** SSH_EXTENDED_DATA_STDERR. */
|
|
35
|
+
export declare const EXTENDED_DATA_STDERR = 1;
|
|
36
|
+
export declare const DISCONNECT_REASON: {
|
|
37
|
+
1: string;
|
|
38
|
+
2: string;
|
|
39
|
+
3: string;
|
|
40
|
+
5: string;
|
|
41
|
+
6: string;
|
|
42
|
+
7: string;
|
|
43
|
+
8: string;
|
|
44
|
+
9: string;
|
|
45
|
+
10: string;
|
|
46
|
+
11: string;
|
|
47
|
+
12: string;
|
|
48
|
+
14: string;
|
|
49
|
+
15: string;
|
|
50
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export declare const DEFAULT_PORT = 22;
|
|
2
|
+
/**
|
|
3
|
+
* How patient `runCommand` is, in three different senses.
|
|
4
|
+
*
|
|
5
|
+
* A single deadline cannot tell "the shell ignored me" apart from "the
|
|
6
|
+
* installer is three minutes into a download", and a short one turns every
|
|
7
|
+
* real piece of work -- a package install, a build, a large copy -- into a
|
|
8
|
+
* false failure that also leaves the command running on the far side.
|
|
9
|
+
*
|
|
10
|
+
* So the wait is judged by what the shell is doing. It has START_MS to
|
|
11
|
+
* acknowledge the command at all; after that it may take as long as it likes
|
|
12
|
+
* as long as it keeps printing, and only silence longer than IDLE_MS, or a run
|
|
13
|
+
* longer than MAX_MS, is treated as stuck.
|
|
14
|
+
*/
|
|
15
|
+
export declare const COMMAND_START_MS = 20000;
|
|
16
|
+
export declare const COMMAND_IDLE_MS: number;
|
|
17
|
+
export declare const COMMAND_MAX_MS: number;
|
|
18
|
+
/**
|
|
19
|
+
* The one line that runs `command` and marks where its output starts and ends.
|
|
20
|
+
*
|
|
21
|
+
* Each shell gets its own, because none of the three agree on how to print a
|
|
22
|
+
* string, run a command and read back its exit status.
|
|
23
|
+
*/
|
|
24
|
+
export declare function frameCommand(family: any, command: string, id: any): string;
|
|
25
|
+
export declare class SshSession extends EventTarget {
|
|
26
|
+
#private;
|
|
27
|
+
/**
|
|
28
|
+
* @param {string} url gateway WebSocket URL
|
|
29
|
+
* @param {object} options
|
|
30
|
+
* @param {string} options.username
|
|
31
|
+
* @param {string} [options.password]
|
|
32
|
+
* @param {'powershell'} [options.preferredShell]
|
|
33
|
+
* @param {(info: object) => Promise<boolean>} [options.verifyHost]
|
|
34
|
+
* @param {(prompt: object) => Promise<string>} [options.requestInput]
|
|
35
|
+
*/
|
|
36
|
+
constructor(url: string, options?: {});
|
|
37
|
+
connect(): void;
|
|
38
|
+
disconnect(): void;
|
|
39
|
+
/** Send keystrokes, or anything else the terminal produces, to the shell. */
|
|
40
|
+
write(data: Uint8Array): void;
|
|
41
|
+
/**
|
|
42
|
+
* Run one command in this shell and return what it printed.
|
|
43
|
+
*
|
|
44
|
+
* Deliberately the *same* shell the user is looking at, not a second channel:
|
|
45
|
+
* a command the assistant runs inherits the working directory, the
|
|
46
|
+
* environment and the login the user already has, and it appears in their
|
|
47
|
+
* terminal as it happens. An agent acting on a machine invisibly is worse
|
|
48
|
+
* than an agent that is slower to read.
|
|
49
|
+
*
|
|
50
|
+
* The output is framed by markers rather than measured, because an
|
|
51
|
+
* interactive shell echoes its input and prints a prompt around it. The
|
|
52
|
+
* markers are assembled by the shell from two pieces, so the echoed command
|
|
53
|
+
* line -- which contains the pieces but not the joined marker -- never looks
|
|
54
|
+
* like the real boundary.
|
|
55
|
+
*
|
|
56
|
+
* A `command` event brackets the run so the terminal can label it, and the
|
|
57
|
+
* three deadlines above decide when a command is stuck rather than slow.
|
|
58
|
+
*/
|
|
59
|
+
runCommand(command: string, { startMs, idleMs, maxMs, }?: {
|
|
60
|
+
idleMs?: number;
|
|
61
|
+
maxMs?: number;
|
|
62
|
+
startMs?: number;
|
|
63
|
+
}): Promise<unknown>;
|
|
64
|
+
/** Tell the shell its window changed, so full-screen programs redraw. */
|
|
65
|
+
resize(columns: number, rows: number): void;
|
|
66
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare class SshTerminal {
|
|
2
|
+
constructor(container: any);
|
|
3
|
+
get columns(): any;
|
|
4
|
+
get rows(): any;
|
|
5
|
+
onData(handler: any): void;
|
|
6
|
+
onResize(handler: any): void;
|
|
7
|
+
write(data: Uint8Array): void;
|
|
8
|
+
/** Gateway-side notices, kept visually apart from what the host prints. */
|
|
9
|
+
notice(text: string, tone?: string): void;
|
|
10
|
+
clear(): void;
|
|
11
|
+
focus(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Size the terminal to the panel, choosing the font so MIN_COLUMNS fit.
|
|
14
|
+
*
|
|
15
|
+
* The columns matter more than the type size here: the commands people run in
|
|
16
|
+
* a side panel -- `ls -l`, `top`, anything in PowerShell that prints a table
|
|
17
|
+
* -- are laid out for 80 columns, and a narrower grid wraps every row into an
|
|
18
|
+
* unreadable stack.
|
|
19
|
+
*
|
|
20
|
+
* `proposeDimensions()` reports the grid the current font size yields, and a
|
|
21
|
+
* monospace cell's width scales with its font size, so `fontSize * cols /
|
|
22
|
+
* MIN_COLUMNS` lands close to the size that gives MIN_COLUMNS. It is measured
|
|
23
|
+
* rather than assumed because the cell-width-to-font-size ratio belongs to
|
|
24
|
+
* whichever font the platform picked. A second pass settles the rounding.
|
|
25
|
+
* Changing the font resizes the element, which the ResizeObserver sees, so
|
|
26
|
+
* the guard keeps that from recursing.
|
|
27
|
+
*/
|
|
28
|
+
fit(): void;
|
|
29
|
+
/** The grid the host is being told about, for a status line or a log. */
|
|
30
|
+
get geometry(): {
|
|
31
|
+
columns: any;
|
|
32
|
+
rows: any;
|
|
33
|
+
fontSize: any;
|
|
34
|
+
};
|
|
35
|
+
get selection(): any;
|
|
36
|
+
/**
|
|
37
|
+
* Read one line from the user, for a password or a one-time code the host
|
|
38
|
+
* asked for during authentication. The shell is not open yet, so the
|
|
39
|
+
* terminal is free to be a prompt.
|
|
40
|
+
*/
|
|
41
|
+
readLine({ prompt, echo }?: {
|
|
42
|
+
echo?: boolean;
|
|
43
|
+
prompt?: string;
|
|
44
|
+
}): Promise<unknown>;
|
|
45
|
+
destroy(): void;
|
|
46
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export declare const CLIENT_VERSION = "SSH-2.0-CloudflareGateway_1.0";
|
|
2
|
+
/** Pick the first client preference the host also offered (RFC 4253 7.1). */
|
|
3
|
+
export declare function negotiate(clientNames: any, serverNames: any): any;
|
|
4
|
+
export declare class SshTransport extends EventTarget {
|
|
5
|
+
#private;
|
|
6
|
+
url: string;
|
|
7
|
+
verifyHost: (info: any) => Promise<boolean> | boolean;
|
|
8
|
+
log: (...args: any[]) => void;
|
|
9
|
+
socket: WebSocket | null;
|
|
10
|
+
openTransport: ((url: string) => any) | null;
|
|
11
|
+
closed: boolean;
|
|
12
|
+
buffer: Uint8Array;
|
|
13
|
+
serverVersion: string;
|
|
14
|
+
greeting: string[];
|
|
15
|
+
sendSequence: number;
|
|
16
|
+
receiveSequence: number;
|
|
17
|
+
outgoing: any;
|
|
18
|
+
incoming: any;
|
|
19
|
+
sessionId: Uint8Array | null;
|
|
20
|
+
kex: any;
|
|
21
|
+
kexQueue: Uint8Array[];
|
|
22
|
+
keepaliveTimer: any;
|
|
23
|
+
bytesSent: number;
|
|
24
|
+
bytesReceived: number;
|
|
25
|
+
encryptChain?: Promise<void>;
|
|
26
|
+
newKeysBarrier?: Promise<void> | null;
|
|
27
|
+
releaseNewKeys?: (() => void) | null;
|
|
28
|
+
pendingServerKexInit?: Uint8Array | null;
|
|
29
|
+
established?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* @param {string} url gateway WebSocket URL
|
|
32
|
+
* @param {object} options
|
|
33
|
+
* @param {(info: object) => Promise<boolean>} options.verifyHost decides
|
|
34
|
+
* whether an unknown or changed host key may be used.
|
|
35
|
+
*/
|
|
36
|
+
constructor(url: string, { verifyHost, log, openTransport }?: {
|
|
37
|
+
verifyHost?: (info: any) => Promise<boolean> | boolean;
|
|
38
|
+
log?: (...args: any[]) => void;
|
|
39
|
+
/** Returns a WebSocket-shaped transport for `url`; default is a real one. */
|
|
40
|
+
openTransport?: ((url: string) => any) | null;
|
|
41
|
+
});
|
|
42
|
+
connect(): void;
|
|
43
|
+
disconnect(message?: string): void;
|
|
44
|
+
fail(error: unknown): void;
|
|
45
|
+
/** Application packets wait while a key exchange is in flight (RFC 4253 7.1). */
|
|
46
|
+
send(payload: Uint8Array): boolean;
|
|
47
|
+
}
|
|
48
|
+
/** Padding for a GCM packet: only the encrypted part is block aligned. */
|
|
49
|
+
export declare function gcmPaddingLength(payloadLength: any): number;
|
|
50
|
+
/** A packet before any keys exist: the whole thing is block aligned. */
|
|
51
|
+
export declare function framePlain(payload: Uint8Array): Uint8Array<ArrayBufferLike>;
|
|
52
|
+
export declare function buildKexInit(offer: any): Uint8Array<ArrayBufferLike>;
|
|
53
|
+
export declare function parseKexInit(payload: Uint8Array): {
|
|
54
|
+
kex: string[];
|
|
55
|
+
hostKey: string[];
|
|
56
|
+
cipherClientToServer: string[];
|
|
57
|
+
cipherServerToClient: string[];
|
|
58
|
+
macClientToServer: string[];
|
|
59
|
+
macServerToClient: string[];
|
|
60
|
+
compressionClientToServer: string[];
|
|
61
|
+
compressionServerToClient: string[];
|
|
62
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare function encodeUtf8(text: string): Uint8Array;
|
|
2
|
+
export declare function decodeUtf8(bytes: Uint8Array): string;
|
|
3
|
+
export declare function concatBytes(...parts: readonly Uint8Array[]): Uint8Array;
|
|
4
|
+
/** Constant-time-ish equality. Used for authentication tags and fingerprints. */
|
|
5
|
+
export declare function bytesEqual(a: Uint8Array, b: Uint8Array): boolean;
|
|
6
|
+
export declare function toBase64(bytes: Uint8Array): string;
|
|
7
|
+
export declare function fromBase64(text: string): Uint8Array;
|
|
8
|
+
/** Base64url without padding, which is what a JSON Web Key wants. */
|
|
9
|
+
export declare function toBase64Url(bytes: Uint8Array): string;
|
|
10
|
+
export declare class SshWriter {
|
|
11
|
+
#private;
|
|
12
|
+
private bytes;
|
|
13
|
+
private view;
|
|
14
|
+
private offset;
|
|
15
|
+
constructor(capacity?: number);
|
|
16
|
+
u8(value: number): this;
|
|
17
|
+
boolean(value: boolean): this;
|
|
18
|
+
u32(value: number): this;
|
|
19
|
+
raw(bytes: Uint8Array): this;
|
|
20
|
+
/** A length-prefixed string. Text is encoded as UTF-8. */
|
|
21
|
+
string(value: string | Uint8Array): this;
|
|
22
|
+
nameList(names: readonly string[]): this;
|
|
23
|
+
/**
|
|
24
|
+
* An mpint: two's complement, big endian, with no leading zero bytes except
|
|
25
|
+
* the one that keeps a positive number from looking negative.
|
|
26
|
+
*/
|
|
27
|
+
mpint(bytes: Uint8Array): this;
|
|
28
|
+
get length(): number;
|
|
29
|
+
take(): Uint8Array;
|
|
30
|
+
}
|
|
31
|
+
export declare class SshReader {
|
|
32
|
+
#private;
|
|
33
|
+
private readonly bytes;
|
|
34
|
+
private readonly view;
|
|
35
|
+
offset: number;
|
|
36
|
+
constructor(bytes: Uint8Array, offset?: number);
|
|
37
|
+
get remaining(): number;
|
|
38
|
+
u8(): number;
|
|
39
|
+
boolean(): boolean;
|
|
40
|
+
u32(): number;
|
|
41
|
+
raw(count: number): Uint8Array;
|
|
42
|
+
/** The bytes of a length-prefixed string. */
|
|
43
|
+
stringBytes(): Uint8Array;
|
|
44
|
+
string(): string;
|
|
45
|
+
nameList(): string[];
|
|
46
|
+
/** An mpint's magnitude, with the sign byte removed. */
|
|
47
|
+
mpint(): Uint8Array;
|
|
48
|
+
skip(count: number): this;
|
|
49
|
+
rest(): Uint8Array;
|
|
50
|
+
}
|
|
51
|
+
/** Pad a magnitude out to a fixed width, which raw curve points need. */
|
|
52
|
+
export declare function padStart(bytes: Uint8Array, width: number): Uint8Array;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interface every remote-desktop protocol presents to the UI.
|
|
3
|
+
*
|
|
4
|
+
* The workspace -- toolbar, stats rail, on-screen keyboard, reconnects -- does
|
|
5
|
+
* not care whether a session is VNC or RDP. Everything that does differ is
|
|
6
|
+
* reached through this interface instead of branching at each call site.
|
|
7
|
+
*/
|
|
8
|
+
import type { ConnectionSettings, RemoteAppLaunch } from '../shared/connection';
|
|
9
|
+
import type { RdpSecurity, RemoteProtocol } from '../shared/protocol';
|
|
10
|
+
/** Where the pointer may go, in framebuffer pixels. */
|
|
11
|
+
export interface ScreenGeometry {
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
viewport: {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Mouse buttons, as the UI names them. */
|
|
22
|
+
export type PointerButton = 0 | 1 | 2;
|
|
23
|
+
/** Wheel movement in discrete remote-protocol notches. Positive is right/down. */
|
|
24
|
+
export interface ScrollDelta {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A live session. Both drivers expose this, so the AI pane's screen tool and
|
|
30
|
+
* the toolbar never have to ask which protocol they are driving.
|
|
31
|
+
*/
|
|
32
|
+
export interface RemoteSession extends EventTarget {
|
|
33
|
+
readonly protocol: RemoteProtocol;
|
|
34
|
+
disconnect(): void;
|
|
35
|
+
/** True once the desktop has been reached. */
|
|
36
|
+
readonly connected: boolean;
|
|
37
|
+
/** Fit the remote desktop to the pane rather than scrolling it. */
|
|
38
|
+
scaleViewport: boolean;
|
|
39
|
+
/** Watch without sending keyboard or pointer input. */
|
|
40
|
+
viewOnly: boolean;
|
|
41
|
+
/** RFB quality level. RDP ignores it. */
|
|
42
|
+
qualityLevel?: number;
|
|
43
|
+
/** RFB compression level. RDP ignores it. */
|
|
44
|
+
compressionLevel?: number;
|
|
45
|
+
/** The transport the metrics rail instruments. Can appear a tick after construction. */
|
|
46
|
+
readonly socket?: WebSocket | null;
|
|
47
|
+
readonly screenGeometry: ScreenGeometry;
|
|
48
|
+
movePointer(x: number, y: number): boolean;
|
|
49
|
+
clickPointer(x: number, y: number, button?: PointerButton): boolean;
|
|
50
|
+
pointerButton(x: number, y: number, button?: PointerButton, pressed?: boolean): boolean;
|
|
51
|
+
scrollPointer(x: number, y: number, delta: ScrollDelta): boolean;
|
|
52
|
+
typeText(text: string): boolean;
|
|
53
|
+
/** Prefer the protocol clipboard for longer text when it can paste reliably. */
|
|
54
|
+
pasteText?(text: string): boolean | Promise<boolean>;
|
|
55
|
+
/** Press or release one key by keysym. */
|
|
56
|
+
sendKey(keysym: number, code: string | null, down?: boolean): void;
|
|
57
|
+
/** Send text to the host's clipboard, when the protocol carries one. */
|
|
58
|
+
sendClipboard?(text: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Stop taking keystrokes: the workspace has given the keyboard to something
|
|
61
|
+
* local, such as the terminal or the assistant's message box.
|
|
62
|
+
*
|
|
63
|
+
* Both protocols listen on the element they paint into, so a key only leaves
|
|
64
|
+
* for the host while that element holds focus. Handing focus back is the
|
|
65
|
+
* whole mechanism -- plus, for RDP, letting go of anything still held down,
|
|
66
|
+
* which would otherwise stay down on the far side.
|
|
67
|
+
*/
|
|
68
|
+
releaseKeyboard?(): void;
|
|
69
|
+
/** Ask the host for a different desktop size, when the protocol allows it. */
|
|
70
|
+
requestDesktopSize?(width: number, height: number): void;
|
|
71
|
+
/** The canvas the session paints into, for screenshots and thumbnails. */
|
|
72
|
+
readonly canvas?: HTMLCanvasElement | null;
|
|
73
|
+
}
|
|
74
|
+
/** What the workspace hands a driver to open a session. */
|
|
75
|
+
export interface SessionOptions {
|
|
76
|
+
credentials: {
|
|
77
|
+
username: string;
|
|
78
|
+
password: string;
|
|
79
|
+
};
|
|
80
|
+
domain: string;
|
|
81
|
+
security: RdpSecurity;
|
|
82
|
+
remoteApp: RemoteAppLaunch | null;
|
|
83
|
+
/** Desktop size to ask the host for. */
|
|
84
|
+
width: number;
|
|
85
|
+
height: number;
|
|
86
|
+
/** False on a phone, where resizing the host would make a portrait strip of it. */
|
|
87
|
+
allowRemoteResize: boolean;
|
|
88
|
+
scaleViewport: boolean;
|
|
89
|
+
viewOnly: boolean;
|
|
90
|
+
quality: number;
|
|
91
|
+
compression: number;
|
|
92
|
+
/** Shown in this driver's own log lines. */
|
|
93
|
+
hostLabel: string;
|
|
94
|
+
}
|
|
95
|
+
/** Wording for the one connect dialog, which is shared markup across protocols. */
|
|
96
|
+
export interface DialogCopy {
|
|
97
|
+
usernameLabel: string;
|
|
98
|
+
usernamePlaceholder: string;
|
|
99
|
+
usernameHelp: string;
|
|
100
|
+
passwordLabel: string;
|
|
101
|
+
passwordPlaceholder: string;
|
|
102
|
+
passwordHelp: string;
|
|
103
|
+
/** A VNC session needs some secret; RDP can sign in on the host's own screen. */
|
|
104
|
+
requiresPassword: boolean;
|
|
105
|
+
}
|
|
106
|
+
/** Everything the UI knows about a close, before anyone tries to explain it. */
|
|
107
|
+
export interface DisconnectContext {
|
|
108
|
+
code?: number;
|
|
109
|
+
reason: string;
|
|
110
|
+
/** Pre-rendered ` (WebSocket 1006: ...)` tail, so wording stays consistent. */
|
|
111
|
+
suffix: string;
|
|
112
|
+
}
|
|
113
|
+
/** One protocol implementation. */
|
|
114
|
+
export interface ProtocolDriver {
|
|
115
|
+
readonly protocol: RemoteProtocol;
|
|
116
|
+
/** Used as the prefix of this driver's console lines. */
|
|
117
|
+
readonly label: string;
|
|
118
|
+
readonly defaultPort: number;
|
|
119
|
+
readonly dialog: DialogCopy;
|
|
120
|
+
/** The gateway endpoint for this connection, including any query it needs. */
|
|
121
|
+
buildUrl(origin: string, settings: ConnectionSettings): string;
|
|
122
|
+
createSession(container: HTMLElement, url: string, options: SessionOptions): RemoteSession;
|
|
123
|
+
/** Extra detail worth logging once the first server frame has been parsed. */
|
|
124
|
+
describeState(session: RemoteSession): Record<string, unknown>;
|
|
125
|
+
/** Protocol-specific wording for a close, or null to fall back to the shared text. */
|
|
126
|
+
describeDisconnect(context: DisconnectContext): string | null;
|
|
127
|
+
}
|
package/dist/protocols/types.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everything VNC-specific, behind the driver interface the RDP side also
|
|
3
|
+
* implements. noVNC's RFB object does the protocol work; this module decides
|
|
4
|
+
* how it is addressed, constructed, controlled and explained.
|
|
5
|
+
*
|
|
6
|
+
* VNC splits the handshake differently from RDP: noVNC hands authentication to
|
|
7
|
+
* the Worker, because macOS Screen Sharing needs the Apple Diffie-Hellman
|
|
8
|
+
* (type 30) exchange that noVNC does not implement. That is why credentials
|
|
9
|
+
* travel in the URL here and never do for RDP.
|
|
10
|
+
*/
|
|
11
|
+
import type { ProtocolDriver } from '../types';
|
|
12
|
+
export declare const vncDriver: ProtocolDriver;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One connection, described once.
|
|
3
|
+
*
|
|
4
|
+
* Every way of starting a session -- a saved card on the welcome screen, an
|
|
5
|
+
* address typed by hand, a RemoteApp launcher, a reconnect after a drop --
|
|
6
|
+
* produces exactly this shape and hands it to exactly one dialog. That is the
|
|
7
|
+
* whole point of the type: before it existed, a saved card could only ask for a
|
|
8
|
+
* username and a password, so its port, security layer, domain and picture
|
|
9
|
+
* quality were unreachable once the card had been made.
|
|
10
|
+
*/
|
|
11
|
+
import { type RdpSecurity, type RemoteProtocol } from './protocol';
|
|
12
|
+
/** A published Windows application launched instead of the full desktop. */
|
|
13
|
+
export interface RemoteAppLaunch {
|
|
14
|
+
/** Alias (`||notepad`) or an executable path. */
|
|
15
|
+
program: string;
|
|
16
|
+
workingDir?: string;
|
|
17
|
+
arguments?: string;
|
|
18
|
+
}
|
|
19
|
+
/** The companion terminal offered beside a desktop. */
|
|
20
|
+
export interface SshCompanion {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
port: number;
|
|
23
|
+
username: string;
|
|
24
|
+
}
|
|
25
|
+
/** Picture and input options. VNC negotiates them; RDP and SSH ignore what does not apply. */
|
|
26
|
+
export interface DisplaySettings {
|
|
27
|
+
/** RFB quality level, 1 (smallest) to 9 (sharpest). */
|
|
28
|
+
quality: number;
|
|
29
|
+
/** RFB compression level, 0 (fastest) to 9 (smallest). */
|
|
30
|
+
compression: number;
|
|
31
|
+
/** Fit the remote desktop to the pane rather than scrolling it. */
|
|
32
|
+
scaling: boolean;
|
|
33
|
+
/** Watch without sending keyboard or pointer input. */
|
|
34
|
+
viewOnly: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Everything a session needs. `password` is the only field never persisted
|
|
38
|
+
* anywhere -- not in the device library on the gateway, not in localStorage.
|
|
39
|
+
*/
|
|
40
|
+
export interface ConnectionSettings {
|
|
41
|
+
/** Stable identity: protocol, address, port and program. See {@link connectionId}. */
|
|
42
|
+
id: string;
|
|
43
|
+
label: string;
|
|
44
|
+
protocol: RemoteProtocol;
|
|
45
|
+
host: string;
|
|
46
|
+
port: number;
|
|
47
|
+
username: string;
|
|
48
|
+
password: string;
|
|
49
|
+
/** Windows domain or computer name. RDP only. */
|
|
50
|
+
domain: string;
|
|
51
|
+
security: RdpSecurity;
|
|
52
|
+
remoteApp: RemoteAppLaunch | null;
|
|
53
|
+
display: DisplaySettings;
|
|
54
|
+
ssh: SshCompanion;
|
|
55
|
+
/** Open the terminal panel as soon as the desktop appears. */
|
|
56
|
+
openSshOnConnect: boolean;
|
|
57
|
+
}
|
|
58
|
+
export declare const DEFAULT_DISPLAY_SETTINGS: DisplaySettings;
|
|
59
|
+
/**
|
|
60
|
+
* A connection's identity is what it points at, not when it was made. Editing
|
|
61
|
+
* the address therefore makes a different connection rather than silently
|
|
62
|
+
* repointing an existing card, which is the behaviour people expect from a
|
|
63
|
+
* list of machines.
|
|
64
|
+
*/
|
|
65
|
+
export declare function connectionId(input: Pick<ConnectionSettings, 'protocol' | 'host' | 'port'> & {
|
|
66
|
+
remoteApp?: RemoteAppLaunch | null;
|
|
67
|
+
}): string;
|
|
68
|
+
/** A blank connection, ready for the dialog to fill in. */
|
|
69
|
+
export declare function emptyConnection(protocol?: RemoteProtocol): ConnectionSettings;
|
|
70
|
+
export declare function normalizeDisplaySettings(value: unknown): DisplaySettings;
|
|
71
|
+
/**
|
|
72
|
+
* Build a complete, valid connection out of whatever a caller happens to have.
|
|
73
|
+
* Partial input from a saved card, a host list entry, a URL or localStorage all
|
|
74
|
+
* arrive here, so the dialog never has to reason about missing fields.
|
|
75
|
+
*/
|
|
76
|
+
export declare function normalizeConnection(input: Partial<ConnectionSettings> & Record<string, unknown>): ConnectionSettings;
|
|
77
|
+
/** What a connection is worth remembering by -- never the password. */
|
|
78
|
+
export type PersistedConnection = Omit<ConnectionSettings, 'password'>;
|
|
79
|
+
export declare function withoutPassword(settings: ConnectionSettings): PersistedConnection;
|
|
80
|
+
/** A one-line description for the dialog's summary row and the status bar. */
|
|
81
|
+
export declare function describeConnection(settings: ConnectionSettings): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A machine as the gateway remembers it, shared by the Durable Object that
|
|
3
|
+
* stores the record and the welcome screen that draws it.
|
|
4
|
+
*
|
|
5
|
+
* Passwords and account names are deliberately absent: the gateway has no need
|
|
6
|
+
* of them and every reason not to hold them. They live in the browser, next to
|
|
7
|
+
* the rest of the connection's settings.
|
|
8
|
+
*/
|
|
9
|
+
import type { RdpSecurity, RemoteProtocol } from './protocol';
|
|
10
|
+
export interface SavedDevice {
|
|
11
|
+
id: string;
|
|
12
|
+
label: string;
|
|
13
|
+
host: string;
|
|
14
|
+
port: number;
|
|
15
|
+
protocol: RemoteProtocol;
|
|
16
|
+
domain?: string;
|
|
17
|
+
security?: RdpSecurity;
|
|
18
|
+
/** RemoteApp alias (`||notepad`) when this card launches an app, not a desktop. */
|
|
19
|
+
program?: string;
|
|
20
|
+
favorite?: boolean;
|
|
21
|
+
/** Milliseconds since the epoch; drives the "recent" ordering. */
|
|
22
|
+
lastUsed?: number;
|
|
23
|
+
createdAt?: number;
|
|
24
|
+
/** Set when a thumbnail exists, so the client can cache-bust its <img>. */
|
|
25
|
+
thumbnailAt?: number;
|
|
26
|
+
}
|
package/dist/shared/device.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The gateway's own roster of machines, and the networks it is allowed to dial.
|
|
3
|
+
*
|
|
4
|
+
* Parsing lives here, with no reference to the Worker environment, so the same
|
|
5
|
+
* code shapes the list in `VNC_HOSTS`/`RDP_HOSTS` and the list the browser
|
|
6
|
+
* receives from `/api/hosts`. Reading those variables is the Worker's job --
|
|
7
|
+
* see `src/worker/config/hosts.ts`.
|
|
8
|
+
*/
|
|
9
|
+
import type { RemoteAppLaunch } from './connection';
|
|
10
|
+
import { type RdpSecurity, type RemoteProtocol } from './protocol';
|
|
11
|
+
/** Optional SSH access to the same machine, which publishes a terminal for it. */
|
|
12
|
+
export interface HostSshAccess {
|
|
13
|
+
port: number;
|
|
14
|
+
username?: string;
|
|
15
|
+
}
|
|
16
|
+
/** One machine as the gateway's configuration describes it. */
|
|
17
|
+
export interface RemoteHostTarget {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
host: string;
|
|
21
|
+
port: number;
|
|
22
|
+
protocol: RemoteProtocol;
|
|
23
|
+
/** Windows domain or computer name pre-filled in the connect dialog. */
|
|
24
|
+
domain?: string;
|
|
25
|
+
security?: RdpSecurity;
|
|
26
|
+
remoteApp?: RemoteAppLaunch;
|
|
27
|
+
ssh?: HostSshAccess;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build the target list offered in the connect dialog. `VNC_HOSTS` and
|
|
31
|
+
* `RDP_HOSTS` are merged into one list; each entry may override its protocol,
|
|
32
|
+
* so a single list can carry both kinds of target.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseConfiguredHosts(options: {
|
|
35
|
+
vncHostsJson?: string;
|
|
36
|
+
rdpHostsJson?: string;
|
|
37
|
+
defaultHost?: string;
|
|
38
|
+
defaultPort?: string;
|
|
39
|
+
defaultRdpHost?: string;
|
|
40
|
+
defaultRdpPort?: string;
|
|
41
|
+
}): RemoteHostTarget[];
|
|
42
|
+
/** One allowed network, as a base address and a mask. */
|
|
43
|
+
export interface Subnet {
|
|
44
|
+
base: number;
|
|
45
|
+
mask: number;
|
|
46
|
+
}
|
|
47
|
+
/** Dotted-quad to a 32-bit number, or null for anything that is not one. */
|
|
48
|
+
export declare function ipv4ToInt(value: string): number | null;
|
|
49
|
+
/**
|
|
50
|
+
* The networks this gateway may dial, beyond the machines named in the host
|
|
51
|
+
* lists. Written as `ALLOWED_SUBNETS`, comma-separated:
|
|
52
|
+
*
|
|
53
|
+
* 192.168.8.0/24 a CIDR block
|
|
54
|
+
* 192.168.8.* the same thing, written the way people say it
|
|
55
|
+
* 192.168.8.67 a single address
|
|
56
|
+
*
|
|
57
|
+
* This is what lets a terminal open on a machine that was never listed. Keep it
|
|
58
|
+
* to networks you own: anything inside one can be reached on any port by anyone
|
|
59
|
+
* who gets past the gateway's login.
|
|
60
|
+
*/
|
|
61
|
+
export declare function parseAllowedSubnets(value?: string): Subnet[];
|
|
62
|
+
/** Whether a dotted-quad address falls inside one of the allowed networks. */
|
|
63
|
+
export declare function hostInAllowedSubnets(host: string, value?: string): boolean;
|
package/dist/shared/hosts.js
CHANGED