ai-remote 0.4.2 → 0.4.4

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.
Files changed (75) hide show
  1. package/dist/index.js +1 -6
  2. package/dist/{protocols/index.d.ts → protocols.d.ts} +2 -0
  3. package/dist/protocols.js +24 -0
  4. package/package.json +15 -10
  5. package/dist/protocols/index.js +0 -34
  6. package/dist/protocols/rdp/buffer.d.ts +0 -38
  7. package/dist/protocols/rdp/buffer.js +0 -169
  8. package/dist/protocols/rdp/caps.d.ts +0 -49
  9. package/dist/protocols/rdp/caps.js +0 -259
  10. package/dist/protocols/rdp/cert.d.ts +0 -18
  11. package/dist/protocols/rdp/cert.js +0 -134
  12. package/dist/protocols/rdp/client.d.ts +0 -56
  13. package/dist/protocols/rdp/client.js +0 -1069
  14. package/dist/protocols/rdp/cliprdr.d.ts +0 -27
  15. package/dist/protocols/rdp/cliprdr.js +0 -239
  16. package/dist/protocols/rdp/credssp.d.ts +0 -34
  17. package/dist/protocols/rdp/credssp.js +0 -253
  18. package/dist/protocols/rdp/crypto.d.ts +0 -63
  19. package/dist/protocols/rdp/crypto.js +0 -368
  20. package/dist/protocols/rdp/display.d.ts +0 -38
  21. package/dist/protocols/rdp/display.js +0 -588
  22. package/dist/protocols/rdp/gcc.d.ts +0 -23
  23. package/dist/protocols/rdp/gcc.js +0 -131
  24. package/dist/protocols/rdp/keymap.d.ts +0 -9
  25. package/dist/protocols/rdp/keymap.js +0 -131
  26. package/dist/protocols/rdp/mcs.d.ts +0 -40
  27. package/dist/protocols/rdp/mcs.js +0 -222
  28. package/dist/protocols/rdp/ntlm.d.ts +0 -61
  29. package/dist/protocols/rdp/ntlm.js +0 -304
  30. package/dist/protocols/rdp/pdu.d.ts +0 -155
  31. package/dist/protocols/rdp/pdu.js +0 -443
  32. package/dist/protocols/rdp/rail.d.ts +0 -119
  33. package/dist/protocols/rdp/rail.js +0 -382
  34. package/dist/protocols/rdp/rle.d.ts +0 -13
  35. package/dist/protocols/rdp/rle.js +0 -275
  36. package/dist/protocols/rdp/sec.d.ts +0 -59
  37. package/dist/protocols/rdp/sec.js +0 -155
  38. package/dist/protocols/rdp/session.d.ts +0 -62
  39. package/dist/protocols/rdp/session.js +0 -306
  40. package/dist/protocols/rdp/tls.d.ts +0 -18
  41. package/dist/protocols/rdp/tls.js +0 -353
  42. package/dist/protocols/rdp/vchannel.d.ts +0 -28
  43. package/dist/protocols/rdp/vchannel.js +0 -58
  44. package/dist/protocols/rdp/x224.d.ts +0 -40
  45. package/dist/protocols/rdp/x224.js +0 -109
  46. package/dist/protocols/ssh/kex.d.ts +0 -97
  47. package/dist/protocols/ssh/kex.js +0 -176
  48. package/dist/protocols/ssh/messages.d.ts +0 -50
  49. package/dist/protocols/ssh/messages.js +0 -54
  50. package/dist/protocols/ssh/session.d.ts +0 -66
  51. package/dist/protocols/ssh/session.js +0 -608
  52. package/dist/protocols/ssh/terminal.d.ts +0 -46
  53. package/dist/protocols/ssh/terminal.js +0 -190
  54. package/dist/protocols/ssh/transport.d.ts +0 -62
  55. package/dist/protocols/ssh/transport.js +0 -612
  56. package/dist/protocols/ssh/wire.d.ts +0 -52
  57. package/dist/protocols/ssh/wire.js +0 -188
  58. package/dist/protocols/types.d.ts +0 -127
  59. package/dist/protocols/types.js +0 -0
  60. package/dist/protocols/vnc/input.d.ts +0 -5
  61. package/dist/protocols/vnc/input.js +0 -15
  62. package/dist/protocols/vnc/session.d.ts +0 -12
  63. package/dist/protocols/vnc/session.js +0 -258
  64. package/dist/shared/connection.d.ts +0 -81
  65. package/dist/shared/connection.js +0 -113
  66. package/dist/shared/device.d.ts +0 -26
  67. package/dist/shared/device.js +0 -0
  68. package/dist/shared/hosts.d.ts +0 -63
  69. package/dist/shared/hosts.js +0 -132
  70. package/dist/shared/icons.d.ts +0 -46
  71. package/dist/shared/icons.js +0 -41
  72. package/dist/shared/protocol.d.ts +0 -28
  73. package/dist/shared/protocol.js +0 -39
  74. package/dist/shared/signals.d.ts +0 -37
  75. package/dist/shared/signals.js +0 -41
