herdr-remote-relay 0.3.24 → 0.3.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/README.zh-CN.md +3 -1
- package/dist/protocol/herdr-keys.d.ts +8 -0
- package/dist/protocol/herdr-keys.js +34 -0
- package/dist/protocol/index.d.ts +2 -0
- package/dist/protocol/index.js +2 -0
- package/dist/protocol/messages.d.ts +12 -0
- package/dist/protocol/release.d.ts +8 -0
- package/dist/protocol/release.js +17 -0
- package/dist/server/client-channel.js +1 -0
- package/dist/server/host-channel.js +3 -1
- package/dist/server/sessions.js +1 -0
- package/dist/server/types.d.ts +2 -0
- package/package.json +1 -1
- package/web/dist/assets/index-BeveQ9Di.js +61 -0
- package/web/dist/index.html +1 -1
- package/web/dist/assets/index-Ci-VU6DA.js +0 -61
package/README.md
CHANGED
|
@@ -11,10 +11,12 @@ Brokers WebSocket connections between browsers and workstation host connectors.
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npm install -g herdr-remote-relay
|
|
14
|
+
npm install -g https://github.com/dibin666/herdr-remote/releases/latest/download/herdr-remote-relay.tgz
|
|
15
15
|
herdr-remote-relay --public-url https://herdr.example.com --password <password>
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
From npm instead: `npm install -g herdr-remote-relay` (it can lag a new release by a while).
|
|
19
|
+
|
|
18
20
|
Requirements: Node.js 22+, TLS reverse proxy (nginx, Caddy, Cloudflare Tunnel).
|
|
19
21
|
|
|
20
22
|
## Docker
|
package/README.zh-CN.md
CHANGED
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
## 安装
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npm install -g herdr-remote-relay
|
|
14
|
+
npm install -g https://github.com/dibin666/herdr-remote/releases/latest/download/herdr-remote-relay.tgz
|
|
15
15
|
herdr-remote-relay --public-url https://herdr.example.com --password <密码>
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
也可从 npm 安装:`npm install -g herdr-remote-relay`(新版本上线后 npm 可能要过一段时间才同步)。
|
|
19
|
+
|
|
18
20
|
前置要求:Node.js 22+、TLS 反向代理(nginx、Caddy、Cloudflare Tunnel 等)。
|
|
19
21
|
|
|
20
22
|
## Docker 运行
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates the Herdr prefix keys crossing the wire, or read from a config
|
|
3
|
+
* file, into one canonical list: lowercase, no whitespace, no duplicates, at
|
|
4
|
+
* most `MAX_HERDR_PREFIX_KEYS` short entries. Herdr ignores entries it cannot
|
|
5
|
+
* read and so does this. `undefined` when nothing usable is left, so a host
|
|
6
|
+
* that says nothing and one that says garbage look the same.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sanitizeHerdrPrefixKeys(value: unknown): string[] | undefined;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// The keys that put the workstation's Herdr into prefix mode, as a host reads
|
|
2
|
+
// them from Herdr's config and a browser receives them. Browser-safe: no Node
|
|
3
|
+
// APIs, so the web app imports it.
|
|
4
|
+
/** Herdr accepts any number of prefix keys; a window has no use for more than this. */
|
|
5
|
+
const MAX_HERDR_PREFIX_KEYS = 8;
|
|
6
|
+
/** Longest real combo is `ctrl+shift+double_quote`; this leaves room for spelling variants. */
|
|
7
|
+
const MAX_HERDR_PREFIX_KEY_LENGTH = 32;
|
|
8
|
+
/**
|
|
9
|
+
* What the browser can act on: a key combo is printable ASCII (modifiers and
|
|
10
|
+
* key names joined by `+`). Whitespace is removed before this is tested.
|
|
11
|
+
*/
|
|
12
|
+
const PREFIX_KEY = /^[\x21-\x7e]+$/;
|
|
13
|
+
/**
|
|
14
|
+
* Validates the Herdr prefix keys crossing the wire, or read from a config
|
|
15
|
+
* file, into one canonical list: lowercase, no whitespace, no duplicates, at
|
|
16
|
+
* most `MAX_HERDR_PREFIX_KEYS` short entries. Herdr ignores entries it cannot
|
|
17
|
+
* read and so does this. `undefined` when nothing usable is left, so a host
|
|
18
|
+
* that says nothing and one that says garbage look the same.
|
|
19
|
+
*/
|
|
20
|
+
export function sanitizeHerdrPrefixKeys(value) {
|
|
21
|
+
if (!Array.isArray(value))
|
|
22
|
+
return undefined;
|
|
23
|
+
const keys = new Set();
|
|
24
|
+
for (const entry of value) {
|
|
25
|
+
if (keys.size >= MAX_HERDR_PREFIX_KEYS)
|
|
26
|
+
break;
|
|
27
|
+
if (typeof entry !== 'string')
|
|
28
|
+
continue;
|
|
29
|
+
const key = entry.replace(/\s+/g, '').toLowerCase();
|
|
30
|
+
if (key.length <= MAX_HERDR_PREFIX_KEY_LENGTH && PREFIX_KEY.test(key))
|
|
31
|
+
keys.add(key);
|
|
32
|
+
}
|
|
33
|
+
return keys.size > 0 ? [...keys] : undefined;
|
|
34
|
+
}
|
package/dist/protocol/index.d.ts
CHANGED
package/dist/protocol/index.js
CHANGED
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
// packages build against; nothing here may be copied into the CLI or the web.
|
|
4
4
|
export * from './frames.js';
|
|
5
5
|
export * from './terminal.js';
|
|
6
|
+
export * from './herdr-keys.js';
|
|
6
7
|
export * from './messages.js';
|
|
7
8
|
export * from './paste.js';
|
|
9
|
+
export * from './release.js';
|
|
@@ -94,6 +94,11 @@ export interface ServerReadyMessage {
|
|
|
94
94
|
clientCount?: number;
|
|
95
95
|
/** The workstation's herdr-remote release; null when it is too old to say. */
|
|
96
96
|
hostVersion?: string | null;
|
|
97
|
+
/**
|
|
98
|
+
* The keys that put the workstation's Herdr into prefix mode, lowercase,
|
|
99
|
+
* like `ctrl+b`. Left out when the host is too old to say.
|
|
100
|
+
*/
|
|
101
|
+
herdrPrefixKeys?: string[];
|
|
97
102
|
}
|
|
98
103
|
export interface ServerPairedMessage {
|
|
99
104
|
type: 'paired';
|
|
@@ -133,6 +138,8 @@ export interface ServerSessionRestartedMessage {
|
|
|
133
138
|
terminalFont?: HostTerminalFont | null;
|
|
134
139
|
/** As in `ready`: the host may have come back on another release. */
|
|
135
140
|
hostVersion?: string | null;
|
|
141
|
+
/** As in `ready`: the host may have come back with another Herdr config. */
|
|
142
|
+
herdrPrefixKeys?: string[];
|
|
136
143
|
}
|
|
137
144
|
export interface ServerExitMessage {
|
|
138
145
|
type: 'exit';
|
|
@@ -239,6 +246,11 @@ export interface HostHelloMessage {
|
|
|
239
246
|
version?: string;
|
|
240
247
|
terminalPalette?: HostTerminalPalette | null;
|
|
241
248
|
terminalFont?: HostTerminalFont | null;
|
|
249
|
+
/**
|
|
250
|
+
* The keys `keys.prefix` in the workstation's Herdr config names, as the
|
|
251
|
+
* host read them. The relay sanitizes them; older connectors leave them out.
|
|
252
|
+
*/
|
|
253
|
+
herdrPrefixKeys?: string[];
|
|
242
254
|
capabilities?: string[];
|
|
243
255
|
}
|
|
244
256
|
/** One PTY the host is running, as the relay's status page lists it. */
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Also the name an update check reports as its source. */
|
|
2
|
+
export declare const GITHUB_RELEASES_URL = "https://github.com/dibin666/herdr-remote/releases";
|
|
3
|
+
/** `{ schema, version, tag, relayVersion, tarball }`, attached to every release. */
|
|
4
|
+
export declare const LATEST_RELEASE_MANIFEST_URL = "https://github.com/dibin666/herdr-remote/releases/latest/download/latest.json";
|
|
5
|
+
/** The newest self-contained CLI tarball, for a workstation that cannot say which it needs. */
|
|
6
|
+
export declare const LATEST_CLI_TARBALL_URL = "https://github.com/dibin666/herdr-remote/releases/latest/download/herdr-remote.tgz";
|
|
7
|
+
/** One CLI release's self-contained tarball; it bundles the relay it was released with. */
|
|
8
|
+
export declare function cliTarballUrl(version: string): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Where herdr-remote is released. The CLI updates from here and the browser
|
|
2
|
+
// shows the same addresses in its manual steps, so there is one definition.
|
|
3
|
+
//
|
|
4
|
+
// GitHub Releases is the primary channel: a release is downloadable the moment
|
|
5
|
+
// it is created, whereas npm can take many minutes after `npm publish` before
|
|
6
|
+
// a new version installs. npm carries the same tarballs as a fallback.
|
|
7
|
+
const RELEASE_REPOSITORY = 'dibin666/herdr-remote';
|
|
8
|
+
/** Also the name an update check reports as its source. */
|
|
9
|
+
export const GITHUB_RELEASES_URL = `https://github.com/${RELEASE_REPOSITORY}/releases`;
|
|
10
|
+
/** `{ schema, version, tag, relayVersion, tarball }`, attached to every release. */
|
|
11
|
+
export const LATEST_RELEASE_MANIFEST_URL = `${GITHUB_RELEASES_URL}/latest/download/latest.json`;
|
|
12
|
+
/** The newest self-contained CLI tarball, for a workstation that cannot say which it needs. */
|
|
13
|
+
export const LATEST_CLI_TARBALL_URL = `${GITHUB_RELEASES_URL}/latest/download/herdr-remote.tgz`;
|
|
14
|
+
/** One CLI release's self-contained tarball; it bundles the relay it was released with. */
|
|
15
|
+
export function cliTarballUrl(version) {
|
|
16
|
+
return `${GITHUB_RELEASES_URL}/download/herdr-remote-v${version}/herdr-remote-${version}.tgz`;
|
|
17
|
+
}
|
|
@@ -148,6 +148,7 @@ export function handleClientConnection(relay, ws, req) {
|
|
|
148
148
|
terminalFont: host.terminalFont || null,
|
|
149
149
|
clientCount: host.clients.size,
|
|
150
150
|
hostVersion: host.version,
|
|
151
|
+
...(host.herdrPrefixKeys ? { herdrPrefixKeys: host.herdrPrefixKeys } : {}),
|
|
151
152
|
});
|
|
152
153
|
if (host.agentStatus)
|
|
153
154
|
jsonSend(ws, host.agentStatus);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// The host side of the relay: a workstation's WebSocket, from its hello and
|
|
2
2
|
// the hand-off from an older connection to every message it sends after.
|
|
3
3
|
import os from 'node:os';
|
|
4
|
-
import { CAPABILITY, PROTOCOL_VERSION, sanitizeTerminalFont, sanitizeTerminalPalette, unpackStreamFrame, } from '../protocol/index.js';
|
|
4
|
+
import { CAPABILITY, PROTOCOL_VERSION, sanitizeHerdrPrefixKeys, sanitizeTerminalFont, sanitizeTerminalPalette, unpackStreamFrame, } from '../protocol/index.js';
|
|
5
5
|
import { forwardFontChunk, forwardFontSubset, settleFontChunk, settleFontSubset, } from './font-proxy.js';
|
|
6
6
|
import { broadcastAgentStatus, broadcastTerminalFont, broadcastUpdateStatus, releaseVersion, } from './host-broadcasts.js';
|
|
7
7
|
import { allowHostHandshake } from './requests.js';
|
|
@@ -10,6 +10,7 @@ import { closeSocket, isOpen, jsonSend, parseJson, randomId, rejectHandshake } f
|
|
|
10
10
|
import { broadcastToClients, notifyHostClientCount, sendClientBinary } from './transport.js';
|
|
11
11
|
function createHostRecord(message, ws, pending, clients = new Set()) {
|
|
12
12
|
const capabilities = Array.isArray(message.capabilities) ? message.capabilities : [];
|
|
13
|
+
const herdrPrefixKeys = sanitizeHerdrPrefixKeys(message.herdrPrefixKeys);
|
|
13
14
|
return {
|
|
14
15
|
id: message.hostId,
|
|
15
16
|
ws,
|
|
@@ -23,6 +24,7 @@ function createHostRecord(message, ws, pending, clients = new Set()) {
|
|
|
23
24
|
terminalPalette: sanitizeTerminalPalette(message.terminalPalette),
|
|
24
25
|
/** Family, size and fetchable files of the workstation's terminal font. */
|
|
25
26
|
terminalFont: sanitizeTerminalFont(message.terminalFont),
|
|
27
|
+
...(herdrPrefixKeys ? { herdrPrefixKeys } : {}),
|
|
26
28
|
/** The latest workstation snapshot is replayed when a browser joins late. */
|
|
27
29
|
agentStatus: null,
|
|
28
30
|
/** Whether the workstation's herdr-remote is behind; replayed the same way. */
|
package/dist/server/sessions.js
CHANGED
|
@@ -72,6 +72,7 @@ export function startSession(relay, host, client, { restarted = false } = {}) {
|
|
|
72
72
|
terminalPalette: host.terminalPalette || null,
|
|
73
73
|
terminalFont: host.terminalFont || null,
|
|
74
74
|
hostVersion: host.version,
|
|
75
|
+
...(host.herdrPrefixKeys ? { herdrPrefixKeys: host.herdrPrefixKeys } : {}),
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
78
|
}
|
package/dist/server/types.d.ts
CHANGED
|
@@ -31,6 +31,8 @@ export interface RelayHost {
|
|
|
31
31
|
connectedAtMs: number;
|
|
32
32
|
terminalPalette: HostTerminalPalette | null;
|
|
33
33
|
terminalFont: HostTerminalFont | null;
|
|
34
|
+
/** Sanitized `keys.prefix` of the host's Herdr; absent when the host did not say. */
|
|
35
|
+
herdrPrefixKeys?: string[];
|
|
34
36
|
/** The latest agent summary, replayed to a window that joins late. */
|
|
35
37
|
agentStatus: ServerAgentStatusMessage | null;
|
|
36
38
|
/** Whether the workstation's herdr-remote is behind; replayed the same way. */
|