ai-remote 0.4.8 → 0.4.9
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/index.d.ts +254 -12
- package/dist/protocols.d.ts +349 -0
- package/package.json +3 -3
- package/dist/protocols/index.d.ts +0 -33
- package/dist/protocols/rdp/buffer.d.ts +0 -38
- package/dist/protocols/rdp/caps.d.ts +0 -49
- package/dist/protocols/rdp/cert.d.ts +0 -18
- package/dist/protocols/rdp/client.d.ts +0 -56
- package/dist/protocols/rdp/cliprdr.d.ts +0 -27
- package/dist/protocols/rdp/credssp.d.ts +0 -34
- package/dist/protocols/rdp/crypto.d.ts +0 -63
- package/dist/protocols/rdp/display.d.ts +0 -38
- package/dist/protocols/rdp/gcc.d.ts +0 -23
- package/dist/protocols/rdp/keymap.d.ts +0 -9
- package/dist/protocols/rdp/mcs.d.ts +0 -40
- package/dist/protocols/rdp/ntlm.d.ts +0 -61
- package/dist/protocols/rdp/pdu.d.ts +0 -155
- package/dist/protocols/rdp/rail.d.ts +0 -119
- package/dist/protocols/rdp/rle.d.ts +0 -13
- package/dist/protocols/rdp/sec.d.ts +0 -59
- package/dist/protocols/rdp/session.d.ts +0 -62
- package/dist/protocols/rdp/tls.d.ts +0 -18
- package/dist/protocols/rdp/vchannel.d.ts +0 -28
- package/dist/protocols/rdp/x224.d.ts +0 -40
- package/dist/protocols/ssh/identity.d.ts +0 -39
- package/dist/protocols/ssh/kex.d.ts +0 -97
- package/dist/protocols/ssh/messages.d.ts +0 -52
- package/dist/protocols/ssh/session.d.ts +0 -67
- package/dist/protocols/ssh/terminal.d.ts +0 -46
- package/dist/protocols/ssh/transport.d.ts +0 -62
- package/dist/protocols/ssh/wire.d.ts +0 -52
- package/dist/protocols/types.d.ts +0 -127
- package/dist/protocols/vnc/des.d.ts +0 -25
- package/dist/protocols/vnc/input.d.ts +0 -5
- package/dist/protocols/vnc/keysyms.d.ts +0 -16
- package/dist/protocols/vnc/rfb.d.ts +0 -64
- package/dist/protocols/vnc/session.d.ts +0 -12
- package/dist/shared/connection.d.ts +0 -81
- package/dist/shared/device.d.ts +0 -26
- package/dist/shared/hosts.d.ts +0 -63
- package/dist/shared/icons.d.ts +0 -46
- package/dist/shared/protocol.d.ts +0 -32
- package/dist/shared/signals.d.ts +0 -37
|
@@ -1,62 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,52 +0,0 @@
|
|
|
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;
|
|
@@ -1,127 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DES, for the one thing VNC still needs it for.
|
|
3
|
-
*
|
|
4
|
-
* The classic VNC password challenge (security type 2) is a single-block DES
|
|
5
|
-
* encryption, and there is no getting round it: it is what every host from
|
|
6
|
-
* x11vnc to RealVNC expects. Node's own crypto cannot help -- OpenSSL 3 moved
|
|
7
|
-
* DES to the legacy provider, which is off in most builds -- and Web Crypto
|
|
8
|
-
* never had it. So it is here, in about a hundred lines of tables.
|
|
9
|
-
*
|
|
10
|
-
* Nothing else in this repository should use this. DES is broken, and the only
|
|
11
|
-
* reason it is here is that a protocol from 1998 froze it into a handshake.
|
|
12
|
-
* The implementation is the textbook one, bit by bit: two blocks per sign-in
|
|
13
|
-
* makes speed irrelevant and clarity worth having.
|
|
14
|
-
*/
|
|
15
|
-
/** One 8-byte block, encrypted under an 8-byte key. */
|
|
16
|
-
export declare function desEncryptBlock(key: Uint8Array, block: Uint8Array): Uint8Array;
|
|
17
|
-
/**
|
|
18
|
-
* The key VNC makes out of a password.
|
|
19
|
-
*
|
|
20
|
-
* Eight bytes, padded with zeros, and every byte's bits reversed -- an accident
|
|
21
|
-
* of the original implementation that every host has copied ever since.
|
|
22
|
-
*/
|
|
23
|
-
export declare function vncKey(password: string): Uint8Array;
|
|
24
|
-
/** The answer to a host's 16-byte challenge: both halves, encrypted. */
|
|
25
|
-
export declare function vncChallengeResponse(password: string, challenge: Uint8Array): Uint8Array;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DOM key codes as X11 keysyms, which is what RFB sends.
|
|
3
|
-
*
|
|
4
|
-
* RDP sends scancodes, so the keyboard map on that side is a hardware table.
|
|
5
|
-
* VNC sends keysyms -- what the key *means* rather than where it sits -- and
|
|
6
|
-
* the useful consequence is that a character needs no modifier bookkeeping:
|
|
7
|
-
* asking for `A` asks for a capital A, and the host works out that its own
|
|
8
|
-
* keyboard would need shift for that.
|
|
9
|
-
*
|
|
10
|
-
* Latin-1 characters are their own code point. Everything above that is the
|
|
11
|
-
* Unicode escape from the X protocol: 0x01000000 plus the code point.
|
|
12
|
-
*/
|
|
13
|
-
/** A character's keysym: itself in Latin-1, and escaped above it. */
|
|
14
|
-
export declare function keysymForChar(character: string): number;
|
|
15
|
-
/** A DOM `code`'s keysym, or 0 for a key this does not know. */
|
|
16
|
-
export declare function keysymForCode(code: string): number;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* An RFB client that needs no browser.
|
|
3
|
-
*
|
|
4
|
-
* The VNC path in this repository has always been noVNC in a tab with the
|
|
5
|
-
* gateway doing the handshake, which is fine for a tab and no use at all to a
|
|
6
|
-
* command line: `RFB` wants a DOM element to paint into, and the half of the
|
|
7
|
-
* handshake macOS requires lives in the Worker. This is the protocol on its
|
|
8
|
-
* own -- version, security, pixels and input -- speaking to an injected
|
|
9
|
-
* transport, so the CLI can hold a desktop the same way it holds an RDP one.
|
|
10
|
-
*
|
|
11
|
-
* The handshake reads as a straight line rather than a state machine, because
|
|
12
|
-
* that is what it is: each step waits for the bytes it needs. Everything after
|
|
13
|
-
* it is a message loop.
|
|
14
|
-
*
|
|
15
|
-
* Two pieces of the protocol need primitives no runtime offers portably --
|
|
16
|
-
* DES for the classic password challenge, MD5 and AES for Apple's key
|
|
17
|
-
* exchange -- so they arrive as an injected `crypto`, the same seam the
|
|
18
|
-
* transport uses.
|
|
19
|
-
*/
|
|
20
|
-
export interface RfbCrypto {
|
|
21
|
-
/** Security type 2: the 16-byte answer to the host's challenge. */
|
|
22
|
-
vncChallenge(password: string, challenge: Uint8Array): Uint8Array;
|
|
23
|
-
/** Security type 30: what macOS Screen Sharing asks for instead of a challenge. */
|
|
24
|
-
appleDh(params: Uint8Array, username: string, password: string): Uint8Array;
|
|
25
|
-
}
|
|
26
|
-
/** One painted area. `copyFrom` is a rectangle the host says is already on screen. */
|
|
27
|
-
export interface RfbRect {
|
|
28
|
-
left: number;
|
|
29
|
-
top: number;
|
|
30
|
-
width: number;
|
|
31
|
-
height: number;
|
|
32
|
-
/** RGBA, row-major. Absent for a copy. */
|
|
33
|
-
rgba?: Uint8Array;
|
|
34
|
-
copyFrom?: {
|
|
35
|
-
x: number;
|
|
36
|
-
y: number;
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
export interface RfbOptions {
|
|
40
|
-
username?: string;
|
|
41
|
-
password?: string;
|
|
42
|
-
/** Let other viewers stay connected. Always true here: a session is watched. */
|
|
43
|
-
shared?: boolean;
|
|
44
|
-
crypto: RfbCrypto;
|
|
45
|
-
openTransport: () => any;
|
|
46
|
-
log?: (step: string, detail?: unknown) => void;
|
|
47
|
-
}
|
|
48
|
-
export declare class RfbClient extends EventTarget {
|
|
49
|
-
#private;
|
|
50
|
-
readonly options: RfbOptions;
|
|
51
|
-
width: number;
|
|
52
|
-
height: number;
|
|
53
|
-
name: string;
|
|
54
|
-
connected: boolean;
|
|
55
|
-
constructor(options: RfbOptions);
|
|
56
|
-
connect(): void;
|
|
57
|
-
disconnect(): void;
|
|
58
|
-
/** `mask` is RFB's own numbering: 1 left, 2 middle, 4 right, 8/16 wheel. */
|
|
59
|
-
pointer(x: number, y: number, mask?: number): void;
|
|
60
|
-
key(keysym: number, pressed: boolean): void;
|
|
61
|
-
cutText(text: string): void;
|
|
62
|
-
/** Ask for the whole desktop again rather than what has changed. */
|
|
63
|
-
refresh(): void;
|
|
64
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
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;
|
|
@@ -1,81 +0,0 @@
|
|
|
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;
|
package/dist/shared/device.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
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/hosts.d.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
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/icons.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Icon path data, shared by the server-rendered login page and the React app.
|
|
3
|
-
*
|
|
4
|
-
* Each value is the inside of a 24x24 stroked `<svg>`; the wrapper differs
|
|
5
|
-
* between the two (a string on the Worker, a component in the browser) but the
|
|
6
|
-
* geometry should not.
|
|
7
|
-
*/
|
|
8
|
-
export declare const ICON_PATHS: {
|
|
9
|
-
readonly monitor: '<rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/>';
|
|
10
|
-
readonly link: '<path d="M9 17H7A5 5 0 0 1 7 7h2M15 7h2a5 5 0 1 1 0 10h-2M8 12h8"/>';
|
|
11
|
-
readonly power: '<path d="M12 2v10"/><path d="M18.4 6.6a9 9 0 1 1-12.8 0"/>';
|
|
12
|
-
readonly maximize: '<path d="M8 3H5a2 2 0 0 0-2 2v3M21 8V5a2 2 0 0 0-2-2h-3M3 16v3a2 2 0 0 0 2 2h3M16 21h3a2 2 0 0 0 2-2v-3"/>';
|
|
13
|
-
readonly minimize: '<path d="M8 3v3a2 2 0 0 1-2 2H3M21 8h-3a2 2 0 0 1-2-2V3M3 16h3a2 2 0 0 1 2 2v3M16 21v-3a2 2 0 0 1 2-2h3"/>';
|
|
14
|
-
readonly keyboard: '<rect x="2" y="4" width="20" height="16" rx="2"/><path d="M6 8h.01M10 8h.01M14 8h.01M18 8h.01M8 12h.01M12 12h.01M16 12h.01M7 16h10"/>';
|
|
15
|
-
readonly clipboard: '<rect x="8" y="2" width="8" height="4" rx="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>';
|
|
16
|
-
readonly check: '<path d="m5 13 4 4 10-10"/>';
|
|
17
|
-
readonly camera: '<path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/>';
|
|
18
|
-
readonly eye: '<path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12z"/><circle cx="12" cy="12" r="3"/>';
|
|
19
|
-
readonly sliders: '<path d="M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M2 14h4M10 8h4M18 16h4"/>';
|
|
20
|
-
readonly expand: '<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>';
|
|
21
|
-
readonly shield: '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>';
|
|
22
|
-
readonly chevron: '<path d="m6 9 6 6 6-6"/>';
|
|
23
|
-
readonly back: '<path d="m15 18-6-6 6-6"/>';
|
|
24
|
-
readonly zap: '<path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/>';
|
|
25
|
-
readonly cube: '<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="m3.3 7 8.7 5 8.7-5M12 22V12"/>';
|
|
26
|
-
readonly logout: '<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9"/>';
|
|
27
|
-
readonly clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3.5 2"/>';
|
|
28
|
-
readonly activity: '<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>';
|
|
29
|
-
readonly transfer: '<path d="m3 16 4 4 4-4M7 20V4M21 8l-4-4-4 4M17 4v16"/>';
|
|
30
|
-
readonly screen: '<rect x="2" y="5" width="20" height="13" rx="2"/><path d="M7 21h10"/>';
|
|
31
|
-
readonly command: '<path d="M15 6a3 3 0 1 1 3 3h-3zm0 0v12m0 0a3 3 0 1 0 3-3h-3zM9 6a3 3 0 1 0-3 3h3zm0 0v12m0 0a3 3 0 1 1-3-3h3z"/>';
|
|
32
|
-
readonly apps: '<rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/>';
|
|
33
|
-
readonly terminal: '<path d="m4 17 6-6-6-6M12 19h8"/>';
|
|
34
|
-
readonly folder: '<path d="M3 7h6l2 2h10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M3 7V6a2 2 0 0 1 2-2h4l2 3"/>';
|
|
35
|
-
readonly close: '<path d="M18 6 6 18M6 6l12 12"/>';
|
|
36
|
-
readonly sparkles: '<path d="m12 3 1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9L12 3z"/><path d="m19 15 .8 2.2 2.2.8-2.2.8L19 21l-.8-2.2-2.2-.8 2.2-.8z"/>';
|
|
37
|
-
readonly broom: '<path d="M10 10V4a2 2 0 0 1 4 0v6"/><path d="M6 10h12a2 2 0 0 1 2 2v2H4v-2a2 2 0 0 1 2-2Z"/><path d="m5 14-2 7h18l-2-7M9 18l-1 3M15 18l1 3"/>';
|
|
38
|
-
readonly panel: '<rect x="3" y="4" width="18" height="16" rx="2"/><path d="M14 4v16"/>';
|
|
39
|
-
readonly menu: '<path d="M4 7h16M4 12h16M4 17h16"/>';
|
|
40
|
-
readonly plus: '<path d="M12 5v14M5 12h14"/>';
|
|
41
|
-
readonly star: '<path d="m12 3 2.9 5.9 6.5.9-4.7 4.6 1.1 6.5L12 17.8 6.2 20.9l1.1-6.5L2.6 9.8l6.5-.9L12 3z"/>';
|
|
42
|
-
readonly trash: '<path d="M3 6h18M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>';
|
|
43
|
-
};
|
|
44
|
-
export type IconName = keyof typeof ICON_PATHS;
|
|
45
|
-
/** The tab icon: a monitor in Cloudflare orange. */
|
|
46
|
-
export declare const FAVICON_DATA_URI = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f38020' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='3' width='20' height='14' rx='2'/%3E%3Cpath d='M8 21h8M12 17v4'/%3E%3C/svg%3E";
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The vocabulary both halves of the gateway share.
|
|
3
|
-
*
|
|
4
|
-
* The Worker and the browser have to agree on what a "protocol" is, what ports
|
|
5
|
-
* they default to and how an RDP security layer is named, so those live here
|
|
6
|
-
* rather than being re-declared on each side and drifting apart.
|
|
7
|
-
*/
|
|
8
|
-
/** A remote-desktop protocol the session workspace can display. */
|
|
9
|
-
export declare const REMOTE_PROTOCOLS: readonly ['vnc', 'rdp'];
|
|
10
|
-
export type RemoteProtocol = (typeof REMOTE_PROTOCOLS)[number];
|
|
11
|
-
/** Every protocol the gateway relays, including the terminal side panel. */
|
|
12
|
-
export declare const TRANSPORT_PROTOCOLS: readonly ['vnc', 'rdp', 'ssh'];
|
|
13
|
-
export type TransportProtocol = (typeof TRANSPORT_PROTOCOLS)[number];
|
|
14
|
-
/**
|
|
15
|
-
* The RDP security layer. `auto` negotiates with the host, which is right for
|
|
16
|
-
* anything that answers honestly; the rest are for hosts that do not.
|
|
17
|
-
*/
|
|
18
|
-
export declare const RDP_SECURITY_MODES: readonly ['auto', 'nla', 'tls', 'rdp'];
|
|
19
|
-
export type RdpSecurity = (typeof RDP_SECURITY_MODES)[number];
|
|
20
|
-
export declare const DEFAULT_PORTS: Record<TransportProtocol, number>;
|
|
21
|
-
export declare const DEFAULT_SSH_PORT: number;
|
|
22
|
-
/** Max time allowed before command start output is detected. */
|
|
23
|
-
export declare const COMMAND_START_MS = 15000;
|
|
24
|
-
/** Max idle silence allowed during command execution. */
|
|
25
|
-
export declare const COMMAND_IDLE_MS: number;
|
|
26
|
-
export declare function isRemoteProtocol(value: unknown): value is RemoteProtocol;
|
|
27
|
-
export declare function isRdpSecurity(value: unknown): value is RdpSecurity;
|
|
28
|
-
/** Coerce anything to a protocol, falling back to what the caller opens on. */
|
|
29
|
-
export declare function toRemoteProtocol(value: unknown, fallback?: RemoteProtocol): RemoteProtocol;
|
|
30
|
-
export declare function toRdpSecurity(value: unknown, fallback?: RdpSecurity): RdpSecurity;
|
|
31
|
-
/** A port number, or the protocol's default when the value is not one. */
|
|
32
|
-
export declare function toPort(value: unknown, fallback: number): number;
|
package/dist/shared/signals.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Control frames the browser and the gateway exchange on the WebSocket that
|
|
3
|
-
* carries a remote-desktop stream.
|
|
4
|
-
*
|
|
5
|
-
* They are plain strings precisely so they can never be confused with the
|
|
6
|
-
* binary protocol payload flowing in either direction, and both sides import
|
|
7
|
-
* these same literals so the two halves cannot drift apart.
|
|
8
|
-
*/
|
|
9
|
-
/** Browser -> gateway: "my WebSocket is open, you may start reading the host". */
|
|
10
|
-
export declare const GATEWAY_READY_SIGNAL = "VNC_GATEWAY_READY_v1";
|
|
11
|
-
/**
|
|
12
|
-
* Browser -> gateway: keep the edge from idling out a silent session.
|
|
13
|
-
* Cloudflare closes a WebSocket with no traffic in either direction for 100s,
|
|
14
|
-
* and an untouched desktop transmits nothing at all.
|
|
15
|
-
*/
|
|
16
|
-
export declare const GATEWAY_KEEPALIVE_SIGNAL = "VNC_GATEWAY_KEEPALIVE_v1";
|
|
17
|
-
/**
|
|
18
|
-
* How often the browser nudges the transport. Well inside the edge's 100s
|
|
19
|
-
* window, so a session that is merely being looked at is never torn down
|
|
20
|
-
* without a close frame -- which is what a bare WebSocket 1006 used to mean.
|
|
21
|
-
*/
|
|
22
|
-
export declare const KEEPALIVE_INTERVAL_MS = 25000;
|
|
23
|
-
export declare const MAX_CLOSE_REASON_BYTES = 123;
|
|
24
|
-
/** Whether a live desktop ended for a transient transport reason worth retrying. */
|
|
25
|
-
export declare function isRetryableDisconnect(diagnostic: {
|
|
26
|
-
close: {
|
|
27
|
-
code: number;
|
|
28
|
-
reason: string;
|
|
29
|
-
} | null;
|
|
30
|
-
established: boolean;
|
|
31
|
-
}): boolean;
|
|
32
|
-
/** WebSocket close reasons are capped at 123 bytes; trim without splitting a code point. */
|
|
33
|
-
export declare function websocketCloseReason(reason: string): string;
|
|
34
|
-
/** 1005/1006/1015 are reserved and cannot be transmitted in a close frame. */
|
|
35
|
-
export declare function sendableCloseCode(code: number): number;
|
|
36
|
-
/** Normalize any WebSocket message payload to bytes. */
|
|
37
|
-
export declare function messageToBytes(data: unknown): Promise<Uint8Array | null>;
|