@@ -1,59 +0,0 @@
1
- import { concatBytes } from './buffer';
2
- export declare const SEC_FLAG: {
3
- EXCHANGE_PKT: number;
4
- TRANSPORT_REQ: number;
5
- ENCRYPT: number;
6
- RESET_SEQNO: number;
7
- IGNORE_SEQNO: number;
8
- INFO_PKT: number;
9
- LICENSE_PKT: number;
10
- LICENSE_ENCRYPT_CS: number;
11
- REDIRECTION_PKT: number;
12
- SECURE_CHECKSUM: number;
13
- AUTODETECT_REQ: number;
14
- AUTODETECT_RSP: number;
15
- HEARTBEAT: number;
16
- };
17
- export declare class SecurityLayer {
18
- #private;
19
- private encryptionMethod;
20
- private encryptionLevel;
21
- private keys;
22
- private encryptState;
23
- private decryptState;
24
- private encryptedPdus;
25
- private decryptedPdus;
26
- constructor();
27
- /** True when data PDUs carry a basic security header at all. */
28
- get headerPresent(): boolean;
29
- get encryptionEnabled(): boolean;
30
- configure(encryptionMethod: number, encryptionLevel: number, clientRandom: Uint8Array, serverRandom: Uint8Array): void;
31
- /**
32
- * Prefix a payload with the basic security header, signing and encrypting it
33
- * when the negotiated level asks for that.
34
- *
35
- * `flags` carries the PDU-kind bits (SEC_INFO_PKT and friends). A payload with
36
- * no flags and no encryption needs no header at all.
37
- */
38
- wrap(payload: Uint8Array, flags?: number): Uint8Array<ArrayBufferLike>;
39
- /**
40
- * Strip (and if needed decrypt) the basic security header from a host PDU.
41
- * `headerMandatory` forces the header to be read even when the host reported
42
- * no encryption, which licensing PDUs require.
43
- */
44
- unwrap(bytes: Uint8Array, headerMandatory?: boolean): {
45
- flags: number;
46
- payload: Uint8Array<ArrayBufferLike>;
47
- };
48
- /**
49
- * Fast-path output carries the same signature and RC4 stream as a slow-path
50
- * PDU, but without the basic security header in front of it.
51
- */
52
- decryptFastPath(payload: Uint8Array): Uint8Array<ArrayBufferLike>;
53
- /**
54
- * Security Exchange PDU (MS-RDPBCGR 2.2.1.10): the client random encrypted
55
- * with the host public key, followed by eight bytes of padding.
56
- */
57
- static securityExchange(encryptedClientRandom: any): Uint8Array<ArrayBufferLike>;
58
- }
59
- export { concatBytes };
@@ -1,155 +0,0 @@
1
- import { Reader, Writer, concatBytes } from "./buffer.js";
2
- import {
3
- ENCRYPTION_METHOD,
4
- deriveSessionKeys,
5
- macSignature,
6
- rc4Crypt,
7
- rc4Init,
8
- updateSessionKey
9
- } from "./crypto.js";
10
- import { ENCRYPTION_LEVEL } from "./gcc.js";
11
- const SEC_FLAG = {
12
- EXCHANGE_PKT: 1,
13
- TRANSPORT_REQ: 2,
14
- ENCRYPT: 8,
15
- RESET_SEQNO: 16,
16
- IGNORE_SEQNO: 32,
17
- INFO_PKT: 64,
18
- LICENSE_PKT: 128,
19
- LICENSE_ENCRYPT_CS: 512,
20
- REDIRECTION_PKT: 1024,
21
- SECURE_CHECKSUM: 2048,
22
- AUTODETECT_REQ: 4096,
23
- AUTODETECT_RSP: 8192,
24
- HEARTBEAT: 16384
25
- };
26
- const KEY_ROTATION_INTERVAL = 4096;
27
- class SecurityLayer {
28
- encryptionMethod;
29
- encryptionLevel;
30
- keys;
31
- encryptState;
32
- decryptState;
33
- encryptedPdus;
34
- decryptedPdus;
35
- constructor() {
36
- this.encryptionMethod = ENCRYPTION_METHOD.NONE;
37
- this.encryptionLevel = ENCRYPTION_LEVEL.NONE;
38
- this.keys = null;
39
- this.encryptState = null;
40
- this.decryptState = null;
41
- this.encryptedPdus = 0;
42
- this.decryptedPdus = 0;
43
- }
44
- /** True when data PDUs carry a basic security header at all. */
45
- get headerPresent() {
46
- return this.encryptionLevel !== ENCRYPTION_LEVEL.NONE || this.encryptionMethod !== ENCRYPTION_METHOD.NONE;
47
- }
48
- get encryptionEnabled() {
49
- return this.encryptionMethod !== ENCRYPTION_METHOD.NONE && this.keys !== null;
50
- }
51
- configure(encryptionMethod, encryptionLevel, clientRandom, serverRandom) {
52
- this.encryptionMethod = encryptionMethod;
53
- this.encryptionLevel = encryptionLevel;
54
- if (encryptionMethod === ENCRYPTION_METHOD.NONE) return;
55
- if (encryptionMethod & ENCRYPTION_METHOD.FIPS) {
56
- throw new Error("RDP: this host requires FIPS encryption, which this client does not implement");
57
- }
58
- this.keys = deriveSessionKeys(clientRandom, serverRandom, encryptionMethod);
59
- this.encryptState = rc4Init(this.keys.encryptKey);
60
- this.decryptState = rc4Init(this.keys.decryptKey);
61
- }
62
- #rotateEncryptKey() {
63
- this.keys.encryptKey = updateSessionKey(
64
- this.keys.initialEncryptKey,
65
- this.keys.encryptKey,
66
- this.keys.keyLength,
67
- this.keys.is40Bit
68
- );
69
- this.encryptState = rc4Init(this.keys.encryptKey);
70
- this.encryptedPdus = 0;
71
- }
72
- #rotateDecryptKey() {
73
- this.keys.decryptKey = updateSessionKey(
74
- this.keys.initialDecryptKey,
75
- this.keys.decryptKey,
76
- this.keys.keyLength,
77
- this.keys.is40Bit
78
- );
79
- this.decryptState = rc4Init(this.keys.decryptKey);
80
- this.decryptedPdus = 0;
81
- }
82
- /**
83
- * Prefix a payload with the basic security header, signing and encrypting it
84
- * when the negotiated level asks for that.
85
- *
86
- * `flags` carries the PDU-kind bits (SEC_INFO_PKT and friends). A payload with
87
- * no flags and no encryption needs no header at all.
88
- */
89
- wrap(payload, flags = 0) {
90
- const encrypt = this.encryptionEnabled;
91
- if (!encrypt && flags === 0 && !this.headerPresent) return payload;
92
- const writer = new Writer(payload.length + 16);
93
- writer.u16le(flags | (encrypt ? SEC_FLAG.ENCRYPT : 0));
94
- writer.u16le(0);
95
- if (!encrypt) {
96
- writer.raw(payload);
97
- return writer.take();
98
- }
99
- writer.raw(macSignature(this.keys.macKey, payload));
100
- writer.raw(rc4Crypt(this.encryptState, payload));
101
- if (++this.encryptedPdus === KEY_ROTATION_INTERVAL) this.#rotateEncryptKey();
102
- return writer.take();
103
- }
104
- /**
105
- * Strip (and if needed decrypt) the basic security header from a host PDU.
106
- * `headerMandatory` forces the header to be read even when the host reported
107
- * no encryption, which licensing PDUs require.
108
- */
109
- unwrap(bytes, headerMandatory = false) {
110
- if (!this.headerPresent && !headerMandatory) return { flags: 0, payload: bytes };
111
- if (bytes.length < 4) return { flags: 0, payload: bytes };
112
- const reader = new Reader(bytes);
113
- const flags = reader.u16le();
114
- reader.u16le();
115
- if (!(flags & SEC_FLAG.ENCRYPT)) {
116
- return { flags, payload: reader.rest() };
117
- }
118
- if (!this.encryptionEnabled) {
119
- throw new Error("RDP: the host encrypted a PDU before the session keys existed");
120
- }
121
- reader.skip(8);
122
- const payload = rc4Crypt(this.decryptState, reader.rest());
123
- if (++this.decryptedPdus === KEY_ROTATION_INTERVAL) this.#rotateDecryptKey();
124
- return { flags, payload };
125
- }
126
- /**
127
- * Fast-path output carries the same signature and RC4 stream as a slow-path
128
- * PDU, but without the basic security header in front of it.
129
- */
130
- decryptFastPath(payload) {
131
- if (!this.encryptionEnabled) return payload;
132
- if (payload.length <= 8) return payload;
133
- const decrypted = rc4Crypt(this.decryptState, payload.subarray(8));
134
- if (++this.decryptedPdus === KEY_ROTATION_INTERVAL) this.#rotateDecryptKey();
135
- return decrypted;
136
- }
137
- /**
138
- * Security Exchange PDU (MS-RDPBCGR 2.2.1.10): the client random encrypted
139
- * with the host public key, followed by eight bytes of padding.
140
- */
141
- static securityExchange(encryptedClientRandom) {
142
- const writer = new Writer(encryptedClientRandom.length + 16);
143
- writer.u16le(SEC_FLAG.EXCHANGE_PKT);
144
- writer.u16le(0);
145
- writer.u32le(encryptedClientRandom.length + 8);
146
- writer.raw(encryptedClientRandom);
147
- writer.zeros(8);
148
- return writer.take();
149
- }
150
- }
151
- export {
152
- SEC_FLAG,
153
- SecurityLayer,
154
- concatBytes
155
- };
@@ -1,62 +0,0 @@
1
- import type { ProtocolDriver } from '../types';
2
- export declare class RdpSession extends EventTarget {
3
- #private;
4
- readonly protocol: 'rdp';
5
- constructor(container: any, url: string, options?: {});
6
- /**
7
- * Ask the host to size the remote application's window to the room this
8
- * session has on the page. Full-desktop sessions have nothing to do here:
9
- * their size is fixed when the connection is negotiated.
10
- */
11
- fitToViewport(): any;
12
- get connected(): boolean;
13
- get canvas(): HTMLCanvasElement | null;
14
- /** The workspace instruments this socket for byte counters and keepalives. */
15
- get socket(): WebSocket | null;
16
- get _sock(): {
17
- _websocket: any;
18
- };
19
- get scaleViewport(): any;
20
- set scaleViewport(enabled: any);
21
- get viewOnly(): any;
22
- set viewOnly(enabled: any);
23
- /**
24
- * The on-screen keyboard and the special-keys dialog call this with an X11
25
- * keysym and a DOM code. RDP wants a scancode, so the code decides; the
26
- * keysym is only a fallback for characters with no key of their own.
27
- */
28
- sendKey(keysym: any, code: number, pressed: boolean): void;
29
- sendCtrlAltDel(): void;
30
- /** Desktop pixels. Returns false when the session cannot accept input. */
31
- movePointer(x: number, y: number): boolean;
32
- clickPointer(x: number, y: number, button?: number): boolean;
33
- pointerButton(x: number, y: number, button?: number, pressed?: boolean): boolean;
34
- scrollPointer(x: number, y: number, delta: {
35
- x: number;
36
- y: number;
37
- }): boolean;
38
- /** Type a run of characters, which RDP carries as Unicode rather than keys. */
39
- typeText(text: string): boolean;
40
- /** What the canvas is showing, for a screen capture or a coordinate check. */
41
- get screenGeometry(): {
42
- width: any;
43
- height: any;
44
- viewport: any;
45
- };
46
- /**
47
- * Hand text to the host's clipboard, falling back to typing it when the host
48
- * declined the clipboard channel -- xrdp builds often do.
49
- */
50
- clipboardPasteFrom(text: string): void;
51
- /**
52
- * Deliver text into the session, which is what the clipboard drawer's button
53
- * has always visibly done. `clipboardPasteFrom` only loads the clipboard, the
54
- * way noVNC's method of that name does.
55
- */
56
- pasteText(text: string): any;
57
- releaseKeyboard(): void;
58
- /** True once the host has agreed to share its clipboard. */
59
- get clipboardShared(): any;
60
- disconnect(): void;
61
- }
62
- export declare const rdpDriver: ProtocolDriver;
@@ -1,306 +0,0 @@
1
- import { RdpClient } from "./client.js";
2
- import { RdpDisplay } from "./display.js";
3
- import { DEFAULT_PORTS } from "../../shared/protocol.js";
4
- const DIALOG = {
5
- usernameLabel: "Username",
6
- usernamePlaceholder: "Windows username",
7
- usernameHelp: "Use the Windows account name for this computer.",
8
- passwordLabel: "Password",
9
- passwordPlaceholder: "Windows password",
10
- passwordHelp: "Use the Windows account password. It may be left empty when the host presents its own sign-in screen.",
11
- // Credentials may be left empty and typed on the remote sign-in screen.
12
- requiresPassword: false
13
- };
14
- function buildUrl(origin, settings) {
15
- const query = new URLSearchParams({
16
- host: settings.host,
17
- port: String(settings.port),
18
- security: settings.security
19
- });
20
- return `${origin}/rdp-ws?${query}`;
21
- }
22
- function describeDisconnect({ code, reason, suffix }) {
23
- if (/hybrid_required|requires network level|authenticates before/i.test(reason)) {
24
- return `The RDP host signs in before showing a desktop${suffix}. Enter the Windows username and password and connect again.`;
25
- }
26
- if (code === 1011 || /cannot connect|unreachable|tcp error|tcp write/i.test(reason)) {
27
- return `The Worker could not keep a TCP connection to the RDP host${suffix}. Check that Remote Desktop is enabled and listening on this address and port.`;
28
- }
29
- return null;
30
- }
31
- class RdpSession extends EventTarget {
32
- protocol = "rdp";
33
- constructor(container, url, options = {}) {
34
- super();
35
- this.url = url;
36
- this.options = options;
37
- this.display = new RdpDisplay(container);
38
- this.display.viewOnly = Boolean(options.viewOnly);
39
- this._rfbConnectionState = "connecting";
40
- this._scaleViewport = options.scaleViewport !== false;
41
- this.display.scaleViewport = this._scaleViewport;
42
- this.lastErrorMessage = "";
43
- this.hostLabel = options.hostLabel || "Remote Desktop";
44
- this.#createClient(options.security || "auto");
45
- this.remoteAppLayoutObserver = options.remoteApp?.program && typeof ResizeObserver === "function" ? new ResizeObserver(() => this.fitToViewport()) : null;
46
- this.remoteAppLayoutObserver?.observe(this.display.scrollHost);
47
- }
48
- #createClient(security) {
49
- this.security = security;
50
- this.client = new RdpClient(this.url, {
51
- width: this.options.width,
52
- height: this.options.height,
53
- username: this.options.credentials?.username || "",
54
- password: this.options.credentials?.password || "",
55
- domain: this.options.domain || "",
56
- security,
57
- keyboardLayout: this.options.keyboardLayout || 1033,
58
- clientName: this.options.clientName || "cf-gateway",
59
- remoteApp: this.options.remoteApp || null
60
- });
61
- this.client.addEventListener("ready", (event) => {
62
- const { width, height } = event.detail;
63
- this.display.resize(width, height);
64
- this.display.attachInput(this.client);
65
- this.display.focus();
66
- this.fitToViewport();
67
- this._rfbConnectionState = "connected";
68
- this.dispatchEvent(new CustomEvent("connect"));
69
- this.dispatchEvent(new CustomEvent("desktopname", {
70
- detail: { name: `${this.hostLabel} (${width}x${height})` }
71
- }));
72
- });
73
- this.client.addEventListener("resize", (event) => {
74
- const { width, height } = event.detail;
75
- this.display.resize(width, height);
76
- this.dispatchEvent(new CustomEvent("desktopname", {
77
- detail: { name: `${this.hostLabel} (${width}x${height})` }
78
- }));
79
- this.fitToViewport();
80
- });
81
- this.client.addEventListener("remoteappviewport", (event) => {
82
- this.display.setViewport(event.detail);
83
- });
84
- this.client.addEventListener("bitmap", (event) => {
85
- this.display.drawRects(event.detail.rects, event.detail.palette);
86
- this.dispatchEvent(new CustomEvent("frame", {
87
- detail: { rects: event.detail.rects }
88
- }));
89
- });
90
- this.client.addEventListener("palette", (event) => {
91
- this.display.palette = event.detail;
92
- });
93
- this.client.addEventListener("pointer", (event) => {
94
- this.display.applyPointer(event.detail);
95
- });
96
- this.client.addEventListener("clipboard", (event) => {
97
- this.dispatchEvent(new CustomEvent("clipboard", { detail: { text: event.detail.text } }));
98
- });
99
- this.client.addEventListener("remoteappresult", (event) => {
100
- this.dispatchEvent(new CustomEvent("remoteappresult", { detail: event.detail }));
101
- });
102
- this.client.addEventListener("remoteappwindow", (event) => {
103
- this.dispatchEvent(new CustomEvent("remoteappwindow", { detail: event.detail }));
104
- });
105
- this.client.addEventListener("remoteappclosed", (event) => {
106
- this.dispatchEvent(new CustomEvent("remoteappclosed", { detail: event.detail }));
107
- });
108
- this.client.addEventListener("error", (event) => {
109
- this.lastErrorMessage = event.detail.message;
110
- });
111
- this.client.addEventListener("close", (event) => {
112
- this._rfbConnectionState = "disconnected";
113
- this.remoteAppLayoutObserver?.disconnect();
114
- this.display.destroy();
115
- this.dispatchEvent(new CustomEvent("disconnect", {
116
- detail: {
117
- clean: Boolean(event.detail.clean),
118
- message: this.lastErrorMessage || event.detail.message || "",
119
- code: event.detail.code,
120
- phase: event.detail.phase
121
- }
122
- }));
123
- });
124
- }
125
- /**
126
- * Ask the host to size the remote application's window to the room this
127
- * session has on the page. Full-desktop sessions have nothing to do here:
128
- * their size is fixed when the connection is negotiated.
129
- */
130
- fitToViewport() {
131
- if (!this.options.remoteApp?.program) return false;
132
- const bounds = this.display.container.getBoundingClientRect();
133
- const width = Math.floor(bounds.width || this.options.width || 0);
134
- const height = Math.floor(bounds.height || this.options.height || 0);
135
- if (width <= 0 || height <= 0) return false;
136
- return this.client.fitRemoteApp(width, height);
137
- }
138
- get connected() {
139
- return this._rfbConnectionState === "connected";
140
- }
141
- get canvas() {
142
- return this.display?.canvas ?? null;
143
- }
144
- /** The workspace instruments this socket for byte counters and keepalives. */
145
- get socket() {
146
- return this.client.socket ?? null;
147
- }
148
- get _sock() {
149
- return { _websocket: this.client.socket };
150
- }
151
- get scaleViewport() {
152
- return this._scaleViewport;
153
- }
154
- set scaleViewport(enabled) {
155
- this._scaleViewport = Boolean(enabled);
156
- this.display.setScaleViewport(this._scaleViewport);
157
- }
158
- get viewOnly() {
159
- return this.display.viewOnly;
160
- }
161
- set viewOnly(enabled) {
162
- this.display.viewOnly = Boolean(enabled);
163
- if (enabled) this.display.releaseAllKeys();
164
- }
165
- /**
166
- * The on-screen keyboard and the special-keys dialog call this with an X11
167
- * keysym and a DOM code. RDP wants a scancode, so the code decides; the
168
- * keysym is only a fallback for characters with no key of their own.
169
- */
170
- sendKey(keysym, code, pressed) {
171
- if (code && this.client.sendKeyByCode(code, pressed)) return;
172
- if (!pressed || !keysym) return;
173
- if (keysym >= 32 && keysym <= 1114111) {
174
- this.client.sendUnicode(String.fromCodePoint(keysym));
175
- }
176
- }
177
- sendCtrlAltDel() {
178
- this.client.sendCtrlAltDel();
179
- }
180
- // --- pointer, for the AI pane's screen-control tool ----------------------
181
- //
182
- // The display already turns browser events into these calls; exposing them
183
- // lets something other than a mouse drive the same path.
184
- /** Desktop pixels. Returns false when the session cannot accept input. */
185
- movePointer(x, y) {
186
- if (!this.client?.connected || this.display.viewOnly) return false;
187
- this.client.sendMouseMove(...this.#clampToDesktop(x, y));
188
- return true;
189
- }
190
- clickPointer(x, y, button = 0) {
191
- if (!this.client?.connected || this.display.viewOnly) return false;
192
- const [px, py] = this.#clampToDesktop(x, y);
193
- this.client.sendMouseMove(px, py);
194
- this.pointerButton(px, py, button, true);
195
- this.pointerButton(px, py, button, false);
196
- return true;
197
- }
198
- pointerButton(x, y, button = 0, pressed = true) {
199
- if (!this.client?.connected || this.display.viewOnly) return false;
200
- const [px, py] = this.#clampToDesktop(x, y);
201
- this.client.sendMouseButton(button, pressed, px, py);
202
- return true;
203
- }
204
- scrollPointer(x, y, delta) {
205
- if (!this.client?.connected || this.display.viewOnly) return false;
206
- const [px, py] = this.#clampToDesktop(x, y);
207
- for (let i = 0; i < Math.min(20, Math.abs(delta.y)); i++) {
208
- this.client.sendWheel(Math.sign(delta.y), px, py, false);
209
- }
210
- for (let i = 0; i < Math.min(20, Math.abs(delta.x)); i++) {
211
- this.client.sendWheel(Math.sign(delta.x), px, py, true);
212
- }
213
- return true;
214
- }
215
- /** Type a run of characters, which RDP carries as Unicode rather than keys. */
216
- typeText(text) {
217
- if (!this.client?.connected || this.display.viewOnly || !text) return false;
218
- let printable = "";
219
- const flushPrintable = () => {
220
- if (!printable) return;
221
- this.client.sendUnicode(printable);
222
- printable = "";
223
- };
224
- for (const character of text) {
225
- if (character === "\n" || character === "\r") {
226
- flushPrintable();
227
- this.client.sendKeyByCode("Enter", true);
228
- this.client.sendKeyByCode("Enter", false);
229
- } else if (character === " ") {
230
- flushPrintable();
231
- this.client.sendKeyByCode("Tab", true);
232
- this.client.sendKeyByCode("Tab", false);
233
- } else {
234
- printable += character;
235
- }
236
- }
237
- flushPrintable();
238
- return true;
239
- }
240
- #clampToDesktop(x, y) {
241
- return [
242
- Math.max(0, Math.min((this.display.width || 1) - 1, Math.round(x))),
243
- Math.max(0, Math.min((this.display.height || 1) - 1, Math.round(y)))
244
- ];
245
- }
246
- /** What the canvas is showing, for a screen capture or a coordinate check. */
247
- get screenGeometry() {
248
- return {
249
- width: this.display.width,
250
- height: this.display.height,
251
- viewport: { ...this.display.viewport }
252
- };
253
- }
254
- /**
255
- * Hand text to the host's clipboard, falling back to typing it when the host
256
- * declined the clipboard channel -- xrdp builds often do.
257
- */
258
- clipboardPasteFrom(text) {
259
- if (!text) return;
260
- const shared = this.client.setClipboardText(text);
261
- if (!shared || typeof shared.then !== "function") {
262
- this.client.sendUnicode(text);
263
- return;
264
- }
265
- shared.then((acknowledged) => {
266
- if (!acknowledged) this.client.sendUnicode(text);
267
- });
268
- }
269
- /**
270
- * Deliver text into the session, which is what the clipboard drawer's button
271
- * has always visibly done. `clipboardPasteFrom` only loads the clipboard, the
272
- * way noVNC's method of that name does.
273
- */
274
- pasteText(text) {
275
- return text ? this.client.pasteToHost(text) : false;
276
- }
277
- releaseKeyboard() {
278
- this.display.releaseAllKeys();
279
- this.display.blur();
280
- }
281
- /** True once the host has agreed to share its clipboard. */
282
- get clipboardShared() {
283
- return this.client.clipboardShared;
284
- }
285
- disconnect() {
286
- this.remoteAppLayoutObserver?.disconnect();
287
- this.client.disconnect();
288
- this.display.destroy();
289
- this._rfbConnectionState = "disconnected";
290
- }
291
- }
292
- const rdpDriver = {
293
- protocol: "rdp",
294
- label: "RDP Client",
295
- defaultPort: DEFAULT_PORTS.rdp,
296
- dialog: DIALOG,
297
- buildUrl,
298
- createSession: (container, url, options) => new RdpSession(container, url, options),
299
- // The RDP client logs its own progress, so there is nothing to add here.
300
- describeState: () => ({}),
301
- describeDisconnect
302
- };
303
- export {
304
- RdpSession,
305
- rdpDriver
306
- };
@@ -1,18 +0,0 @@
1
- export declare class Tls12Client {
2
- #private;
3
- /**
4
- * @param {(bytes: Uint8Array) => void} send write raw bytes to the transport
5
- * @param {(bytes: Uint8Array) => void} onData decrypted application data
6
- * @param {(error: Error) => void} onError fatal protocol failure
7
- */
8
- constructor({ send, onData, onError }: {
9
- onData: any;
10
- onError: any;
11
- send: any;
12
- });
13
- start(): Promise<any>;
14
- /** Feed transport bytes. Calls are serialized, so order is preserved. */
15
- receive(bytes: Uint8Array): any;
16
- /** Send application data once the handshake has completed. */
17
- write(plaintext: Uint8Array): any;
18
- }