tunli 0.2.0 → 0.3.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/CHANGELOG.md +20 -0
- package/README.md +39 -0
- package/dist/client.js +6 -0
- package/dist/client.js.map +1 -1
- package/dist/commands/CommandConnect/CommandConnect.d.ts +4 -0
- package/dist/commands/CommandConnect/CommandConnect.d.ts.map +1 -0
- package/dist/commands/CommandConnect/CommandConnect.js +51 -0
- package/dist/commands/CommandConnect/CommandConnect.js.map +1 -0
- package/dist/commands/CommandHTTP/CommandHttp.d.ts.map +1 -1
- package/dist/commands/CommandHTTP/CommandHttp.js +20 -1
- package/dist/commands/CommandHTTP/CommandHttp.js.map +1 -1
- package/dist/commands/CommandIdentity/CommandIdentity.d.ts +4 -0
- package/dist/commands/CommandIdentity/CommandIdentity.d.ts.map +1 -0
- package/dist/commands/CommandIdentity/CommandIdentity.js +18 -0
- package/dist/commands/CommandIdentity/CommandIdentity.js.map +1 -0
- package/dist/commands/CommandRegister/CommandRegister.d.ts.map +1 -1
- package/dist/commands/CommandRegister/CommandRegister.js +7 -0
- package/dist/commands/CommandRegister/CommandRegister.js.map +1 -1
- package/dist/commands/CommandShare/CommandShare.d.ts +4 -0
- package/dist/commands/CommandShare/CommandShare.d.ts.map +1 -0
- package/dist/commands/CommandShare/CommandShare.js +55 -0
- package/dist/commands/CommandShare/CommandShare.js.map +1 -0
- package/dist/identity/identity.d.ts +11 -0
- package/dist/identity/identity.d.ts.map +1 -0
- package/dist/identity/identity.js +39 -0
- package/dist/identity/identity.js.map +1 -0
- package/dist/lib/defs.d.ts +2 -0
- package/dist/lib/defs.d.ts.map +1 -1
- package/dist/lib/defs.js +2 -0
- package/dist/lib/defs.js.map +1 -1
- package/dist/share/ShareClient.d.ts +35 -0
- package/dist/share/ShareClient.d.ts.map +1 -0
- package/dist/share/ShareClient.js +83 -0
- package/dist/share/ShareClient.js.map +1 -0
- package/dist/share/ShareHost.d.ts +40 -0
- package/dist/share/ShareHost.d.ts.map +1 -0
- package/dist/share/ShareHost.js +83 -0
- package/dist/share/ShareHost.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2026-03-24
|
|
4
|
+
|
|
5
|
+
### Share / Connect (private peer-to-peer tunnels)
|
|
6
|
+
- `tunli share <port>` — share a local port privately; outputs a public key for the other party
|
|
7
|
+
- `tunli connect <pubkey>` — connect to a remote share, opens a local TCP port (random or `--port`)
|
|
8
|
+
- Connecting client's public key shown on host side at connect/disconnect
|
|
9
|
+
- `docs/share-relay-spec.md` — relay server implementation spec (Socket.IO `/share` namespace)
|
|
10
|
+
|
|
11
|
+
### Identity
|
|
12
|
+
- Ed25519 keypair generated once at `tunli register` time, stored in `~/.tunli/identity.key` (private, mode 0600) and `~/.tunli/identity.pub`
|
|
13
|
+
- Public key encoded as `tunli1<base64url>` — recognisable, copy-paste-safe
|
|
14
|
+
- Short fingerprint (8-char hex) for display
|
|
15
|
+
- `tunli identity` — show public key and fingerprint
|
|
16
|
+
- Foundation for private peer-to-peer tunnels (`tunli share` / `tunli connect`)
|
|
17
|
+
|
|
18
|
+
### `tunli http` foreground mode
|
|
19
|
+
- `--foreground` — run the tunnel in the CLI process without a background daemon; exits when the process is killed
|
|
20
|
+
- `--dashboard` — foreground mode with the live TUI dashboard attached
|
|
21
|
+
- `--logs` — foreground mode with live log output to stdout
|
|
22
|
+
|
|
3
23
|
## [0.2.0] - 2026-03-24
|
|
4
24
|
|
|
5
25
|
### Dashboard
|
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@ Requires Node.js >= 22.
|
|
|
34
34
|
- Profiles & environments
|
|
35
35
|
- Self-hosted relay servers
|
|
36
36
|
- CIDR allow/deny access control
|
|
37
|
+
- Private peer-to-peer tunnels (`tunli share` / `tunli connect`) — no public URL, access by key only
|
|
37
38
|
|
|
38
39
|
## Quick Start
|
|
39
40
|
|
|
@@ -66,6 +67,14 @@ tunli http 3000 --save myapp # save as a named profile for later reuse
|
|
|
66
67
|
|
|
67
68
|
Use `--save <name>` to persist the configuration as a profile. You can then start it again with `tunli use <profile>` or `tunli @<profile>`.
|
|
68
69
|
|
|
70
|
+
**Foreground mode** — run the tunnel directly in the CLI process without a background daemon:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
tunli http 3000 --foreground # silent, exits when the process is killed
|
|
74
|
+
tunli http 3000 --dashboard # with live TUI dashboard
|
|
75
|
+
tunli http 3000 --logs # with live log output to stdout
|
|
76
|
+
```
|
|
77
|
+
|
|
69
78
|
### `tunli use <profile>`
|
|
70
79
|
|
|
71
80
|
Start a tunnel using a saved profile. Profiles are created via `tunli http --save` or managed with `tunli profile`.
|
|
@@ -182,6 +191,36 @@ tunli profile use staging # set staging as the default profile
|
|
|
182
191
|
tunli profile delete staging # remove a profile
|
|
183
192
|
```
|
|
184
193
|
|
|
194
|
+
### `tunli identity`
|
|
195
|
+
|
|
196
|
+
Show your tunli identity (public key and fingerprint). The keypair is generated automatically on first `tunli register`.
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
tunli identity
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### `tunli share <port> [host]`
|
|
203
|
+
|
|
204
|
+
Share a local port privately via a peer-to-peer tunnel. No public URL is created — only someone with your public key can connect.
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
tunli share 8080
|
|
208
|
+
# → Your public key: tunli1abc...
|
|
209
|
+
# → Share this: tunli connect tunli1abc...
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### `tunli connect <pubkey>`
|
|
213
|
+
|
|
214
|
+
Connect to a remote share by the host's public key. Opens a local TCP port that proxies to the remote service.
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
tunli connect tunli1abc...
|
|
218
|
+
# → Connected. Service available at localhost:52416
|
|
219
|
+
# → For SSH: ssh -p 52416 user@localhost
|
|
220
|
+
|
|
221
|
+
tunli connect tunli1abc... --port 2222 # fixed local port
|
|
222
|
+
```
|
|
223
|
+
|
|
185
224
|
### `tunli update`
|
|
186
225
|
|
|
187
226
|
Download and apply the latest binary release.
|
package/dist/client.js
CHANGED
|
@@ -19,6 +19,9 @@ import { createCommandLogs } from "#commands/CommandLogs/CommandLogs";
|
|
|
19
19
|
import { createCommandStop } from "#commands/CommandStop/CommandStop";
|
|
20
20
|
import { createCommandRestart } from "#commands/CommandRestart/CommandRestart";
|
|
21
21
|
import { createCommandUpdate } from "#commands/CommandUpdate/CommandUpdate";
|
|
22
|
+
import { createCommandIdentity } from "#commands/CommandIdentity/CommandIdentity";
|
|
23
|
+
import { createCommandShare } from "#commands/CommandShare/CommandShare";
|
|
24
|
+
import { createCommandConnect } from "#commands/CommandConnect/CommandConnect";
|
|
22
25
|
import { ApiClient } from "#api-client/ApiClient";
|
|
23
26
|
import { readPackageJson } from "#package-json/packageJson";
|
|
24
27
|
const globalConf = new ParsedGlobalConfig(readJsonFile(GLOBAL_CONFIG_FILEPATH), GLOBAL_CONFIG_FILEPATH);
|
|
@@ -61,6 +64,9 @@ program.addCommand(createCommandLogs(ctx, program));
|
|
|
61
64
|
program.addCommand(createCommandStop(ctx, program));
|
|
62
65
|
program.addCommand(createCommandRestart(ctx, program));
|
|
63
66
|
program.addCommand(createCommandUpdate(ctx, program));
|
|
67
|
+
program.addCommand(createCommandIdentity(ctx, program));
|
|
68
|
+
program.addCommand(createCommandShare(ctx, program));
|
|
69
|
+
program.addCommand(createCommandConnect(ctx, program));
|
|
64
70
|
program.action(({ options }) => {
|
|
65
71
|
if (options.version) {
|
|
66
72
|
ctx.logger.info(`tunli: ${packageJson?.version}`);
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAC,MAAM,EAAoB,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAC,2BAA2B,EAAE,sBAAsB,EAAE,qBAAqB,EAAC,MAAM,WAAW,CAAC;AACrG,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,yBAAyB,EAAC,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAC,qBAAqB,EAAC,MAAM,2CAA2C,CAAC;AAChF,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAChD,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAC,iBAAiB,EAAC,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAC,oBAAoB,EAAC,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,sBAAsB,EAAC,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAC,oBAAoB,EAAC,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAE1D,MAAM,UAAU,GAAG,IAAI,kBAAkB,CAAC,YAAY,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC,CAAA;AACvG,MAAM,SAAS,GAAG,2BAA2B,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,YAAY,CAAC,2BAA2B,CAAC,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACzJ,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;AACrC,MAAM,GAAG,GAAY;IACnB,MAAM,EAAE;QACN,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,SAAS;QAChB,iBAAiB,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,qBAAqB,CAAC;KAClE;IACD,IAAI,CAAC,IAAa;QAChB,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;IACzB,CAAC;IACD,SAAS,EAAE,IAAI,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/C,MAAM,EAAE;QACN,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB;CACF,CAAA;AAED,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,oBAAoB,CAAC;KACjC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9C,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACrD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;AACtE,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACvD,wDAAwD;AACxD,uDAAuD;AACvD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,yBAAyB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AAC3D,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACrD,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACtD,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACrD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACxD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACnD,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;AACtD,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandConnect.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandConnect/CommandConnect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAAS,MAAM,kBAAkB,CAAA;AAC1D,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AAKzC,eAAO,MAAM,oBAAoB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YA+DnE,CAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Argument, Command, Option } from '#commander/index';
|
|
2
|
+
import { ensureIdentity } from '#identity/identity';
|
|
3
|
+
import { createShareClient } from '#share/ShareClient';
|
|
4
|
+
import { DEFAULT_SERVER_NAME } from '#lib/defs';
|
|
5
|
+
export const createCommandConnect = (ctx, _program) => {
|
|
6
|
+
const cmd = new Command('connect')
|
|
7
|
+
.description('Connect to a remote share by public key')
|
|
8
|
+
.addArgument(new Argument('pubkey', 'Public key of the share host (tunli1...)').required())
|
|
9
|
+
.addOption(new Option('port', 'Local port to listen on (default: random)').argument('port').parse(Number));
|
|
10
|
+
cmd.action(async ({ args, options }) => {
|
|
11
|
+
const targetPublicKey = args.pubkey;
|
|
12
|
+
const localPort = options.port ?? 0;
|
|
13
|
+
if (!targetPublicKey.startsWith('tunli1')) {
|
|
14
|
+
ctx.logger.error('Invalid public key. Expected format: tunli1...');
|
|
15
|
+
return ctx.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const serverName = ctx.config.global.activeServer ?? DEFAULT_SERVER_NAME;
|
|
18
|
+
const serverConf = ctx.config.global.server(serverName);
|
|
19
|
+
if (!serverConf.exists() || !serverConf.authToken || !serverConf.url) {
|
|
20
|
+
ctx.logger.error('Not registered. Run `tunli register` first.');
|
|
21
|
+
return ctx.exit(1);
|
|
22
|
+
}
|
|
23
|
+
const serverConfig = { url: serverConf.url, authToken: serverConf.authToken };
|
|
24
|
+
const apiClient = ctx.apiClient.withServer(serverConfig);
|
|
25
|
+
const connectInfoResult = await apiClient.connectInfo();
|
|
26
|
+
if (connectInfoResult.error) {
|
|
27
|
+
ctx.logger.error(`Failed to reach relay: ${connectInfoResult.error.message}`);
|
|
28
|
+
return ctx.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const { socketUrl, capturePath } = connectInfoResult.data;
|
|
31
|
+
const identity = ensureIdentity();
|
|
32
|
+
ctx.logger.info(`Connecting to share ${targetPublicKey}...`);
|
|
33
|
+
const client = createShareClient(serverConfig, socketUrl, capturePath, identity, targetPublicKey, localPort, (event) => {
|
|
34
|
+
if (event.type === 'connected') {
|
|
35
|
+
ctx.logger.info(`Connected. Service available at localhost:${event.localPort}`);
|
|
36
|
+
ctx.logger.info(`For SSH: ssh -p ${event.localPort} user@localhost`);
|
|
37
|
+
}
|
|
38
|
+
else if (event.type === 'error') {
|
|
39
|
+
ctx.logger.error(`Connection failed: ${event.message}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
else if (event.type === 'disconnected') {
|
|
43
|
+
ctx.logger.info('Share host disconnected.');
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
process.on('SIGINT', () => { client.disconnect(); process.exit(0); });
|
|
47
|
+
process.on('SIGTERM', () => { client.disconnect(); process.exit(0); });
|
|
48
|
+
});
|
|
49
|
+
return cmd;
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=CommandConnect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandConnect.js","sourceRoot":"","sources":["../../../src/commands/CommandConnect/CommandConnect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandHttp.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandHTTP/CommandHttp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,
|
|
1
|
+
{"version":3,"file":"CommandHttp.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandHTTP/CommandHttp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAA2B,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAY1C,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YA6DhE,CAAA"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { Argument, Command } from "#commander/index";
|
|
1
|
+
import { Argument, Command, Option } from "#commander/index";
|
|
2
2
|
import { checkPort } from "#utils/checkFunctions";
|
|
3
3
|
import { resolveConfig } from "#commands/CommandConfig/utils/resolveConfig";
|
|
4
4
|
import { addSharedOptions } from "#commands/CommandConfig/utils/sharedOptions";
|
|
5
5
|
import { validateProfileConfig } from "#config/validations/validateProfileConfig";
|
|
6
6
|
import { DaemonClient } from "#daemon/DaemonClient";
|
|
7
|
+
import { AppEventEmitter } from "#cli-app/AppEventEmitter";
|
|
8
|
+
import { createProxy } from "#proxy/Proxy";
|
|
9
|
+
import { initDashboard } from "#cli-app/Dashboard";
|
|
10
|
+
import { initLiveLog } from "#cli-app/LiveLog";
|
|
7
11
|
export const createCommandHttp = (ctx, _program) => {
|
|
8
12
|
const cmd = new Command('http')
|
|
9
13
|
.description('Start a tunnel to a local HTTP service')
|
|
@@ -11,6 +15,9 @@ export const createCommandHttp = (ctx, _program) => {
|
|
|
11
15
|
addSharedOptions(cmd, 'save');
|
|
12
16
|
cmd.addArgument(new Argument('port', 'Local port to forward (e.g. 3000)').required().parse(checkPort));
|
|
13
17
|
cmd.addArgument(new Argument('host', 'Local host to forward to (default: localhost)'));
|
|
18
|
+
cmd.addOption(new Option('foreground', 'Run tunnel in the foreground (no daemon)'));
|
|
19
|
+
cmd.addOption(new Option('dashboard', 'Show live dashboard (implies --foreground)'));
|
|
20
|
+
cmd.addOption(new Option('logs', 'Show live log output (implies --foreground)'));
|
|
14
21
|
cmd.action(async ({ args, options }) => {
|
|
15
22
|
const port = args.port;
|
|
16
23
|
const host = args.host ?? 'localhost';
|
|
@@ -24,6 +31,18 @@ export const createCommandHttp = (ctx, _program) => {
|
|
|
24
31
|
const validated = await validateProfileConfig(ctx, config);
|
|
25
32
|
if (opts.save)
|
|
26
33
|
config.save();
|
|
34
|
+
if (opts.foreground || opts.dashboard || opts.logs) {
|
|
35
|
+
const appEmitter = new AppEventEmitter();
|
|
36
|
+
const proxy = await createProxy(validated, appEmitter);
|
|
37
|
+
process.once('exit', () => proxy.disconnect());
|
|
38
|
+
process.on('SIGINT', () => process.exit(0));
|
|
39
|
+
process.on('SIGTERM', () => process.exit(0));
|
|
40
|
+
if (opts.dashboard)
|
|
41
|
+
initDashboard(validated, appEmitter);
|
|
42
|
+
else if (opts.logs)
|
|
43
|
+
initLiveLog(validated, appEmitter);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
27
46
|
await DaemonClient.ensureRunning();
|
|
28
47
|
const client = new DaemonClient();
|
|
29
48
|
const result = await client.send({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandHttp.js","sourceRoot":"","sources":["../../../src/commands/CommandHTTP/CommandHttp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAmB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"CommandHttp.js","sourceRoot":"","sources":["../../../src/commands/CommandHTTP/CommandHttp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAmB,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAC,aAAa,EAAC,MAAM,6CAA6C,CAAC;AAC1E,OAAO,EAAC,gBAAgB,EAAC,MAAM,6CAA6C,CAAC;AAE7E,OAAO,EAAC,qBAAqB,EAAC,MAAM,2CAA2C,CAAC;AAChF,OAAO,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AACzC,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAE7C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAY,EAAE,QAAiB,EAAE,EAAE;IACnE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SAC5B,WAAW,CAAC,wCAAwC,CAAC;SACrD,KAAK,CAAC,OAAO,CAAC,CAAA;IACjB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAC7B,GAAG,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,mCAAmC,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;IACtG,GAAG,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,+CAA+C,CAAC,CAAC,CAAA;IACtF,GAAG,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE,0CAA0C,CAAC,CAAC,CAAA;IACnF,GAAG,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,4CAA4C,CAAC,CAAC,CAAA;IACpF,GAAG,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,6CAA6C,CAAC,CAAC,CAAA;IAChF,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAC,IAAI,EAAE,OAAO,EAAc,EAAE,EAAE;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAc,CAAA;QAChC,MAAM,IAAI,GAAI,IAAI,CAAC,IAA2B,IAAI,WAAW,CAAA;QAC7D,MAAM,IAAI,GAAG,OAAoH,CAAA;QAEjI,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE;YAChC,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,IAAI;YAC1B,MAAM,EAAE,IAAI,CAAC,MAAM,KAAK,IAAI;YAC5B,OAAO,EAAE,IAAI,CAAC,IAAI;SACnB,EAAE,MAAM,CAAC,CAAA;QAEV,MAAM,CAAC,MAAM,CAAC,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAC,CAAC,CAAA;QAE7C,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAE1D,IAAI,IAAI,CAAC,IAAI;YAAE,MAAM,CAAC,IAAI,EAAE,CAAA;QAE5B,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACnD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YACxC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;YACtD,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAA;YAC9C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAC3C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAC5C,IAAI,IAAI,CAAC,SAAS;gBAAE,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;iBACnD,IAAI,IAAI,CAAC,IAAI;gBAAE,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;YACtD,OAAM;QACR,CAAC;QAED,MAAM,YAAY,CAAC,aAAa,EAAE,CAAA;QAClC,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAA;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC;YAC/B,IAAI,EAAS,OAAO;YACpB,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,UAAU,EAAG,SAAS,CAAC,KAAK,CAAC,UAAU;YACvC,QAAQ,EAAK,SAAS,CAAC,KAAK,CAAC,QAAQ;YACrC,SAAS,EAAI,SAAS,CAAC,YAAY,CAAC,GAAG;YACvC,SAAS,EAAI,SAAS,CAAC,YAAY,CAAC,SAAS;YAC7C,MAAM,EAAO,SAAS,CAAC,MAAM;YAC7B,QAAQ,EAAK,SAAS,CAAC,QAAQ;YAC/B,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,UAAU,EAAG,SAAS,CAAC,UAAU;SAClC,CAAC,CAAA;QAEF,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAChC,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;YAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IACtF,CAAC,CAAC,CAAA;IACF,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandIdentity.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandIdentity/CommandIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAmB,MAAM,kBAAkB,CAAA;AAC1D,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AAIzC,eAAO,MAAM,qBAAqB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YAepE,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from '#commander/index';
|
|
2
|
+
import { ensureIdentity, encodePublicKey, fingerprint } from '#identity/identity';
|
|
3
|
+
import { IDENTITY_KEY_PATH, IDENTITY_PUB_PATH } from '#lib/defs';
|
|
4
|
+
export const createCommandIdentity = (ctx, _program) => {
|
|
5
|
+
const cmd = new Command('identity')
|
|
6
|
+
.description('Show your tunli identity (public key and fingerprint)');
|
|
7
|
+
cmd.action((_) => {
|
|
8
|
+
const identity = ensureIdentity();
|
|
9
|
+
const pubKey = encodePublicKey(identity.publicKeyRaw);
|
|
10
|
+
const fp = fingerprint(identity.publicKeyRaw);
|
|
11
|
+
ctx.logger.info(`Public key: ${pubKey}`);
|
|
12
|
+
ctx.logger.info(`Fingerprint: ${fp}`);
|
|
13
|
+
ctx.logger.info(`Key file: ${IDENTITY_KEY_PATH}`);
|
|
14
|
+
ctx.logger.info(`Pub file: ${IDENTITY_PUB_PATH}`);
|
|
15
|
+
});
|
|
16
|
+
return cmd;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=CommandIdentity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandIdentity.js","sourceRoot":"","sources":["../../../src/commands/CommandIdentity/CommandIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAmB,MAAM,kBAAkB,CAAA;AAE1D,OAAO,EAAC,cAAc,EAAE,eAAe,EAAE,WAAW,EAAC,MAAM,oBAAoB,CAAA;AAC/E,OAAO,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,WAAW,CAAA;AAE9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAY,EAAE,QAAiB,EAAE,EAAE;IACvE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;SAChC,WAAW,CAAC,uDAAuD,CAAC,CAAA;IAEvE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAc,EAAE,EAAE;QAC5B,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;QACjC,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;QACrD,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;QAC7C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAA;QACzC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAA;QACrC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,iBAAiB,EAAE,CAAC,CAAA;QACpD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,iBAAiB,EAAE,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandRegister.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandRegister/CommandRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAA2B,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"CommandRegister.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandRegister/CommandRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAA2B,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAI1C,eAAO,MAAM,qBAAqB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YA6DpE,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command, Option } from "#commander/index";
|
|
2
2
|
import { DEFAULT_API_SERVER_URL, DEFAULT_SERVER_NAME } from "#lib/defs";
|
|
3
|
+
import { encodePublicKey, ensureIdentity, fingerprint, loadIdentity } from "#identity/identity";
|
|
3
4
|
export const createCommandRegister = (ctx, _program) => {
|
|
4
5
|
const cmd = new Command('register')
|
|
5
6
|
.description('Register a new account and store the auth token')
|
|
@@ -33,6 +34,12 @@ export const createCommandRegister = (ctx, _program) => {
|
|
|
33
34
|
.setAuthToken(data)
|
|
34
35
|
.save();
|
|
35
36
|
ctx.logger.info(`Registration successful. Relay: ${opt.relay} (${serverName})`);
|
|
37
|
+
const isNew = loadIdentity() === null;
|
|
38
|
+
const identity = ensureIdentity();
|
|
39
|
+
if (isNew) {
|
|
40
|
+
ctx.logger.info(`Identity key generated: ${encodePublicKey(identity.publicKeyRaw)}`);
|
|
41
|
+
ctx.logger.info(`Fingerprint: ${fingerprint(identity.publicKeyRaw)}`);
|
|
42
|
+
}
|
|
36
43
|
});
|
|
37
44
|
cmd.extendUsage();
|
|
38
45
|
cmd.addExample('register', 'Register a new account against tunli.app');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandRegister.js","sourceRoot":"","sources":["../../../src/commands/CommandRegister/CommandRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,MAAM,EAAmB,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAC,sBAAsB,EAAE,mBAAmB,EAAC,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"CommandRegister.js","sourceRoot":"","sources":["../../../src/commands/CommandRegister/CommandRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,MAAM,EAAmB,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAC,sBAAsB,EAAE,mBAAmB,EAAC,MAAM,WAAW,CAAC;AACtE,OAAO,EAAC,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAE9F,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAY,EAAE,QAAiB,EAAE,EAAE;IAQvE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;SAChC,WAAW,CAAC,iDAAiD,CAAC;SAC9D,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,yDAAyD,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SACpG,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,2EAA2E,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;SAC3J,SAAS,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,gFAAgF,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAEjK,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAC,OAAO,EAAc,EAAE,EAAE;QAC1C,MAAM,GAAG,GAAG,OAAkB,CAAA;QAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,KAAK,IAAI,CAAA;QAChC,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,mBAAmB,CAAA;QACpF,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAEvD,IAAI,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAA;YACnE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC;QAED,MAAM,EAAC,IAAI,EAAE,KAAK,EAAC,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAE7D,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YACnB,IAAI,KAAK,EAAE,CAAC;gBACV,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACjC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAA;YAClE,CAAC;YACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YACpC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,GAAG,UAAU,CAAA;QAC7C,CAAC;QAED,UAAU;aACP,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;aACjB,YAAY,CAAC,IAAI,CAAC;aAClB,IAAI,EAAE,CAAA;QAET,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,GAAG,CAAC,KAAK,KAAK,UAAU,GAAG,CAAC,CAAA;QAE/E,MAAM,KAAK,GAAG,YAAY,EAAE,KAAK,IAAI,CAAA;QACrC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAA;QACjC,IAAI,KAAK,EAAE,CAAC;YACV,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;YACpF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;QACvE,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,WAAW,EAAE,CAAA;IACjB,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,0CAA0C,CAAC,CAAA;IACtE,GAAG,CAAC,UAAU,CAAC,0DAA0D,EAAE,6CAA6C,CAAC,CAAA;IACzH,GAAG,CAAC,UAAU,CAAC,kBAAkB,EAAE,gDAAgD,CAAC,CAAA;IAEpF,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandShare.d.ts","sourceRoot":"","sources":["../../../src/commands/CommandShare/CommandShare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,OAAO,EAAC,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AAKzC,eAAO,MAAM,kBAAkB,GAAI,KAAK,OAAO,EAAE,UAAU,OAAO,YAgEjE,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Argument, Command } from '#commander/index';
|
|
2
|
+
import { ensureIdentity, encodePublicKey, fingerprint } from '#identity/identity';
|
|
3
|
+
import { createShareHost } from '#share/ShareHost';
|
|
4
|
+
import { DEFAULT_SERVER_NAME } from '#lib/defs';
|
|
5
|
+
export const createCommandShare = (ctx, _program) => {
|
|
6
|
+
const cmd = new Command('share')
|
|
7
|
+
.description('Share a local port via a private peer-to-peer tunnel')
|
|
8
|
+
.addArgument(new Argument('port', 'Local port to share').required().parse(Number))
|
|
9
|
+
.addArgument(new Argument('host', 'Local host to share (default: localhost)'));
|
|
10
|
+
cmd.action(async ({ args }) => {
|
|
11
|
+
const port = args.port;
|
|
12
|
+
const host = args.host ?? 'localhost';
|
|
13
|
+
const serverName = ctx.config.global.activeServer ?? DEFAULT_SERVER_NAME;
|
|
14
|
+
const serverConf = ctx.config.global.server(serverName);
|
|
15
|
+
if (!serverConf.exists() || !serverConf.authToken || !serverConf.url) {
|
|
16
|
+
ctx.logger.error('Not registered. Run `tunli register` first.');
|
|
17
|
+
return ctx.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const serverConfig = { url: serverConf.url, authToken: serverConf.authToken };
|
|
20
|
+
const apiClient = ctx.apiClient.withServer(serverConfig);
|
|
21
|
+
const connectInfoResult = await apiClient.connectInfo();
|
|
22
|
+
if (connectInfoResult.error) {
|
|
23
|
+
ctx.logger.error(`Failed to reach relay: ${connectInfoResult.error.message}`);
|
|
24
|
+
return ctx.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const { socketUrl, capturePath } = connectInfoResult.data;
|
|
27
|
+
const identity = ensureIdentity();
|
|
28
|
+
const pubKey = encodePublicKey(identity.publicKeyRaw);
|
|
29
|
+
const fp = fingerprint(identity.publicKeyRaw);
|
|
30
|
+
ctx.logger.info(`Sharing ${host}:${port}`);
|
|
31
|
+
ctx.logger.info(`Your public key: ${pubKey}`);
|
|
32
|
+
ctx.logger.info(`Fingerprint: ${fp}`);
|
|
33
|
+
ctx.logger.info(`Share this with the other party:`);
|
|
34
|
+
ctx.logger.info(` tunli connect ${pubKey}`);
|
|
35
|
+
ctx.logger.info(`Waiting for connections... (Ctrl+C to stop)`);
|
|
36
|
+
const host_ = createShareHost(serverConfig, socketUrl, capturePath, identity, host, port, (event) => {
|
|
37
|
+
if (event.type === 'registered') {
|
|
38
|
+
ctx.logger.info('Registered with relay.');
|
|
39
|
+
}
|
|
40
|
+
else if (event.type === 'client-connected') {
|
|
41
|
+
ctx.logger.info(`Client connected: ${event.publicKey}`);
|
|
42
|
+
}
|
|
43
|
+
else if (event.type === 'client-disconnected') {
|
|
44
|
+
ctx.logger.info(`Client disconnected: ${event.publicKey}`);
|
|
45
|
+
}
|
|
46
|
+
else if (event.type === 'error') {
|
|
47
|
+
ctx.logger.error(`Share error: ${event.message}`);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
process.on('SIGINT', () => { host_.disconnect(); process.exit(0); });
|
|
51
|
+
process.on('SIGTERM', () => { host_.disconnect(); process.exit(0); });
|
|
52
|
+
});
|
|
53
|
+
return cmd;
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=CommandShare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandShare.js","sourceRoot":"","sources":["../../../src/commands/CommandShare/CommandShare.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type Identity = {
|
|
2
|
+
privateKeyPem: string;
|
|
3
|
+
publicKeyRaw: Buffer;
|
|
4
|
+
};
|
|
5
|
+
export declare const encodePublicKey: (publicKeyRaw: Buffer) => string;
|
|
6
|
+
export declare const decodePublicKey: (encoded: string) => Buffer;
|
|
7
|
+
export declare const fingerprint: (publicKeyRaw: Buffer) => string;
|
|
8
|
+
export declare const saveIdentity: (identity: Identity) => void;
|
|
9
|
+
export declare const loadIdentity: () => Identity | null;
|
|
10
|
+
export declare const ensureIdentity: () => Identity;
|
|
11
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity/identity.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,QAAQ,GAAG;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,cAAc,MAAM,KAAG,MACJ,CAAA;AAEnD,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,MAGjD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,cAAc,MAAM,KAAG,MACkB,CAAA;AAUrE,eAAO,MAAM,YAAY,GAAI,UAAU,QAAQ,KAAG,IAIjD,CAAA;AAED,eAAO,MAAM,YAAY,QAAO,QAAQ,GAAG,IAK1C,CAAA;AAED,eAAO,MAAM,cAAc,QAAO,QAMjC,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createHash, generateKeyPairSync } from 'node:crypto';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { GLOBAL_CONFIG_DIR, IDENTITY_KEY_PATH, IDENTITY_PUB_PATH } from '#lib/defs';
|
|
4
|
+
const TUNLI_PREFIX = 'tunli1';
|
|
5
|
+
export const encodePublicKey = (publicKeyRaw) => TUNLI_PREFIX + publicKeyRaw.toString('base64url');
|
|
6
|
+
export const decodePublicKey = (encoded) => {
|
|
7
|
+
if (!encoded.startsWith(TUNLI_PREFIX))
|
|
8
|
+
throw new Error('Invalid tunli public key');
|
|
9
|
+
return Buffer.from(encoded.slice(TUNLI_PREFIX.length), 'base64url');
|
|
10
|
+
};
|
|
11
|
+
export const fingerprint = (publicKeyRaw) => createHash('sha256').update(publicKeyRaw).digest('hex').slice(0, 8);
|
|
12
|
+
const generate = () => {
|
|
13
|
+
const { privateKey, publicKey } = generateKeyPairSync('ed25519');
|
|
14
|
+
const privateKeyPem = privateKey.export({ type: 'pkcs8', format: 'pem' });
|
|
15
|
+
// SPKI DER for Ed25519: 12-byte header + 32-byte raw key
|
|
16
|
+
const publicKeyRaw = publicKey.export({ type: 'spki', format: 'der' }).subarray(-32);
|
|
17
|
+
return { privateKeyPem, publicKeyRaw };
|
|
18
|
+
};
|
|
19
|
+
export const saveIdentity = (identity) => {
|
|
20
|
+
mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
|
|
21
|
+
writeFileSync(IDENTITY_KEY_PATH, identity.privateKeyPem, { encoding: 'utf-8', mode: 0o600 });
|
|
22
|
+
writeFileSync(IDENTITY_PUB_PATH, encodePublicKey(identity.publicKeyRaw), { encoding: 'utf-8' });
|
|
23
|
+
};
|
|
24
|
+
export const loadIdentity = () => {
|
|
25
|
+
if (!existsSync(IDENTITY_KEY_PATH) || !existsSync(IDENTITY_PUB_PATH))
|
|
26
|
+
return null;
|
|
27
|
+
const privateKeyPem = readFileSync(IDENTITY_KEY_PATH, 'utf-8');
|
|
28
|
+
const publicKeyRaw = decodePublicKey(readFileSync(IDENTITY_PUB_PATH, 'utf-8').trim());
|
|
29
|
+
return { privateKeyPem, publicKeyRaw };
|
|
30
|
+
};
|
|
31
|
+
export const ensureIdentity = () => {
|
|
32
|
+
const existing = loadIdentity();
|
|
33
|
+
if (existing)
|
|
34
|
+
return existing;
|
|
35
|
+
const identity = generate();
|
|
36
|
+
saveIdentity(identity);
|
|
37
|
+
return identity;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity/identity.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/defs.d.ts
CHANGED
|
@@ -15,4 +15,6 @@ export declare const TUNLI_BIN_DIR: string;
|
|
|
15
15
|
export declare const TUNLI_BIN_PATH: string;
|
|
16
16
|
export declare const TUNLI_BIN_NEW_PATH: string;
|
|
17
17
|
export declare const RESTART_DUMP_FILEPATH: string;
|
|
18
|
+
export declare const IDENTITY_KEY_PATH: string;
|
|
19
|
+
export declare const IDENTITY_PUB_PATH: string;
|
|
18
20
|
//# sourceMappingURL=defs.d.ts.map
|
package/dist/lib/defs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../src/lib/defs.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,OAAO,CAAA;AAEjC,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC,eAAO,MAAM,sBAAsB,0BAA0B,CAAA;AAE7D,eAAO,MAAM,yBAAyB,qEAAqE,CAAA;AAE3G,eAAO,MAAM,eAAe,WAAW,CAAA;AAEvC,eAAO,MAAM,iBAAiB,QAAsC,CAAC;AAErE,eAAO,MAAM,sBAAsB,QAA4C,CAAA;AAE/E,eAAO,MAAM,qBAAqB,QAAyD,CAAA;AAE3F,eAAO,MAAM,mBAAmB,cAAc,CAAA;AAC9C,eAAO,MAAM,oBAAoB,YAAY,CAAA;AAE7C,eAAO,MAAM,yBAAyB,UAalC,CAAC;AAEL,eAAO,MAAM,2BAA2B,oBAA2D,CAAA;AAEnG,eAAO,MAAM,kBAAkB,QAA4C,CAAA;AAE3E,eAAO,MAAM,aAAa,QAAoC,CAAA;AAC9D,eAAO,MAAM,cAAc,QAAuC,CAAA;AAClE,eAAO,MAAM,kBAAkB,QAA8C,CAAA;AAC7E,eAAO,MAAM,qBAAqB,QAA0C,CAAA"}
|
|
1
|
+
{"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../src/lib/defs.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,OAAO,CAAA;AAEjC,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC,eAAO,MAAM,sBAAsB,0BAA0B,CAAA;AAE7D,eAAO,MAAM,yBAAyB,qEAAqE,CAAA;AAE3G,eAAO,MAAM,eAAe,WAAW,CAAA;AAEvC,eAAO,MAAM,iBAAiB,QAAsC,CAAC;AAErE,eAAO,MAAM,sBAAsB,QAA4C,CAAA;AAE/E,eAAO,MAAM,qBAAqB,QAAyD,CAAA;AAE3F,eAAO,MAAM,mBAAmB,cAAc,CAAA;AAC9C,eAAO,MAAM,oBAAoB,YAAY,CAAA;AAE7C,eAAO,MAAM,yBAAyB,UAalC,CAAC;AAEL,eAAO,MAAM,2BAA2B,oBAA2D,CAAA;AAEnG,eAAO,MAAM,kBAAkB,QAA4C,CAAA;AAE3E,eAAO,MAAM,aAAa,QAAoC,CAAA;AAC9D,eAAO,MAAM,cAAc,QAAuC,CAAA;AAClE,eAAO,MAAM,kBAAkB,QAA8C,CAAA;AAC7E,eAAO,MAAM,qBAAqB,QAA0C,CAAA;AAE5E,eAAO,MAAM,iBAAiB,QAA6C,CAAA;AAC3E,eAAO,MAAM,iBAAiB,QAA6C,CAAA"}
|
package/dist/lib/defs.js
CHANGED
|
@@ -30,4 +30,6 @@ export const TUNLI_BIN_DIR = resolve(GLOBAL_CONFIG_DIR, 'bin');
|
|
|
30
30
|
export const TUNLI_BIN_PATH = resolve(TUNLI_BIN_DIR, 'tunli-main');
|
|
31
31
|
export const TUNLI_BIN_NEW_PATH = resolve(TUNLI_BIN_DIR, 'tunli-main.update');
|
|
32
32
|
export const RESTART_DUMP_FILEPATH = resolve(GLOBAL_CONFIG_DIR, 'dump.json');
|
|
33
|
+
export const IDENTITY_KEY_PATH = resolve(GLOBAL_CONFIG_DIR, 'identity.key');
|
|
34
|
+
export const IDENTITY_PUB_PATH = resolve(GLOBAL_CONFIG_DIR, 'identity.pub');
|
|
33
35
|
//# sourceMappingURL=defs.js.map
|
package/dist/lib/defs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defs.js","sourceRoot":"","sources":["../../src/lib/defs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAC,MAAM,MAAM,CAAC;AACvC,OAAO,EAAC,OAAO,EAAC,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAC,UAAU,EAAC,MAAM,IAAI,CAAC;AAE9B,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAA;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAA;AAE7D,MAAM,CAAC,MAAM,yBAAyB,GAAG,kEAAkE,CAAA;AAE3G,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA;AAEvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAE/E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,CAAA;AAE3F,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAA;AAE7C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE;IAC7C,MAAM,YAAY,GAAa,EAAE,CAAA;IACjC,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IAEtB,GAAG,CAAC;QACF,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACjG,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACrC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,MAAK;QACvC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC,CAAA;IACvE,CAAC,QAAQ,mBAAmB,CAAC,GAAG,EAAE,KAAK,SAAS,IAAI,mBAAmB,CAAC,MAAM,EAAC;IAE/E,OAAO,YAAY,CAAA;AACrB,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,CAAC,MAAM,2BAA2B,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;AAEnG,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAE3E,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"defs.js","sourceRoot":"","sources":["../../src/lib/defs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAC,MAAM,MAAM,CAAC;AACvC,OAAO,EAAC,OAAO,EAAC,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAC,UAAU,EAAC,MAAM,IAAI,CAAC;AAE9B,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAA;AAEjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAA;AAE7D,MAAM,CAAC,MAAM,yBAAyB,GAAG,kEAAkE,CAAA;AAE3G,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA;AAEvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAE/E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,CAAA;AAE3F,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAA;AAE7C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE;IAC7C,MAAM,YAAY,GAAa,EAAE,CAAA;IACjC,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IAEtB,GAAG,CAAC;QACF,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACjG,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACrC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,MAAK;QACvC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC,CAAA;IACvE,CAAC,QAAQ,mBAAmB,CAAC,GAAG,EAAE,KAAK,SAAS,IAAI,mBAAmB,CAAC,MAAM,EAAC;IAE/E,OAAO,YAAY,CAAA;AACrB,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,CAAC,MAAM,2BAA2B,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;AAEnG,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;AAE3E,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAA;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;AAE5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Share client (Bob side) — Bob runs `tunli connect <pubkey>`.
|
|
3
|
+
*
|
|
4
|
+
* Connects to the relay's `/share` Socket.IO namespace and requests
|
|
5
|
+
* a connection to Alice's share by her public key. Once the relay
|
|
6
|
+
* confirms the session, a local TCP server is started on `localPort`
|
|
7
|
+
* (0 = OS-assigned). Any TCP client connecting to that port (e.g. an
|
|
8
|
+
* SSH client) gets its data piped through the relay to Alice's machine.
|
|
9
|
+
*
|
|
10
|
+
* Required relay events (server → client):
|
|
11
|
+
* share-connected {sessionId} — relay confirmed the session
|
|
12
|
+
* share-error {message} — connection refused / not found
|
|
13
|
+
* share-data {sessionId, data} — data from Alice
|
|
14
|
+
* share-end {sessionId} — Alice disconnected
|
|
15
|
+
*
|
|
16
|
+
* Required relay events (client → server):
|
|
17
|
+
* share-connect {targetPublicKey, publicKey} — request connection to Alice; publicKey is Bob's own key so Alice can identify the caller
|
|
18
|
+
* share-data {sessionId, data}
|
|
19
|
+
* share-end {sessionId}
|
|
20
|
+
*/
|
|
21
|
+
import type { ServerConfig } from '#types/types';
|
|
22
|
+
import type { Identity } from '#identity/identity';
|
|
23
|
+
export type ShareClientEvent = {
|
|
24
|
+
type: 'connected';
|
|
25
|
+
localPort: number;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'error';
|
|
28
|
+
message: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'disconnected';
|
|
31
|
+
};
|
|
32
|
+
export declare const createShareClient: (serverConfig: ServerConfig, socketUrl: string, socketPath: string, identity: Identity, targetPublicKey: string, localPort: number, onEvent: (event: ShareClientEvent) => void) => {
|
|
33
|
+
disconnect: () => void;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=ShareClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareClient.d.ts","sourceRoot":"","sources":["../../src/share/ShareClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAGhD,MAAM,MAAM,gBAAgB,GACxB;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,GACtC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GAChC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAC,CAAA;AAE1B,eAAO,MAAM,iBAAiB,GAC5B,cAAc,YAAY,EAC1B,WAAW,MAAM,EACjB,YAAY,MAAM,EAClB,UAAU,QAAQ,EAClB,iBAAiB,MAAM,EACvB,WAAW,MAAM,EACjB,SAAS,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,KACzC;IAAC,UAAU,EAAE,MAAM,IAAI,CAAA;CAoEzB,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Share client (Bob side) — Bob runs `tunli connect <pubkey>`.
|
|
3
|
+
*
|
|
4
|
+
* Connects to the relay's `/share` Socket.IO namespace and requests
|
|
5
|
+
* a connection to Alice's share by her public key. Once the relay
|
|
6
|
+
* confirms the session, a local TCP server is started on `localPort`
|
|
7
|
+
* (0 = OS-assigned). Any TCP client connecting to that port (e.g. an
|
|
8
|
+
* SSH client) gets its data piped through the relay to Alice's machine.
|
|
9
|
+
*
|
|
10
|
+
* Required relay events (server → client):
|
|
11
|
+
* share-connected {sessionId} — relay confirmed the session
|
|
12
|
+
* share-error {message} — connection refused / not found
|
|
13
|
+
* share-data {sessionId, data} — data from Alice
|
|
14
|
+
* share-end {sessionId} — Alice disconnected
|
|
15
|
+
*
|
|
16
|
+
* Required relay events (client → server):
|
|
17
|
+
* share-connect {targetPublicKey, publicKey} — request connection to Alice; publicKey is Bob's own key so Alice can identify the caller
|
|
18
|
+
* share-data {sessionId, data}
|
|
19
|
+
* share-end {sessionId}
|
|
20
|
+
*/
|
|
21
|
+
import net from 'node:net';
|
|
22
|
+
import { io } from 'socket.io-client';
|
|
23
|
+
import { encodePublicKey } from '#identity/identity';
|
|
24
|
+
export const createShareClient = (serverConfig, socketUrl, socketPath, identity, targetPublicKey, localPort, onEvent) => {
|
|
25
|
+
const shareUrl = socketUrl.replace(/\/$/, '') + '/share';
|
|
26
|
+
const socket = io(shareUrl, {
|
|
27
|
+
path: socketPath,
|
|
28
|
+
auth: { token: serverConfig.authToken },
|
|
29
|
+
});
|
|
30
|
+
// One session per local TCP client connection.
|
|
31
|
+
// Currently the relay creates one session per `share-connect`, so we
|
|
32
|
+
// only track the single active one. Multi-client support can be added
|
|
33
|
+
// on both sides later.
|
|
34
|
+
let sessionId = null;
|
|
35
|
+
let activeTcpClient = null;
|
|
36
|
+
const server = net.createServer();
|
|
37
|
+
socket.on('connect', () => {
|
|
38
|
+
socket.emit('share-connect', { targetPublicKey, publicKey: encodePublicKey(identity.publicKeyRaw) });
|
|
39
|
+
});
|
|
40
|
+
socket.on('share-connected', ({ sessionId: sid }) => {
|
|
41
|
+
sessionId = sid;
|
|
42
|
+
if (server.listening)
|
|
43
|
+
return;
|
|
44
|
+
server.listen(localPort, '127.0.0.1', () => {
|
|
45
|
+
const addr = server.address();
|
|
46
|
+
onEvent({ type: 'connected', localPort: addr.port });
|
|
47
|
+
});
|
|
48
|
+
server.on('connection', (client) => {
|
|
49
|
+
activeTcpClient = client;
|
|
50
|
+
// Notify Alice that a local TCP client has connected — she should now
|
|
51
|
+
// open the TCP connection to her local service.
|
|
52
|
+
socket.emit('share-session-start', { sessionId });
|
|
53
|
+
client.on('data', (chunk) => {
|
|
54
|
+
if (sessionId)
|
|
55
|
+
socket.emit('share-data', { sessionId, data: chunk });
|
|
56
|
+
});
|
|
57
|
+
const closeClient = () => {
|
|
58
|
+
if (sessionId)
|
|
59
|
+
socket.emit('share-end', { sessionId });
|
|
60
|
+
activeTcpClient = null;
|
|
61
|
+
};
|
|
62
|
+
client.on('end', closeClient);
|
|
63
|
+
client.on('error', closeClient);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
socket.on('share-error', ({ message }) => onEvent({ type: 'error', message }));
|
|
67
|
+
socket.on('share-data', ({ data }) => {
|
|
68
|
+
activeTcpClient?.write(Buffer.from(data));
|
|
69
|
+
});
|
|
70
|
+
socket.on('share-end', () => {
|
|
71
|
+
activeTcpClient?.end();
|
|
72
|
+
activeTcpClient = null;
|
|
73
|
+
onEvent({ type: 'disconnected' });
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
disconnect: () => {
|
|
77
|
+
activeTcpClient?.destroy();
|
|
78
|
+
server.close();
|
|
79
|
+
socket.disconnect();
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=ShareClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareClient.js","sourceRoot":"","sources":["../../src/share/ShareClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,GAAG,MAAM,UAAU,CAAA;AAC1B,OAAO,EAAC,EAAE,EAAc,MAAM,kBAAkB,CAAA;AAGhD,OAAO,EAAC,eAAe,EAAC,MAAM,oBAAoB,CAAA;AAOlD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,YAA0B,EAC1B,SAAiB,EACjB,UAAkB,EAClB,QAAkB,EAClB,eAAuB,EACvB,SAAiB,EACjB,OAA0C,EAChB,EAAE;IAC5B,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAA;IACxD,MAAM,MAAM,GAAW,EAAE,CAAC,QAAQ,EAAE;QAClC,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,EAAC,KAAK,EAAE,YAAY,CAAC,SAAS,EAAC;KACtC,CAAC,CAAA;IAEF,+CAA+C;IAC/C,qEAAqE;IACrE,sEAAsE;IACtE,uBAAuB;IACvB,IAAI,SAAS,GAAkB,IAAI,CAAA;IACnC,IAAI,eAAe,GAAsB,IAAI,CAAA;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAA;IAEjC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACxB,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAC,eAAe,EAAE,SAAS,EAAE,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAC,CAAC,CAAA;IACpG,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,EAAC,SAAS,EAAE,GAAG,EAAsB,EAAE,EAAE;QACrE,SAAS,GAAG,GAAG,CAAA;QAEf,IAAI,MAAM,CAAC,SAAS;YAAE,OAAM;QAE5B,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,EAAE;YACzC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAqB,CAAA;YAChD,OAAO,CAAC,EAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAC,CAAC,CAAA;QACpD,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAkB,EAAE,EAAE;YAC7C,eAAe,GAAG,MAAM,CAAA;YACxB,sEAAsE;YACtE,gDAAgD;YAChD,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAC,SAAS,EAAC,CAAC,CAAA;YAE/C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAClC,IAAI,SAAS;oBAAE,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,EAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAC,CAAC,CAAA;YACpE,CAAC,CAAC,CAAA;YAEF,MAAM,WAAW,GAAG,GAAG,EAAE;gBACvB,IAAI,SAAS;oBAAE,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAC,SAAS,EAAC,CAAC,CAAA;gBACpD,eAAe,GAAG,IAAI,CAAA;YACxB,CAAC,CAAA;YAED,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;YAC7B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,EAAC,OAAO,EAAoB,EAAE,EAAE,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAC,CAAC,CAAC,CAAA;IAE7F,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAC,IAAI,EAAiB,EAAE,EAAE;QACjD,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;QAC1B,eAAe,EAAE,GAAG,EAAE,CAAA;QACtB,eAAe,GAAG,IAAI,CAAA;QACtB,OAAO,CAAC,EAAC,IAAI,EAAE,cAAc,EAAC,CAAC,CAAA;IACjC,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,UAAU,EAAE,GAAG,EAAE;YACf,eAAe,EAAE,OAAO,EAAE,CAAA;YAC1B,MAAM,CAAC,KAAK,EAAE,CAAA;YACd,MAAM,CAAC,UAAU,EAAE,CAAA;QACrB,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Share host (server side) — Alice runs `tunli share <port>`.
|
|
3
|
+
*
|
|
4
|
+
* Connects to the relay's `/share` Socket.IO namespace and registers
|
|
5
|
+
* with her public key. The relay bridges incoming client connections
|
|
6
|
+
* to this socket. For each session, a TCP connection is opened to the
|
|
7
|
+
* local target (host:port) and data is piped in both directions.
|
|
8
|
+
*
|
|
9
|
+
* Required relay events (server → client):
|
|
10
|
+
* share-registered — registration confirmed
|
|
11
|
+
* share-error {message} — registration or session error
|
|
12
|
+
* share-client {sessionId} — a client has connected
|
|
13
|
+
* share-data {sessionId, data: Buffer} — data from a client
|
|
14
|
+
* share-end {sessionId} — client disconnected
|
|
15
|
+
*
|
|
16
|
+
* Required relay events (client → server):
|
|
17
|
+
* share-register {publicKey} — register as share host
|
|
18
|
+
* share-data {sessionId, data: Buffer}
|
|
19
|
+
* share-end {sessionId}
|
|
20
|
+
*/
|
|
21
|
+
import type { ServerConfig } from '#types/types';
|
|
22
|
+
import { type Identity } from '#identity/identity';
|
|
23
|
+
export type ShareHostEvent = {
|
|
24
|
+
type: 'registered';
|
|
25
|
+
} | {
|
|
26
|
+
type: 'client-connected';
|
|
27
|
+
sessionId: string;
|
|
28
|
+
publicKey: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'client-disconnected';
|
|
31
|
+
sessionId: string;
|
|
32
|
+
publicKey: string;
|
|
33
|
+
} | {
|
|
34
|
+
type: 'error';
|
|
35
|
+
message: string;
|
|
36
|
+
};
|
|
37
|
+
export declare const createShareHost: (serverConfig: ServerConfig, socketUrl: string, socketPath: string, identity: Identity, targetHost: string, targetPort: number, onEvent: (event: ShareHostEvent) => void) => {
|
|
38
|
+
disconnect: () => void;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=ShareHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareHost.d.ts","sourceRoot":"","sources":["../../src/share/ShareHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAkB,KAAK,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAEjE,MAAM,MAAM,cAAc,GACtB;IAAC,IAAI,EAAE,YAAY,CAAA;CAAC,GACpB;IAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,GAChE;IAAC,IAAI,EAAE,qBAAqB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,GACnE;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAA;AAEpC,eAAO,MAAM,eAAe,GAC1B,cAAc,YAAY,EAC1B,WAAW,MAAM,EACjB,YAAY,MAAM,EAClB,UAAU,QAAQ,EAClB,YAAY,MAAM,EAClB,YAAY,MAAM,EAClB,SAAS,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,KACvC;IAAC,UAAU,EAAE,MAAM,IAAI,CAAA;CAoEzB,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Share host (server side) — Alice runs `tunli share <port>`.
|
|
3
|
+
*
|
|
4
|
+
* Connects to the relay's `/share` Socket.IO namespace and registers
|
|
5
|
+
* with her public key. The relay bridges incoming client connections
|
|
6
|
+
* to this socket. For each session, a TCP connection is opened to the
|
|
7
|
+
* local target (host:port) and data is piped in both directions.
|
|
8
|
+
*
|
|
9
|
+
* Required relay events (server → client):
|
|
10
|
+
* share-registered — registration confirmed
|
|
11
|
+
* share-error {message} — registration or session error
|
|
12
|
+
* share-client {sessionId} — a client has connected
|
|
13
|
+
* share-data {sessionId, data: Buffer} — data from a client
|
|
14
|
+
* share-end {sessionId} — client disconnected
|
|
15
|
+
*
|
|
16
|
+
* Required relay events (client → server):
|
|
17
|
+
* share-register {publicKey} — register as share host
|
|
18
|
+
* share-data {sessionId, data: Buffer}
|
|
19
|
+
* share-end {sessionId}
|
|
20
|
+
*/
|
|
21
|
+
import net from 'node:net';
|
|
22
|
+
import { io } from 'socket.io-client';
|
|
23
|
+
import { encodePublicKey } from '#identity/identity';
|
|
24
|
+
export const createShareHost = (serverConfig, socketUrl, socketPath, identity, targetHost, targetPort, onEvent) => {
|
|
25
|
+
const shareUrl = socketUrl.replace(/\/$/, '') + '/share';
|
|
26
|
+
const socket = io(shareUrl, {
|
|
27
|
+
path: socketPath,
|
|
28
|
+
auth: { token: serverConfig.authToken },
|
|
29
|
+
});
|
|
30
|
+
const sessions = new Map();
|
|
31
|
+
const sessionKeys = new Map(); // sessionId → publicKey
|
|
32
|
+
socket.on('connect', () => {
|
|
33
|
+
socket.emit('share-register', { publicKey: encodePublicKey(identity.publicKeyRaw) });
|
|
34
|
+
});
|
|
35
|
+
socket.on('share-registered', () => onEvent({ type: 'registered' }));
|
|
36
|
+
socket.on('share-error', ({ message }) => onEvent({ type: 'error', message }));
|
|
37
|
+
socket.on('share-client', ({ sessionId, publicKey }) => {
|
|
38
|
+
// Bob registered — just remember the key, TCP opens on share-session-start
|
|
39
|
+
sessionKeys.set(sessionId, publicKey);
|
|
40
|
+
onEvent({ type: 'client-connected', sessionId, publicKey });
|
|
41
|
+
});
|
|
42
|
+
socket.on('share-session-start', ({ sessionId }) => {
|
|
43
|
+
const publicKey = sessionKeys.get(sessionId) ?? 'unknown';
|
|
44
|
+
const tcp = net.connect(targetPort, targetHost);
|
|
45
|
+
sessions.set(sessionId, tcp);
|
|
46
|
+
tcp.on('data', (chunk) => socket.emit('share-data', { sessionId, data: chunk }));
|
|
47
|
+
const closeSession = () => {
|
|
48
|
+
if (!sessions.has(sessionId))
|
|
49
|
+
return;
|
|
50
|
+
sessions.delete(sessionId);
|
|
51
|
+
sessionKeys.delete(sessionId);
|
|
52
|
+
socket.emit('share-end', { sessionId });
|
|
53
|
+
onEvent({ type: 'client-disconnected', sessionId, publicKey });
|
|
54
|
+
};
|
|
55
|
+
tcp.on('end', closeSession);
|
|
56
|
+
tcp.on('error', (e) => {
|
|
57
|
+
onEvent({ type: 'error', message: `Could not connect to ${targetHost}:${targetPort} — ${e.message}` });
|
|
58
|
+
closeSession();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
socket.on('share-data', ({ sessionId, data }) => {
|
|
62
|
+
sessions.get(sessionId)?.write(Buffer.from(data));
|
|
63
|
+
});
|
|
64
|
+
socket.on('share-end', ({ sessionId }) => {
|
|
65
|
+
const tcp = sessions.get(sessionId);
|
|
66
|
+
if (!tcp)
|
|
67
|
+
return;
|
|
68
|
+
const publicKey = sessionKeys.get(sessionId) ?? 'unknown';
|
|
69
|
+
sessions.delete(sessionId);
|
|
70
|
+
sessionKeys.delete(sessionId);
|
|
71
|
+
tcp.end();
|
|
72
|
+
onEvent({ type: 'client-disconnected', sessionId, publicKey });
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
disconnect: () => {
|
|
76
|
+
for (const tcp of sessions.values())
|
|
77
|
+
tcp.destroy();
|
|
78
|
+
sessions.clear();
|
|
79
|
+
socket.disconnect();
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=ShareHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareHost.js","sourceRoot":"","sources":["../../src/share/ShareHost.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED