terminay 4.2.0
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/account.d.ts +31 -0
- package/dist/account.js +150 -0
- package/dist/account.js.map +1 -0
- package/dist/address.d.ts +14 -0
- package/dist/address.js +58 -0
- package/dist/address.js.map +1 -0
- package/dist/args.d.ts +37 -0
- package/dist/args.js +252 -0
- package/dist/args.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +92 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/install.d.ts +48 -0
- package/dist/commands/install.js +213 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/lifecycle.d.ts +23 -0
- package/dist/commands/lifecycle.js +66 -0
- package/dist/commands/lifecycle.js.map +1 -0
- package/dist/commands/pairing.d.ts +23 -0
- package/dist/commands/pairing.js +143 -0
- package/dist/commands/pairing.js.map +1 -0
- package/dist/commands/uninstall.d.ts +26 -0
- package/dist/commands/uninstall.js +70 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/upgrade.d.ts +30 -0
- package/dist/commands/upgrade.js +175 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/context.d.ts +26 -0
- package/dist/context.js +37 -0
- package/dist/context.js.map +1 -0
- package/dist/download.d.ts +11 -0
- package/dist/download.js +95 -0
- package/dist/download.js.map +1 -0
- package/dist/health.d.ts +18 -0
- package/dist/health.js +61 -0
- package/dist/health.js.map +1 -0
- package/dist/http.d.ts +11 -0
- package/dist/http.js +88 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +30 -0
- package/dist/install.js +100 -0
- package/dist/install.js.map +1 -0
- package/dist/layout.d.ts +52 -0
- package/dist/layout.js +96 -0
- package/dist/layout.js.map +1 -0
- package/dist/manifest.d.ts +46 -0
- package/dist/manifest.js +115 -0
- package/dist/manifest.js.map +1 -0
- package/dist/platform.d.ts +17 -0
- package/dist/platform.js +34 -0
- package/dist/platform.js.map +1 -0
- package/dist/prompt.d.ts +20 -0
- package/dist/prompt.js +47 -0
- package/dist/prompt.js.map +1 -0
- package/dist/resolve.d.ts +35 -0
- package/dist/resolve.js +194 -0
- package/dist/resolve.js.map +1 -0
- package/dist/socket.d.ts +55 -0
- package/dist/socket.js +98 -0
- package/dist/socket.js.map +1 -0
- package/dist/socketClient.d.ts +1 -0
- package/dist/socketClient.js +22 -0
- package/dist/socketClient.js.map +1 -0
- package/dist/source.d.ts +24 -0
- package/dist/source.js +152 -0
- package/dist/source.js.map +1 -0
- package/dist/systemd.d.ts +30 -0
- package/dist/systemd.js +86 -0
- package/dist/systemd.js.map +1 -0
- package/dist/unit.d.ts +37 -0
- package/dist/unit.js +74 -0
- package/dist/unit.js.map +1 -0
- package/dist/verify.d.ts +24 -0
- package/dist/verify.js +46 -0
- package/dist/verify.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { InstallScope } from './args.js';
|
|
2
|
+
import { type PromptStreams } from './prompt.js';
|
|
3
|
+
export declare const DEDICATED_ACCOUNT = "terminay";
|
|
4
|
+
export declare const DEDICATED_HOME = "/var/lib/terminay";
|
|
5
|
+
export declare class ScopeError extends Error {
|
|
6
|
+
}
|
|
7
|
+
export interface ScopeSelection {
|
|
8
|
+
readonly scope: InstallScope;
|
|
9
|
+
readonly runAs: string;
|
|
10
|
+
readonly home: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Who is running this. `USER` is absent more often than it looks — a systemd
|
|
14
|
+
* user session, a container, a cron job, and `sudo -u` all commonly have no
|
|
15
|
+
* `USER` in the environment — so the passwd database is the authority and the
|
|
16
|
+
* environment is only a hint.
|
|
17
|
+
*/
|
|
18
|
+
export declare function invokingUser(): string | undefined;
|
|
19
|
+
export declare function selectScope(options: {
|
|
20
|
+
readonly requested?: InstallScope;
|
|
21
|
+
readonly streams?: PromptStreams;
|
|
22
|
+
}): Promise<InstallScope>;
|
|
23
|
+
export declare function assertRootForSystemScope(command: string, uid?: number | undefined): void;
|
|
24
|
+
export declare function selectRunAs(options: {
|
|
25
|
+
readonly scope: InstallScope;
|
|
26
|
+
readonly requested?: string;
|
|
27
|
+
readonly streams?: PromptStreams;
|
|
28
|
+
readonly currentUser?: string;
|
|
29
|
+
}): Promise<ScopeSelection>;
|
|
30
|
+
/** The data root is the trust boundary, so it is owner-only from the start. */
|
|
31
|
+
export declare function prepareDataRoot(dataRoot: string, runAs: string, scope: InstallScope): Promise<void>;
|
package/dist/account.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { chmod, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { userInfo } from 'node:os';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
import { choose, defaultStreams, isInteractive, } from './prompt.js';
|
|
6
|
+
/**
|
|
7
|
+
* Choosing the scope of an install and the account the server runs as.
|
|
8
|
+
*
|
|
9
|
+
* The run-as account is the security decision in this whole command: the
|
|
10
|
+
* daemon's terminals run as that user, so the choice decides whose files,
|
|
11
|
+
* keys, and SSH agent the server can reach. The prompt says so, the dedicated
|
|
12
|
+
* account is preselected, and naming a login user is deliberate rather than
|
|
13
|
+
* incidental.
|
|
14
|
+
*/
|
|
15
|
+
const execFileAsync = promisify(execFile);
|
|
16
|
+
export const DEDICATED_ACCOUNT = 'terminay';
|
|
17
|
+
export const DEDICATED_HOME = '/var/lib/terminay';
|
|
18
|
+
const USER_NAME = /^[a-z_][a-z0-9_-]{0,31}$/u;
|
|
19
|
+
export class ScopeError extends Error {
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Who is running this. `USER` is absent more often than it looks — a systemd
|
|
23
|
+
* user session, a container, a cron job, and `sudo -u` all commonly have no
|
|
24
|
+
* `USER` in the environment — so the passwd database is the authority and the
|
|
25
|
+
* environment is only a hint.
|
|
26
|
+
*/
|
|
27
|
+
export function invokingUser() {
|
|
28
|
+
const named = process.env.USER ?? process.env.LOGNAME;
|
|
29
|
+
if (typeof named === 'string' && named.length > 0)
|
|
30
|
+
return named;
|
|
31
|
+
try {
|
|
32
|
+
const name = userInfo().username;
|
|
33
|
+
return typeof name === 'string' && name.length > 0 ? name : undefined;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function selectScope(options) {
|
|
40
|
+
if (options.requested !== undefined)
|
|
41
|
+
return options.requested;
|
|
42
|
+
const streams = options.streams ?? defaultStreams();
|
|
43
|
+
if (!isInteractive(streams)) {
|
|
44
|
+
throw new ScopeError('no terminal is attached, so the install scope cannot be asked for. Pass --system for a system service or --user for a service owned by your login.');
|
|
45
|
+
}
|
|
46
|
+
return choose('Install Terminay Server for the whole machine, or just for your login?', [
|
|
47
|
+
['system', 'System-wide service, started at boot (needs root)'],
|
|
48
|
+
['user', 'User service, running as you and started when you log in'],
|
|
49
|
+
], streams);
|
|
50
|
+
}
|
|
51
|
+
export function assertRootForSystemScope(command, uid = process.getuid?.()) {
|
|
52
|
+
if (uid === 0)
|
|
53
|
+
return;
|
|
54
|
+
throw new ScopeError(`a system-wide install writes to /etc and /opt, so it needs root. Re-run it as: sudo ${command}`);
|
|
55
|
+
}
|
|
56
|
+
async function userExists(name) {
|
|
57
|
+
try {
|
|
58
|
+
await execFileAsync('id', ['-u', name], { timeout: 30_000 });
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function homeOf(name) {
|
|
66
|
+
try {
|
|
67
|
+
const { stdout } = await execFileAsync('getent', ['passwd', name], {
|
|
68
|
+
timeout: 30_000,
|
|
69
|
+
});
|
|
70
|
+
const home = stdout.split('\n')[0]?.split(':')[5];
|
|
71
|
+
return home !== undefined && home.length > 0 ? home : undefined;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function createDedicatedAccount() {
|
|
78
|
+
await execFileAsync('useradd', [
|
|
79
|
+
'--system',
|
|
80
|
+
'--home-dir',
|
|
81
|
+
DEDICATED_HOME,
|
|
82
|
+
'--create-home',
|
|
83
|
+
'--shell',
|
|
84
|
+
'/usr/sbin/nologin',
|
|
85
|
+
DEDICATED_ACCOUNT,
|
|
86
|
+
], { timeout: 60_000 });
|
|
87
|
+
}
|
|
88
|
+
export async function selectRunAs(options) {
|
|
89
|
+
if (options.scope === 'user') {
|
|
90
|
+
const user = options.currentUser ?? invokingUser();
|
|
91
|
+
if (user === undefined || user.length === 0)
|
|
92
|
+
throw new ScopeError('the invoking user could not be determined');
|
|
93
|
+
if (options.requested !== undefined && options.requested !== user) {
|
|
94
|
+
throw new ScopeError('--run-as cannot be used with a user-scope install: the service always runs as you.');
|
|
95
|
+
}
|
|
96
|
+
const home = (await homeOf(user)) ?? process.env.HOME;
|
|
97
|
+
if (home === undefined)
|
|
98
|
+
throw new ScopeError(`the home directory of ${user} could not be determined`);
|
|
99
|
+
return Object.freeze({ scope: options.scope, runAs: user, home });
|
|
100
|
+
}
|
|
101
|
+
if (options.requested !== undefined) {
|
|
102
|
+
if (!USER_NAME.test(options.requested))
|
|
103
|
+
throw new ScopeError(`--run-as is not a valid account name: ${options.requested}`);
|
|
104
|
+
// Checked before anything is written, so a typo does not leave a
|
|
105
|
+
// half-installed service behind.
|
|
106
|
+
if (!(await userExists(options.requested))) {
|
|
107
|
+
throw new ScopeError(`--run-as names an account that does not exist on this machine: ${options.requested}`);
|
|
108
|
+
}
|
|
109
|
+
const home = await homeOf(options.requested);
|
|
110
|
+
if (home === undefined)
|
|
111
|
+
throw new ScopeError(`the home directory of ${options.requested} could not be determined`);
|
|
112
|
+
return Object.freeze({
|
|
113
|
+
scope: options.scope,
|
|
114
|
+
runAs: options.requested,
|
|
115
|
+
home,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
const streams = options.streams ?? defaultStreams();
|
|
119
|
+
let choice = 'dedicated';
|
|
120
|
+
if (isInteractive(streams)) {
|
|
121
|
+
choice = await choose('Which account should the server and its terminals run as?\nThis decides whose files, keys, and agents a paired device can reach.', [
|
|
122
|
+
[
|
|
123
|
+
'dedicated',
|
|
124
|
+
`A dedicated \`${DEDICATED_ACCOUNT}\` account with its own home (recommended)`,
|
|
125
|
+
],
|
|
126
|
+
['login', 'An existing login user, named with --run-as'],
|
|
127
|
+
], streams);
|
|
128
|
+
}
|
|
129
|
+
if (choice === 'login') {
|
|
130
|
+
throw new ScopeError('re-run the install with --run-as <user> to name the login account the server should run as.');
|
|
131
|
+
}
|
|
132
|
+
if (!(await userExists(DEDICATED_ACCOUNT)))
|
|
133
|
+
await createDedicatedAccount();
|
|
134
|
+
return Object.freeze({
|
|
135
|
+
scope: options.scope,
|
|
136
|
+
runAs: DEDICATED_ACCOUNT,
|
|
137
|
+
home: DEDICATED_HOME,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** The data root is the trust boundary, so it is owner-only from the start. */
|
|
141
|
+
export async function prepareDataRoot(dataRoot, runAs, scope) {
|
|
142
|
+
await mkdir(dataRoot, { recursive: true, mode: 0o700 });
|
|
143
|
+
await chmod(dataRoot, 0o700);
|
|
144
|
+
if (scope !== 'system')
|
|
145
|
+
return;
|
|
146
|
+
await execFileAsync('chown', ['-R', `${runAs}:${runAs}`, dataRoot], {
|
|
147
|
+
timeout: 60_000,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Narrowed to what the probe uses, so a test can supply its own. */
|
|
2
|
+
export interface ProbeSocket {
|
|
3
|
+
on(event: 'error', handler: (error: Error) => void): unknown;
|
|
4
|
+
connect(port: number, address: string, callback: () => void): unknown;
|
|
5
|
+
address(): {
|
|
6
|
+
address: string;
|
|
7
|
+
};
|
|
8
|
+
close(): unknown;
|
|
9
|
+
}
|
|
10
|
+
export type ProbeSocketFactory = () => ProbeSocket;
|
|
11
|
+
export declare function primaryAddress(createProbeSocket?: ProbeSocketFactory): Promise<string | undefined>;
|
|
12
|
+
/** Bracket an IPv6 literal so the result is a usable origin. */
|
|
13
|
+
export declare function originFor(address: string, port: number): string;
|
|
14
|
+
export declare function defaultDirectOrigin(port: number, createProbeSocket?: ProbeSocketFactory): Promise<string | undefined>;
|
package/dist/address.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createSocket } from 'node:dgram';
|
|
2
|
+
/**
|
|
3
|
+
* Guessing the address devices will actually reach this machine on.
|
|
4
|
+
*
|
|
5
|
+
* A UDP socket "connected" to a public address picks the source address the
|
|
6
|
+
* routing table would use, without sending a packet. That is right for a box
|
|
7
|
+
* with a routable address and wrong for one behind NAT, which is why the
|
|
8
|
+
* derived origin is printed at install and `--direct-origin` is documented
|
|
9
|
+
* next to it.
|
|
10
|
+
*/
|
|
11
|
+
const PROBE_ADDRESS = '203.0.113.1';
|
|
12
|
+
const PROBE_PORT = 33_333;
|
|
13
|
+
const openProbeSocket = () => createSocket('udp4');
|
|
14
|
+
export function primaryAddress(createProbeSocket = openProbeSocket) {
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
let socket;
|
|
17
|
+
try {
|
|
18
|
+
socket = createProbeSocket();
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
resolve(undefined);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const finish = (value) => {
|
|
25
|
+
try {
|
|
26
|
+
socket.close();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Already closed.
|
|
30
|
+
}
|
|
31
|
+
resolve(value);
|
|
32
|
+
};
|
|
33
|
+
socket.on('error', () => finish(undefined));
|
|
34
|
+
try {
|
|
35
|
+
socket.connect(PROBE_PORT, PROBE_ADDRESS, () => {
|
|
36
|
+
try {
|
|
37
|
+
finish(socket.address().address);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
finish(undefined);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
finish(undefined);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Bracket an IPv6 literal so the result is a usable origin. */
|
|
50
|
+
export function originFor(address, port) {
|
|
51
|
+
const host = address.includes(':') ? `[${address}]` : address;
|
|
52
|
+
return `https://${host}:${port}`;
|
|
53
|
+
}
|
|
54
|
+
export async function defaultDirectOrigin(port, createProbeSocket = openProbeSocket) {
|
|
55
|
+
const address = await primaryAddress(createProbeSocket);
|
|
56
|
+
return address === undefined ? undefined : originFor(address, port);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;GAQG;AAEH,MAAM,aAAa,GAAG,aAAa,CAAC;AACpC,MAAM,UAAU,GAAG,MAAM,CAAC;AAY1B,MAAM,eAAe,GAAuB,GAAG,EAAE,CAChD,YAAY,CAAC,MAAM,CAA2B,CAAC;AAEhD,MAAM,UAAU,cAAc,CAC7B,oBAAwC,eAAe;IAEvD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,IAAI,MAAmB,CAAC;QACxB,IAAI,CAAC;YACJ,MAAM,GAAG,iBAAiB,EAAE,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,CAAC,SAAS,CAAC,CAAC;YACnB,OAAO;QACR,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,KAAyB,EAAE,EAAE;YAC5C,IAAI,CAAC;gBACJ,MAAM,CAAC,KAAK,EAAE,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACR,kBAAkB;YACnB,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC;QACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC;YACJ,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE;gBAC9C,IAAI,CAAC;oBACJ,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;gBAClC,CAAC;gBAAC,MAAM,CAAC;oBACR,MAAM,CAAC,SAAS,CAAC,CAAC;gBACnB,CAAC;YACF,CAAC,CAAC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,CAAC,SAAS,CAAC,CAAC;QACnB,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,IAAY;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9D,OAAO,WAAW,IAAI,IAAI,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,IAAY,EACZ,oBAAwC,eAAe;IAEvD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,CAAC;IACxD,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACrE,CAAC"}
|
package/dist/args.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argument parsing for the `terminay` binary.
|
|
3
|
+
*
|
|
4
|
+
* The parser is strict on purpose: an operator typing an install command as
|
|
5
|
+
* root should be told a flag is unknown rather than have it silently ignored,
|
|
6
|
+
* because the ignored flag might have been the one choosing the account the
|
|
7
|
+
* daemon's terminals run as.
|
|
8
|
+
*/
|
|
9
|
+
export type DaemonCommand = 'install' | 'uninstall' | 'start' | 'stop' | 'status' | 'upgrade' | 'qr-code' | 'approvals' | 'approve' | 'deny' | 'reset-identity';
|
|
10
|
+
export type InstallScope = 'system' | 'user';
|
|
11
|
+
export type PairingMode = 'hosted' | 'direct';
|
|
12
|
+
export interface DaemonOptions {
|
|
13
|
+
readonly scope?: InstallScope;
|
|
14
|
+
readonly runAs?: string;
|
|
15
|
+
readonly port?: number;
|
|
16
|
+
readonly directOrigin?: string;
|
|
17
|
+
readonly hostedDomain?: string;
|
|
18
|
+
readonly expose?: string;
|
|
19
|
+
readonly projectRoot?: string;
|
|
20
|
+
readonly allowDowngrade: boolean;
|
|
21
|
+
readonly purge: boolean;
|
|
22
|
+
readonly yes: boolean;
|
|
23
|
+
readonly wait: boolean;
|
|
24
|
+
readonly mode?: PairingMode;
|
|
25
|
+
}
|
|
26
|
+
export interface ParsedCommandLine {
|
|
27
|
+
readonly command: DaemonCommand | 'help';
|
|
28
|
+
/** `install` and `upgrade` take an optional version reference. */
|
|
29
|
+
readonly ref?: string;
|
|
30
|
+
/** `approve` and `deny` take a required approval id. */
|
|
31
|
+
readonly approvalId?: string;
|
|
32
|
+
readonly options: DaemonOptions;
|
|
33
|
+
}
|
|
34
|
+
export declare class UsageError extends Error {
|
|
35
|
+
}
|
|
36
|
+
export declare function parseCommandLine(argv: readonly string[]): ParsedCommandLine;
|
|
37
|
+
export declare const HELP_TEXT = "terminay \u2014 install and control a headless Terminay Server\n\nUsage:\n npx terminay daemon <command> [arguments] [flags]\n\nCommands:\n install [ref] Install and start the server. `ref` is a tag such as\n v4.1.1, `main` for the rolling channel, or a branch or\n commit to build from source. Defaults to the latest tag.\n upgrade [ref] Upgrade, following the installed channel by default.\n uninstall Stop and remove the service and installed versions.\n start | stop Start or stop the service.\n status Report unit state, version, channel, and exposure.\n qr-code Show a scannable pairing code and approve the device\n that scans it. Alias: pairing-url.\n approvals List pending device approvals.\n approve <id> Approve a pending device.\n deny <id> Deny a pending device.\n reset-identity Rotate the host key and revoke every paired device.\n\nFlags:\n --system, --user Install scope. Prompted when a terminal is attached.\n --run-as <user> Account the server and its terminals run as.\n --port <port> Port the server listens on.\n --direct-origin <o> Origin devices reach directly, such as\n https://box.example.com:8443.\n --hosted-domain <d> Hosted signalling domain.\n --expose <modes> off, hosted, direct, or hosted,direct.\n --project-root <p> Directory the server opens projects from.\n --allow-downgrade Permit upgrade to an older version.\n --purge Also remove the data root on uninstall.\n --yes Skip confirmation prompts.\n --no-wait Print pairing URLs and exit without waiting.\n --mode <m> Render the hosted or direct pairing URL.\n --help Show this help.\n";
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Argument parsing for the `terminay` binary.
|
|
3
|
+
*
|
|
4
|
+
* The parser is strict on purpose: an operator typing an install command as
|
|
5
|
+
* root should be told a flag is unknown rather than have it silently ignored,
|
|
6
|
+
* because the ignored flag might have been the one choosing the account the
|
|
7
|
+
* daemon's terminals run as.
|
|
8
|
+
*/
|
|
9
|
+
const COMMANDS = [
|
|
10
|
+
'install',
|
|
11
|
+
'uninstall',
|
|
12
|
+
'start',
|
|
13
|
+
'stop',
|
|
14
|
+
'status',
|
|
15
|
+
'upgrade',
|
|
16
|
+
'qr-code',
|
|
17
|
+
'approvals',
|
|
18
|
+
'approve',
|
|
19
|
+
'deny',
|
|
20
|
+
'reset-identity',
|
|
21
|
+
];
|
|
22
|
+
/** `pairing-url` is the descriptive name; `qr-code` is what it renders. */
|
|
23
|
+
const ALIASES = Object.freeze({
|
|
24
|
+
'pairing-url': 'qr-code',
|
|
25
|
+
});
|
|
26
|
+
const VALUE_FLAGS = Object.freeze([
|
|
27
|
+
'--run-as',
|
|
28
|
+
'--port',
|
|
29
|
+
'--direct-origin',
|
|
30
|
+
'--hosted-domain',
|
|
31
|
+
'--expose',
|
|
32
|
+
'--project-root',
|
|
33
|
+
'--mode',
|
|
34
|
+
]);
|
|
35
|
+
const BOOLEAN_FLAGS = Object.freeze([
|
|
36
|
+
'--system',
|
|
37
|
+
'--user',
|
|
38
|
+
'--allow-downgrade',
|
|
39
|
+
'--purge',
|
|
40
|
+
'--yes',
|
|
41
|
+
'--no-wait',
|
|
42
|
+
]);
|
|
43
|
+
/**
|
|
44
|
+
* Which flags each command accepts. A flag that does nothing for a command is
|
|
45
|
+
* rejected rather than accepted and dropped, so `upgrade --purge` cannot read
|
|
46
|
+
* as though it were understood.
|
|
47
|
+
*/
|
|
48
|
+
const ACCEPTED = Object.freeze({
|
|
49
|
+
install: [
|
|
50
|
+
'--system',
|
|
51
|
+
'--user',
|
|
52
|
+
'--run-as',
|
|
53
|
+
'--port',
|
|
54
|
+
'--direct-origin',
|
|
55
|
+
'--hosted-domain',
|
|
56
|
+
'--expose',
|
|
57
|
+
'--project-root',
|
|
58
|
+
],
|
|
59
|
+
upgrade: ['--system', '--user', '--allow-downgrade'],
|
|
60
|
+
uninstall: ['--system', '--user', '--purge', '--yes'],
|
|
61
|
+
start: ['--system', '--user'],
|
|
62
|
+
stop: ['--system', '--user'],
|
|
63
|
+
status: ['--system', '--user'],
|
|
64
|
+
'qr-code': ['--system', '--user', '--no-wait', '--mode'],
|
|
65
|
+
approvals: ['--system', '--user'],
|
|
66
|
+
approve: ['--system', '--user'],
|
|
67
|
+
deny: ['--system', '--user'],
|
|
68
|
+
'reset-identity': ['--system', '--user', '--yes'],
|
|
69
|
+
});
|
|
70
|
+
const REF_COMMANDS = ['install', 'upgrade'];
|
|
71
|
+
const APPROVAL_ID_COMMANDS = ['approve', 'deny'];
|
|
72
|
+
const APPROVAL_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
73
|
+
export class UsageError extends Error {
|
|
74
|
+
}
|
|
75
|
+
function fail(message) {
|
|
76
|
+
throw new UsageError(message);
|
|
77
|
+
}
|
|
78
|
+
function parsePort(raw) {
|
|
79
|
+
if (!/^\d{1,5}$/u.test(raw))
|
|
80
|
+
fail('--port must be a whole number between 1 and 65535');
|
|
81
|
+
const port = Number(raw);
|
|
82
|
+
if (port < 1 || port > 65535)
|
|
83
|
+
fail('--port must be a whole number between 1 and 65535');
|
|
84
|
+
return port;
|
|
85
|
+
}
|
|
86
|
+
function parseMode(raw) {
|
|
87
|
+
if (raw !== 'hosted' && raw !== 'direct')
|
|
88
|
+
fail('--mode must be hosted or direct');
|
|
89
|
+
return raw;
|
|
90
|
+
}
|
|
91
|
+
export function parseCommandLine(argv) {
|
|
92
|
+
const noOptions = Object.freeze({
|
|
93
|
+
allowDowngrade: false,
|
|
94
|
+
purge: false,
|
|
95
|
+
yes: false,
|
|
96
|
+
wait: true,
|
|
97
|
+
});
|
|
98
|
+
if (argv.length === 0 || argv[0] === '--help' || argv[0] === 'help') {
|
|
99
|
+
return Object.freeze({ command: 'help', options: noOptions });
|
|
100
|
+
}
|
|
101
|
+
if (argv[0] !== 'daemon')
|
|
102
|
+
fail(`unknown command: ${argv[0]}. The only command group is \`daemon\`.`);
|
|
103
|
+
const rest = argv.slice(1);
|
|
104
|
+
if (rest.length === 0)
|
|
105
|
+
return Object.freeze({ command: 'help', options: noOptions });
|
|
106
|
+
if (rest.includes('--help'))
|
|
107
|
+
return Object.freeze({ command: 'help', options: noOptions });
|
|
108
|
+
const requested = rest[0];
|
|
109
|
+
const command = ALIASES[requested] ??
|
|
110
|
+
(COMMANDS.includes(requested)
|
|
111
|
+
? requested
|
|
112
|
+
: undefined);
|
|
113
|
+
if (command === undefined) {
|
|
114
|
+
fail(`unknown daemon command: ${requested}. Expected one of: ${[...COMMANDS, ...Object.keys(ALIASES)].join(', ')}.`);
|
|
115
|
+
}
|
|
116
|
+
const accepted = ACCEPTED[command];
|
|
117
|
+
const positional = [];
|
|
118
|
+
const values = new Map();
|
|
119
|
+
const booleans = new Set();
|
|
120
|
+
for (let index = 1; index < rest.length; index += 1) {
|
|
121
|
+
const token = rest[index];
|
|
122
|
+
if (!token.startsWith('-')) {
|
|
123
|
+
positional.push(token);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const equals = token.indexOf('=');
|
|
127
|
+
const name = equals < 0 ? token : token.slice(0, equals);
|
|
128
|
+
if (VALUE_FLAGS.includes(name)) {
|
|
129
|
+
if (!accepted.includes(name))
|
|
130
|
+
fail(`${name} is not accepted by \`daemon ${command}\``);
|
|
131
|
+
let value;
|
|
132
|
+
if (equals >= 0) {
|
|
133
|
+
value = token.slice(equals + 1);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
const next = rest[index + 1];
|
|
137
|
+
if (next === undefined || next.startsWith('-'))
|
|
138
|
+
fail(`${name} requires a value`);
|
|
139
|
+
value = next;
|
|
140
|
+
index += 1;
|
|
141
|
+
}
|
|
142
|
+
if (value.length === 0)
|
|
143
|
+
fail(`${name} requires a value`);
|
|
144
|
+
if (values.has(name))
|
|
145
|
+
fail(`${name} was given more than once`);
|
|
146
|
+
values.set(name, value);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (BOOLEAN_FLAGS.includes(name)) {
|
|
150
|
+
if (equals >= 0)
|
|
151
|
+
fail(`${name} does not take a value`);
|
|
152
|
+
if (!accepted.includes(name))
|
|
153
|
+
fail(`${name} is not accepted by \`daemon ${command}\``);
|
|
154
|
+
booleans.add(name);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
fail(`unknown flag: ${name}`);
|
|
158
|
+
}
|
|
159
|
+
if (booleans.has('--system') && booleans.has('--user'))
|
|
160
|
+
fail('--system and --user cannot both be given');
|
|
161
|
+
let ref;
|
|
162
|
+
let approvalId;
|
|
163
|
+
if (REF_COMMANDS.includes(command)) {
|
|
164
|
+
if (positional.length > 1)
|
|
165
|
+
fail(`\`daemon ${command}\` takes at most one version reference`);
|
|
166
|
+
ref = positional[0];
|
|
167
|
+
}
|
|
168
|
+
else if (APPROVAL_ID_COMMANDS.includes(command)) {
|
|
169
|
+
if (positional.length !== 1)
|
|
170
|
+
fail(`\`daemon ${command}\` requires exactly one approval id`);
|
|
171
|
+
approvalId = positional[0];
|
|
172
|
+
if (!APPROVAL_ID.test(approvalId))
|
|
173
|
+
fail('approval id is not a valid identifier');
|
|
174
|
+
}
|
|
175
|
+
else if (positional.length > 0) {
|
|
176
|
+
fail(`\`daemon ${command}\` takes no arguments`);
|
|
177
|
+
}
|
|
178
|
+
const port = values.get('--port');
|
|
179
|
+
const mode = values.get('--mode');
|
|
180
|
+
const scope = booleans.has('--system')
|
|
181
|
+
? 'system'
|
|
182
|
+
: booleans.has('--user')
|
|
183
|
+
? 'user'
|
|
184
|
+
: undefined;
|
|
185
|
+
const options = Object.freeze({
|
|
186
|
+
...(scope === undefined ? {} : { scope }),
|
|
187
|
+
...(values.has('--run-as')
|
|
188
|
+
? { runAs: values.get('--run-as') }
|
|
189
|
+
: {}),
|
|
190
|
+
...(port === undefined ? {} : { port: parsePort(port) }),
|
|
191
|
+
...(values.has('--direct-origin')
|
|
192
|
+
? { directOrigin: values.get('--direct-origin') }
|
|
193
|
+
: {}),
|
|
194
|
+
...(values.has('--hosted-domain')
|
|
195
|
+
? { hostedDomain: values.get('--hosted-domain') }
|
|
196
|
+
: {}),
|
|
197
|
+
...(values.has('--expose')
|
|
198
|
+
? { expose: values.get('--expose') }
|
|
199
|
+
: {}),
|
|
200
|
+
...(values.has('--project-root')
|
|
201
|
+
? { projectRoot: values.get('--project-root') }
|
|
202
|
+
: {}),
|
|
203
|
+
allowDowngrade: booleans.has('--allow-downgrade'),
|
|
204
|
+
purge: booleans.has('--purge'),
|
|
205
|
+
yes: booleans.has('--yes'),
|
|
206
|
+
wait: !booleans.has('--no-wait'),
|
|
207
|
+
...(mode === undefined ? {} : { mode: parseMode(mode) }),
|
|
208
|
+
});
|
|
209
|
+
return Object.freeze({
|
|
210
|
+
command,
|
|
211
|
+
...(ref === undefined ? {} : { ref }),
|
|
212
|
+
...(approvalId === undefined ? {} : { approvalId }),
|
|
213
|
+
options,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
export const HELP_TEXT = `terminay — install and control a headless Terminay Server
|
|
217
|
+
|
|
218
|
+
Usage:
|
|
219
|
+
npx terminay daemon <command> [arguments] [flags]
|
|
220
|
+
|
|
221
|
+
Commands:
|
|
222
|
+
install [ref] Install and start the server. \`ref\` is a tag such as
|
|
223
|
+
v4.1.1, \`main\` for the rolling channel, or a branch or
|
|
224
|
+
commit to build from source. Defaults to the latest tag.
|
|
225
|
+
upgrade [ref] Upgrade, following the installed channel by default.
|
|
226
|
+
uninstall Stop and remove the service and installed versions.
|
|
227
|
+
start | stop Start or stop the service.
|
|
228
|
+
status Report unit state, version, channel, and exposure.
|
|
229
|
+
qr-code Show a scannable pairing code and approve the device
|
|
230
|
+
that scans it. Alias: pairing-url.
|
|
231
|
+
approvals List pending device approvals.
|
|
232
|
+
approve <id> Approve a pending device.
|
|
233
|
+
deny <id> Deny a pending device.
|
|
234
|
+
reset-identity Rotate the host key and revoke every paired device.
|
|
235
|
+
|
|
236
|
+
Flags:
|
|
237
|
+
--system, --user Install scope. Prompted when a terminal is attached.
|
|
238
|
+
--run-as <user> Account the server and its terminals run as.
|
|
239
|
+
--port <port> Port the server listens on.
|
|
240
|
+
--direct-origin <o> Origin devices reach directly, such as
|
|
241
|
+
https://box.example.com:8443.
|
|
242
|
+
--hosted-domain <d> Hosted signalling domain.
|
|
243
|
+
--expose <modes> off, hosted, direct, or hosted,direct.
|
|
244
|
+
--project-root <p> Directory the server opens projects from.
|
|
245
|
+
--allow-downgrade Permit upgrade to an older version.
|
|
246
|
+
--purge Also remove the data root on uninstall.
|
|
247
|
+
--yes Skip confirmation prompts.
|
|
248
|
+
--no-wait Print pairing URLs and exit without waiting.
|
|
249
|
+
--mode <m> Render the hosted or direct pairing URL.
|
|
250
|
+
--help Show this help.
|
|
251
|
+
`;
|
|
252
|
+
//# sourceMappingURL=args.js.map
|
package/dist/args.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED