dsh-zen-remote 2.2.9 → 2.3.2
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 +2 -2
- package/README.zh-CN.md +2 -2
- package/docs/interface.md +1 -1
- package/docs/remote-access.md +20 -0
- package/lan-gate.mjs +11 -1
- package/lib/adapters/dsh-better-sidebar/index.js +6 -2
- package/lib/adapters/dsh-better-sidebar/index.js.map +1 -1
- package/lib/adapters/dsh-better-sidebar/methods.js +3 -0
- package/lib/adapters/dsh-better-sidebar/methods.js.map +1 -1
- package/lib/admin-routes.js +33 -2
- package/lib/admin-routes.js.map +1 -1
- package/lib/client.js +3293 -6
- package/lib/config.js +70 -0
- package/lib/config.js.map +1 -1
- package/lib/index.js +232 -2
- package/lib/index.js.map +1 -1
- package/lib/intercept.js +43 -3
- package/lib/intercept.js.map +1 -1
- package/lib/lan-gate-server.cjs +58 -3
- package/lib/merge-streams.js +42 -12
- package/lib/merge-streams.js.map +1 -1
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts +1 -1
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts.map +1 -1
- package/lib/types/adapters/dsh-better-sidebar/methods.d.ts.map +1 -1
- package/lib/types/admin-routes.d.ts +13 -0
- package/lib/types/admin-routes.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +204 -1
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/wizard/GatewayWizard.d.ts +29 -0
- package/lib/types/client/wizard/GatewayWizard.d.ts.map +1 -0
- package/lib/types/client/wizard/WizardCard.d.ts +30 -0
- package/lib/types/client/wizard/WizardCard.d.ts.map +1 -0
- package/lib/types/client/wizard/cards/MigrateCard.d.ts +15 -0
- package/lib/types/client/wizard/cards/MigrateCard.d.ts.map +1 -0
- package/lib/types/client/wizard/cards/PortForwardCard.d.ts +15 -0
- package/lib/types/client/wizard/cards/PortForwardCard.d.ts.map +1 -0
- package/lib/types/client/wizard/cards/ProxyCard.d.ts +19 -0
- package/lib/types/client/wizard/cards/ProxyCard.d.ts.map +1 -0
- package/lib/types/client/wizard/cards/TokenCard.d.ts +20 -0
- package/lib/types/client/wizard/cards/TokenCard.d.ts.map +1 -0
- package/lib/types/client/wizard/register-wizard.d.ts +51 -0
- package/lib/types/client/wizard/register-wizard.d.ts.map +1 -0
- package/lib/types/client/wizard/wizard-css.d.ts +10 -0
- package/lib/types/client/wizard/wizard-css.d.ts.map +1 -0
- package/lib/types/client-data/qr.d.ts +20 -0
- package/lib/types/client-data/qr.d.ts.map +1 -0
- package/lib/types/client-data/settings-form.d.ts +7 -2
- package/lib/types/client-data/settings-form.d.ts.map +1 -1
- package/lib/types/client-data/wizard.d.ts +247 -0
- package/lib/types/client-data/wizard.d.ts.map +1 -0
- package/lib/types/config.d.ts +27 -0
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/intercept.d.ts.map +1 -1
- package/lib/types/merge-streams.d.ts.map +1 -1
- package/lib/types/wizard/binary-io.d.ts +111 -0
- package/lib/types/wizard/binary-io.d.ts.map +1 -0
- package/lib/types/wizard/binary.d.ts +118 -0
- package/lib/types/wizard/binary.d.ts.map +1 -0
- package/lib/types/wizard/caddy-process.d.ts +101 -0
- package/lib/types/wizard/caddy-process.d.ts.map +1 -0
- package/lib/types/wizard/caddy.d.ts +53 -0
- package/lib/types/wizard/caddy.d.ts.map +1 -0
- package/lib/types/wizard/cloudflare.d.ts +112 -0
- package/lib/types/wizard/cloudflare.d.ts.map +1 -0
- package/lib/types/wizard/cloudflared.d.ts +71 -0
- package/lib/types/wizard/cloudflared.d.ts.map +1 -0
- package/lib/types/wizard/probe.d.ts +66 -0
- package/lib/types/wizard/probe.d.ts.map +1 -0
- package/lib/types/wizard/proxy-snippets.d.ts +60 -0
- package/lib/types/wizard/proxy-snippets.d.ts.map +1 -0
- package/lib/types/wizard/routes.d.ts +152 -0
- package/lib/types/wizard/routes.d.ts.map +1 -0
- package/lib/types/wizard/source-detect.d.ts +53 -0
- package/lib/types/wizard/source-detect.d.ts.map +1 -0
- package/lib/types/wizard/status.d.ts +115 -0
- package/lib/types/wizard/status.d.ts.map +1 -0
- package/lib/types/wizard/token-store.d.ts +27 -0
- package/lib/types/wizard/token-store.d.ts.map +1 -0
- package/lib/types/wizard/tunnel-orchestrator.d.ts +90 -0
- package/lib/types/wizard/tunnel-orchestrator.d.ts.map +1 -0
- package/lib/types/wizard/verify.d.ts +97 -0
- package/lib/types/wizard/verify.d.ts.map +1 -0
- package/lib/wizard/binary-io.js +386 -0
- package/lib/wizard/binary-io.js.map +1 -0
- package/lib/wizard/binary.js +138 -0
- package/lib/wizard/binary.js.map +1 -0
- package/lib/wizard/caddy-process.js +162 -0
- package/lib/wizard/caddy-process.js.map +1 -0
- package/lib/wizard/caddy.js +80 -0
- package/lib/wizard/caddy.js.map +1 -0
- package/lib/wizard/cloudflare.js +334 -0
- package/lib/wizard/cloudflare.js.map +1 -0
- package/lib/wizard/cloudflared.js +158 -0
- package/lib/wizard/cloudflared.js.map +1 -0
- package/lib/wizard/probe.js +118 -0
- package/lib/wizard/probe.js.map +1 -0
- package/lib/wizard/proxy-snippets.js +112 -0
- package/lib/wizard/proxy-snippets.js.map +1 -0
- package/lib/wizard/routes.js +462 -0
- package/lib/wizard/routes.js.map +1 -0
- package/lib/wizard/source-detect.js +77 -0
- package/lib/wizard/source-detect.js.map +1 -0
- package/lib/wizard/status.js +94 -0
- package/lib/wizard/status.js.map +1 -0
- package/lib/wizard/token-store.js +71 -0
- package/lib/wizard/token-store.js.map +1 -0
- package/lib/wizard/tunnel-orchestrator.js +155 -0
- package/lib/wizard/tunnel-orchestrator.js.map +1 -0
- package/lib/wizard/verify.js +171 -0
- package/lib/wizard/verify.js.map +1 -0
- package/package.json +37 -37
- package/scripts/check-settings-form.mjs +5 -4
- package/scripts/check-wizard-ui.mjs +690 -0
- package/src/adapters/dsh-better-sidebar/index.ts +6 -2
- package/src/adapters/dsh-better-sidebar/methods.ts +3 -0
- package/src/admin-routes.ts +44 -2
- package/src/client/index.tsx +9 -0
- package/src/client/locales.ts +410 -2
- package/src/client/wizard/GatewayWizard.tsx +2224 -0
- package/src/client/wizard/WizardCard.tsx +81 -0
- package/src/client/wizard/cards/MigrateCard.tsx +42 -0
- package/src/client/wizard/cards/PortForwardCard.tsx +37 -0
- package/src/client/wizard/cards/ProxyCard.tsx +56 -0
- package/src/client/wizard/cards/TokenCard.tsx +81 -0
- package/src/client/wizard/register-wizard.ts +99 -0
- package/src/client/wizard/wizard-css.ts +948 -0
- package/src/client-data/qr.ts +284 -0
- package/src/client-data/settings-form.ts +12 -3
- package/src/client-data/wizard.ts +432 -0
- package/src/config.ts +87 -0
- package/src/index.ts +227 -2
- package/src/intercept.ts +43 -3
- package/src/merge-streams.ts +41 -12
- package/src/wizard/binary-io.ts +449 -0
- package/src/wizard/binary.ts +177 -0
- package/src/wizard/caddy-process.ts +228 -0
- package/src/wizard/caddy.ts +97 -0
- package/src/wizard/cloudflare.ts +413 -0
- package/src/wizard/cloudflared.ts +196 -0
- package/src/wizard/probe.ts +161 -0
- package/src/wizard/proxy-snippets.ts +128 -0
- package/src/wizard/routes.ts +537 -0
- package/src/wizard/source-detect.ts +87 -0
- package/src/wizard/status.ts +180 -0
- package/src/wizard/token-store.ts +73 -0
- package/src/wizard/tunnel-orchestrator.ts +197 -0
- package/src/wizard/verify.ts +236 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../src/wizard/cloudflare.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cloudflared process lifecycle (GW-7, 路 C's last mile). The tunnel's
|
|
3
|
+
* connector runs in the foreground (`tunnel run`) as a child of the DSH
|
|
4
|
+
* host, managed through the same subprocess service as the gateway child
|
|
5
|
+
* and the managed Caddy.
|
|
6
|
+
*
|
|
7
|
+
* The connector secret NEVER touches argv (visible to every process on
|
|
8
|
+
* the machine via ps) and is never an environment variable either — it is
|
|
9
|
+
* written to `<DSH_HOME>/zen-remote-ingress/tunnel-token`, mode 0600,
|
|
10
|
+
* through a temp-file-then-rename so a crash mid-write can never leave a
|
|
11
|
+
* half token at the real path, and handed to cloudflared with
|
|
12
|
+
* `--token-file`.
|
|
13
|
+
*
|
|
14
|
+
* Idempotency and cleanup mirror caddy-process.ts: a live child refuses a
|
|
15
|
+
* second start (stop first to switch tunnels), stop is idempotent, and an
|
|
16
|
+
* exited child clears its own slot. The host wiring hands stop to
|
|
17
|
+
* ctx.effect so the row's disposal kills cloudflared too.
|
|
18
|
+
*/
|
|
19
|
+
import { type DownloadProgress } from './binary-io.js';
|
|
20
|
+
import { type BinaryPlatform } from './binary.js';
|
|
21
|
+
import type { SubprocessServiceLike } from './caddy-process.js';
|
|
22
|
+
/** Where the connector secret lives (design.md: 不进 Config 的字段). */
|
|
23
|
+
export declare function tunnelTokenPath(dshHome: string): string;
|
|
24
|
+
/** Whether a non-empty tunnel-token file exists (the projection's boolean
|
|
25
|
+
* only — GW-fix-4/M1: the manager's EXISTENCE says nothing about whether a
|
|
26
|
+
* token has been stored). */
|
|
27
|
+
export declare function tunnelTokenConfigured(dshHome: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Persist the tunnel connector secret: 0600, atomic (write the `.part`
|
|
30
|
+
* sibling, then rename over the real path).
|
|
31
|
+
*/
|
|
32
|
+
export declare function writeTunnelTokenFile(dshHome: string, token: string): string;
|
|
33
|
+
export interface CloudflaredManagerOptions {
|
|
34
|
+
/** The host's subprocess service (ctx.subprocess). */
|
|
35
|
+
subprocess: SubprocessServiceLike;
|
|
36
|
+
/** `<DSH_HOME>` — the binary and the token file live under it. */
|
|
37
|
+
dshHome: string;
|
|
38
|
+
/** Injected transport for the one-time binary download (tests). */
|
|
39
|
+
fetchImpl?: typeof fetch;
|
|
40
|
+
/** Forced platform mapping (tests). */
|
|
41
|
+
platform?: BinaryPlatform;
|
|
42
|
+
/** Download progress relay (bytes, declared total or null). */
|
|
43
|
+
onProgress?: DownloadProgress;
|
|
44
|
+
/** Stdio byte caps for the child, both streams. Default 64 KiB. */
|
|
45
|
+
maxLogBytes?: number;
|
|
46
|
+
}
|
|
47
|
+
export type CloudflaredStartResult = {
|
|
48
|
+
ok: true;
|
|
49
|
+
binaryPath: string;
|
|
50
|
+
tokenFile: string;
|
|
51
|
+
alreadyRunning: false;
|
|
52
|
+
} | {
|
|
53
|
+
ok: false;
|
|
54
|
+
error: 'already-running' | 'missing-token' | 'download-failed' | 'spawn-failed';
|
|
55
|
+
detail?: string;
|
|
56
|
+
installUrl?: string;
|
|
57
|
+
};
|
|
58
|
+
export interface CloudflaredManager {
|
|
59
|
+
/** Idempotent front door: a live cloudflared refuses a second start. */
|
|
60
|
+
start(input: {
|
|
61
|
+
tunnelToken: unknown;
|
|
62
|
+
}): Promise<CloudflaredStartResult>;
|
|
63
|
+
/** Idempotent terminate; safe before any start. */
|
|
64
|
+
stop(): void;
|
|
65
|
+
/** Whether a child is currently held. */
|
|
66
|
+
isRunning(): boolean;
|
|
67
|
+
/** Whether any start has succeeded in this manager's lifetime. */
|
|
68
|
+
hasStarted(): boolean;
|
|
69
|
+
}
|
|
70
|
+
export declare function createCloudflaredManager(options: CloudflaredManagerOptions): CloudflaredManager;
|
|
71
|
+
//# sourceMappingURL=cloudflared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflared.d.ts","sourceRoot":"","sources":["../../../src/wizard/cloudflared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EAAqC,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACzF,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,KAAK,EAAE,qBAAqB,EAAwB,MAAM,oBAAoB,CAAA;AAErF,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;6BAE6B;AAC7B,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM9D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAiB3E;AAED,MAAM,WAAW,yBAAyB;IACxC,sDAAsD;IACtD,UAAU,EAAE,qBAAqB,CAAA;IACjC,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAA;IACf,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,gBAAgB,CAAA;IAC7B,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,KAAK,CAAA;CAAE,GAC1E;IACA,EAAE,EAAE,KAAK,CAAA;IACT,KAAK,EAAE,iBAAiB,GAAG,eAAe,GAAG,iBAAiB,GAAG,cAAc,CAAA;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAEH,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,KAAK,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACvE,mDAAmD;IACnD,IAAI,IAAI,IAAI,CAAA;IACZ,yCAAyC;IACzC,SAAS,IAAI,OAAO,CAAA;IACpB,kEAAkE;IAClE,UAAU,IAAI,OAAO,CAAA;CACtB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,kBAAkB,CAgG/F"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hostPath probe (GW-8): the server machine walks its OWN public URL and
|
|
3
|
+
* classifies what answers, so the wizard can say something sharper than
|
|
4
|
+
* "it didn't work" — the pairing page showing up means TLS + proxying to
|
|
5
|
+
* the gateway both work; the admin surface answering 200 means the proxy
|
|
6
|
+
* is DROPPING the forwarded headers the gateway trusts; a redirect smells
|
|
7
|
+
* like Cloudflare Access or a proxy rewriting to a login page.
|
|
8
|
+
*
|
|
9
|
+
* Split exactly as the ticket asks: the two `classify*Response` functions
|
|
10
|
+
* are pure (the check scripts can drive them), `probeHostPath` owns the
|
|
11
|
+
* fetch I/O — `redirect: 'manual'` so a proxy's 3xx is SEEN, never
|
|
12
|
+
* followed — with the URL admission reusing client-pairing's
|
|
13
|
+
* `normalizeServerUrl` (https anywhere; plain http only for the explicit
|
|
14
|
+
* private-network allowances) and a 10 s ceiling per request.
|
|
15
|
+
*/
|
|
16
|
+
/** What answered on `GET <publicUrl>/`. */
|
|
17
|
+
export type RootClassification = 'gateway-pairing-page' | 'unexpected-401' | 'unexpected-200' | 'redirect' | 'unexpected';
|
|
18
|
+
/** What answered on `GET <publicUrl>/lan-gate/admin`. */
|
|
19
|
+
export type AdminClassification = 'gateway-admin-403' | 'admin-exposed' | 'proxy-403' | 'unexpected';
|
|
20
|
+
/**
|
|
21
|
+
* `GET /`: the ONE right answer is the gateway's pairing page — 401,
|
|
22
|
+
* text/html, carrying the claim-endpoint marker the page's own script
|
|
23
|
+
* posts to. A 200 means the URL belongs to something else entirely.
|
|
24
|
+
*/
|
|
25
|
+
export declare function classifyRootResponse(status: number, contentType: string, body: string): RootClassification;
|
|
26
|
+
/**
|
|
27
|
+
* `GET /lan-gate/admin`: right is the gateway's own 403 JSON — a public
|
|
28
|
+
* visitor must not get in. 200 + HTML is the DANGEROUS shape: something
|
|
29
|
+
* answered with a page, meaning the proxy forwarded without the
|
|
30
|
+
* forwarded headers and the gateway's local-only wall never saw a
|
|
31
|
+
* proxied request (the admin page leaked). 403 + HTML smells like
|
|
32
|
+
* Cloudflare Access interposing its own login.
|
|
33
|
+
*/
|
|
34
|
+
export declare function classifyAdminResponse(status: number, contentType: string, body: string): AdminClassification;
|
|
35
|
+
export interface HostPathReached {
|
|
36
|
+
kind: 'reached';
|
|
37
|
+
root: RootClassification;
|
|
38
|
+
admin: AdminClassification;
|
|
39
|
+
/** Wall-clock cost of both requests, milliseconds. */
|
|
40
|
+
ms: number;
|
|
41
|
+
}
|
|
42
|
+
export interface HostPathUnreachable {
|
|
43
|
+
kind: 'unreachable';
|
|
44
|
+
/** `invalid-url` / `insecure-http` — the URL never stood a chance;
|
|
45
|
+
* `timeout` — the 10 s ceiling fired; `network` — DNS, refused, reset. */
|
|
46
|
+
reason: 'invalid-url' | 'insecure-http' | 'timeout' | 'network';
|
|
47
|
+
detail?: string;
|
|
48
|
+
ms: number;
|
|
49
|
+
}
|
|
50
|
+
export type HostPathOutcome = HostPathReached | HostPathUnreachable;
|
|
51
|
+
export interface ProbeOptions {
|
|
52
|
+
fetchImpl?: typeof fetch;
|
|
53
|
+
/** Per-request ceiling. Default 10 000 ms (the ticket's value). */
|
|
54
|
+
timeoutMs?: number;
|
|
55
|
+
/** Clock for the `ms` measurement (tests). */
|
|
56
|
+
now?: () => number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Probe the machine's public URL from here: both the root path and the
|
|
60
|
+
* admin surface, never following a redirect. The two requests run
|
|
61
|
+
* concurrently; the answer carries both classifications and the elapsed
|
|
62
|
+
* time. Every failure mode is a VALUE (`kind: 'unreachable'`), never a
|
|
63
|
+
* throw — the wizard routes render whichever verdict arrived.
|
|
64
|
+
*/
|
|
65
|
+
export declare function probeHostPath(publicUrl: unknown, options?: ProbeOptions): Promise<HostPathOutcome>;
|
|
66
|
+
//# sourceMappingURL=probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../../src/wizard/probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,2CAA2C;AAC3C,MAAM,MAAM,kBAAkB,GAC1B,sBAAsB,GACtB,gBAAgB,GAChB,gBAAgB,GAChB,UAAU,GACV,YAAY,CAAA;AAEhB,yDAAyD;AACzD,MAAM,MAAM,mBAAmB,GAC3B,mBAAmB,GACnB,eAAe,GACf,WAAW,GACX,YAAY,CAAA;AAEhB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAQ1G;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAkB5G;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,kBAAkB,CAAA;IACxB,KAAK,EAAE,mBAAmB,CAAA;IAC1B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,CAAA;IACnB;8EAC0E;IAC1E,MAAM,EAAE,aAAa,GAAG,eAAe,GAAG,SAAS,GAAG,SAAS,CAAA;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,mBAAmB,CAAA;AAEnE,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAqBD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CA+B5G"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reverse-proxy configuration snippets (GW-5, 路 B) — for the user who
|
|
3
|
+
* ALREADY runs their own proxy, the wizard hands out copy-paste material
|
|
4
|
+
* instead of managing a process. Everything here is pure text generation:
|
|
5
|
+
* every interpolated value passes a charset gate (the domain through
|
|
6
|
+
* config.ts's `hostOf`, the upstream host likewise, the port in [1,
|
|
7
|
+
* 65535]), so a hostile form value cannot smuggle a directive into
|
|
8
|
+
* anyone's nginx.
|
|
9
|
+
*
|
|
10
|
+
* The upstream port is the gateway's ACTUAL port — the caller reads it
|
|
11
|
+
* from the running gateway (it may have retried past the configured one),
|
|
12
|
+
* never from config.
|
|
13
|
+
*/
|
|
14
|
+
export type SnippetResult = {
|
|
15
|
+
ok: true;
|
|
16
|
+
text: string;
|
|
17
|
+
} | {
|
|
18
|
+
ok: false;
|
|
19
|
+
error: 'bad-domain' | 'bad-upstream-host' | 'bad-upstream-port';
|
|
20
|
+
};
|
|
21
|
+
export interface SnippetInput {
|
|
22
|
+
/** Public domain the proxy terminates TLS for (bare hostname). */
|
|
23
|
+
domain: unknown;
|
|
24
|
+
/** Where the gateway listens — a hostname or IP literal (e.g. the
|
|
25
|
+
* loopback default). */
|
|
26
|
+
upstreamHost: unknown;
|
|
27
|
+
/** The gateway's ACTUAL port. */
|
|
28
|
+
upstreamPort: unknown;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* nginx: a complete server block. The WebSocket upgrade map sits outside
|
|
32
|
+
* the server (http-level context) — the snippet says so in a comment, the
|
|
33
|
+
* user pastes it into the http/server scope their setup offers. Long
|
|
34
|
+
* idle tunnels need the 3600s read/send timeouts, uploads the 128m
|
|
35
|
+
* client body cap, and streaming the buffering switch — all three are
|
|
36
|
+
* the shapes DSH's relay traffic actually needs.
|
|
37
|
+
*/
|
|
38
|
+
export declare function nginxSnippet(input: SnippetInput): SnippetResult;
|
|
39
|
+
/**
|
|
40
|
+
* Caddy (user-operated, not the wizard-managed one): the site block is
|
|
41
|
+
* one `reverse_proxy` line — Caddy routes the rest itself.
|
|
42
|
+
*/
|
|
43
|
+
export declare function caddySnippet(input: SnippetInput): SnippetResult;
|
|
44
|
+
export type StepsResult = {
|
|
45
|
+
ok: true;
|
|
46
|
+
steps: string[];
|
|
47
|
+
} | {
|
|
48
|
+
ok: false;
|
|
49
|
+
error: 'bad-upstream-host' | 'bad-upstream-port';
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Lucky (Web 服务反代) three steps: listen 443, proxy to the upstream,
|
|
53
|
+
* flip the catch-all switch. Text only — Lucky has no config file format
|
|
54
|
+
* to generate.
|
|
55
|
+
*/
|
|
56
|
+
export declare function luckySteps(input: {
|
|
57
|
+
upstreamHost: unknown;
|
|
58
|
+
upstreamPort: unknown;
|
|
59
|
+
}): StepsResult;
|
|
60
|
+
//# sourceMappingURL=proxy-snippets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-snippets.d.ts","sourceRoot":"","sources":["../../../src/wizard/proxy-snippets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,CAAA;CAAE,CAAA;AAElF,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAA;IACf;4BACwB;IACxB,YAAY,EAAE,OAAO,CAAA;IACrB,iCAAiC;IACjC,YAAY,EAAE,OAAO,CAAA;CACtB;AAiBD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAiC/D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAW/D;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,GAAG,mBAAmB,CAAA;CAAE,CAAA;AAEnE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAAE,YAAY,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,GAAG,WAAW,CAa/F"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard route skeleton (GW-4, extended by GW-5): every
|
|
3
|
+
* `/_dsh/zen-remote/admin/wizard/*` route the gateway wizard serves, with
|
|
4
|
+
* the security walls applied to ALL of them, in this order:
|
|
5
|
+
*
|
|
6
|
+
* 1. `connection.admit` — webServer-registered routes skip DSH's `/api`
|
|
7
|
+
* authentication, so each request asks the connection service first;
|
|
8
|
+
* its rejection is relayed verbatim (401/403).
|
|
9
|
+
* 2. The gateway marker. A request wearing `x-zen-remote-via` came
|
|
10
|
+
* THROUGH the gateway from a remote device. Unlike the admin status
|
|
11
|
+
* route there is no read-only exception: the wizard is a server-owner
|
|
12
|
+
* surface, and a remote device gets a flat 403 `via-gateway` — GET
|
|
13
|
+
* included. The marker wall runs BEFORE same-origin because a
|
|
14
|
+
* forwarded request presents as same-origin (the gateway rewrites
|
|
15
|
+
* Origin/Host onto the upstream origin); the marker is the only thing
|
|
16
|
+
* identifying it.
|
|
17
|
+
* 3. `sameOriginPost` for every POST.
|
|
18
|
+
*
|
|
19
|
+
* Real routes: `GET /wizard/status` (the sanitized projection from
|
|
20
|
+
* status.ts — reads only, never mutates) and, since GW-5, `POST
|
|
21
|
+
* /wizard/trust-proxy` (merge one detected proxy IP into the persisted
|
|
22
|
+
* `trustedProxies` list). Every other POST under the prefix is a 501
|
|
23
|
+
* placeholder; later tasks fill those in. GET /status answers from a
|
|
24
|
+
* per-request config resolution and the injected runtime probe; a throwing
|
|
25
|
+
* runtime probe degrades to "nothing configured" instead of failing the
|
|
26
|
+
* read.
|
|
27
|
+
*
|
|
28
|
+
* The handler is built by a factory so the tests drive it over a real
|
|
29
|
+
* socket with mock admit/config (same seam as the admin routes).
|
|
30
|
+
*/
|
|
31
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
32
|
+
import type { AdminAdmission, AdminConfigSnapshot } from '../admin-routes.js';
|
|
33
|
+
import type { ConfigSource } from '../config.js';
|
|
34
|
+
import type { CaddyStartResult } from './caddy-process.js';
|
|
35
|
+
import type { TunnelCheckResult, TunnelSetupResult } from './tunnel-orchestrator.js';
|
|
36
|
+
import { type WizardRuntimeInput } from './status.js';
|
|
37
|
+
import type { VerificationCheckResult, VerificationStartResult } from './verify.js';
|
|
38
|
+
/** Prefix all wizard routes live under (one webServer prefix registration;
|
|
39
|
+
* the host web server matches longest-prefix-first, so these win over the
|
|
40
|
+
* plain admin prefix registration). */
|
|
41
|
+
export declare const WIZARD_ROUTE_PREFIX = "/_dsh/zen-remote/admin/wizard";
|
|
42
|
+
/** GET: the sanitized wizard status projection. */
|
|
43
|
+
export declare const WIZARD_STATUS_ROUTE = "/_dsh/zen-remote/admin/wizard/status";
|
|
44
|
+
/** POST `{ip}`: merge one detected reverse-proxy IP into the persisted
|
|
45
|
+
* trustedProxies (GW-5). */
|
|
46
|
+
export declare const WIZARD_TRUST_PROXY_ROUTE = "/_dsh/zen-remote/admin/wizard/trust-proxy";
|
|
47
|
+
/** POST `{publicUrl}`: start the final verification — mint the web pairing
|
|
48
|
+
* code (GW-9). GET: poll its status. */
|
|
49
|
+
export declare const WIZARD_VERIFY_ROUTE = "/_dsh/zen-remote/admin/wizard/verify";
|
|
50
|
+
/** POST `{token}`: store the Cloudflare API token 0600 on this machine;
|
|
51
|
+
* DELETE: stop the consumers and remove it (GW-13a). */
|
|
52
|
+
export declare const WIZARD_CF_TOKEN_ROUTE = "/_dsh/zen-remote/admin/wizard/cf-token";
|
|
53
|
+
/** POST `{token}`: store the cloudflared connector token (GW-13a). */
|
|
54
|
+
export declare const WIZARD_TUNNEL_TOKEN_ROUTE = "/_dsh/zen-remote/admin/wizard/tunnel-token";
|
|
55
|
+
/** POST: start the managed Caddy from the saved row config; POST (stop)
|
|
56
|
+
* terminates it; GET answers its three-state (GW-13a). */
|
|
57
|
+
export declare const WIZARD_CADDY_START_ROUTE = "/_dsh/zen-remote/admin/wizard/caddy/start";
|
|
58
|
+
export declare const WIZARD_CADDY_STOP_ROUTE = "/_dsh/zen-remote/admin/wizard/caddy/stop";
|
|
59
|
+
export declare const WIZARD_CADDY_STATUS_ROUTE = "/_dsh/zen-remote/admin/wizard/caddy/status";
|
|
60
|
+
/** POST `{domain}`: the zone/account probe the migration card re-checks;
|
|
61
|
+
* POST `{domain, tunnelId?}`: the full tunnel setup; POST (stop) and GET
|
|
62
|
+
* (three-state) mirror the Caddy pair (GW-13b). */
|
|
63
|
+
export declare const WIZARD_TUNNEL_CHECK_ROUTE = "/_dsh/zen-remote/admin/wizard/tunnel/check-domain";
|
|
64
|
+
export declare const WIZARD_TUNNEL_SETUP_ROUTE = "/_dsh/zen-remote/admin/wizard/tunnel/setup";
|
|
65
|
+
export declare const WIZARD_TUNNEL_STOP_ROUTE = "/_dsh/zen-remote/admin/wizard/tunnel/stop";
|
|
66
|
+
export declare const WIZARD_TUNNEL_STATUS_ROUTE = "/_dsh/zen-remote/admin/wizard/tunnel/status";
|
|
67
|
+
/** The managed Caddy's three-state. `stopped` means a start happened and
|
|
68
|
+
* the process has since exited (degraded); `never-started` precedes that. */
|
|
69
|
+
export type CaddyProcessState = 'running' | 'stopped' | 'never-started';
|
|
70
|
+
export interface WizardHandlerOptions {
|
|
71
|
+
/** The connection service's admit, injected by apply(); tests fake it. */
|
|
72
|
+
admit: (req: IncomingMessage) => AdminAdmission;
|
|
73
|
+
/** Fresh resolveConfig() per call — the ingress fields are volatile row
|
|
74
|
+
* fields and must not go stale. */
|
|
75
|
+
getConfig: () => AdminConfigSnapshot;
|
|
76
|
+
/** The live wizard runtime facts (token presence as booleans, process
|
|
77
|
+
* liveness, the gateway's actual port, probe memories, the untrusted-
|
|
78
|
+
* proxy detection), read PER REQUEST. MAY be async (the GW-5 wiring
|
|
79
|
+
* rounds-trips the gateway's own status). MUST be read-only — GET
|
|
80
|
+
* /status calls it, and a GET never changes state. Absent means
|
|
81
|
+
* "nothing configured, nothing running"; a throw is degraded to the
|
|
82
|
+
* same. Later tasks inject the real probe. */
|
|
83
|
+
getRuntime?: () => WizardRuntimeInput | Promise<WizardRuntimeInput>;
|
|
84
|
+
/** The trust-proxy persistence (GW-5, GW-fix-2/L2), injected by apply():
|
|
85
|
+
* the CURRENTLY resolved trustedProxies with its layer, and the atomic
|
|
86
|
+
* persister for a merged list. `write` re-checks the persisted surface
|
|
87
|
+
* against `expected` (the value `resolved` answered moments earlier) —
|
|
88
|
+
* answering false when another writer moved it in between, which the
|
|
89
|
+
* route turns into a 409 instead of a silent clobber. Absent — a wiring
|
|
90
|
+
* that predates GW-5 — and the route answers 501 like the other
|
|
91
|
+
* placeholders. */
|
|
92
|
+
trustProxy?: {
|
|
93
|
+
resolved: () => {
|
|
94
|
+
value: string;
|
|
95
|
+
source: ConfigSource;
|
|
96
|
+
};
|
|
97
|
+
write: (expected: string, list: string) => boolean | Promise<boolean>;
|
|
98
|
+
};
|
|
99
|
+
/** The Cloudflare token store (GW-13a), injected by apply(): 0600 files
|
|
100
|
+
* under the ingress directory. `deleteCfToken` is called AFTER the
|
|
101
|
+
* callers have stopped the consuming processes. Absent — a wiring that
|
|
102
|
+
* predates GW-13 — and the routes answer 501. */
|
|
103
|
+
tokenStore?: {
|
|
104
|
+
writeCfToken: (token: string) => void;
|
|
105
|
+
deleteCfToken: () => void;
|
|
106
|
+
cfTokenConfigured: () => boolean;
|
|
107
|
+
writeTunnelToken: (token: string) => void;
|
|
108
|
+
};
|
|
109
|
+
/** The managed Caddy (GW-13a), injected by apply(). `start` receives the
|
|
110
|
+
* SAVED row values and the gateway's actual port; the Cloudflare token
|
|
111
|
+
* comes from the token store inside the wiring (never through routes). */
|
|
112
|
+
caddy?: {
|
|
113
|
+
start: (input: {
|
|
114
|
+
domain: string;
|
|
115
|
+
httpsPort: number;
|
|
116
|
+
gatewayPort: number;
|
|
117
|
+
}) => Promise<CaddyStartResult>;
|
|
118
|
+
stop: () => void;
|
|
119
|
+
status: () => CaddyProcessState;
|
|
120
|
+
};
|
|
121
|
+
/** The Cloudflare Tunnel orchestration (GW-13b), injected by apply().
|
|
122
|
+
* `setup` receives the SAVED domain and (when the user adopted an
|
|
123
|
+
* existing tunnel) its id; the Cloudflare token comes from the token
|
|
124
|
+
* store inside the wiring. Absent — unwired — and the routes 501. */
|
|
125
|
+
tunnel?: {
|
|
126
|
+
checkDomain: (domain: string) => Promise<TunnelCheckResult>;
|
|
127
|
+
setup: (input: {
|
|
128
|
+
domain: string;
|
|
129
|
+
tunnelId?: string;
|
|
130
|
+
}) => Promise<TunnelSetupResult>;
|
|
131
|
+
stop: () => void;
|
|
132
|
+
status: () => CaddyProcessState;
|
|
133
|
+
};
|
|
134
|
+
/** The final-verification orchestration (GW-9), injected by apply():
|
|
135
|
+
* POST mints the pairing code, GET polls the session. Absent — a wiring
|
|
136
|
+
* that predates GW-9 — and both answer 501 like the placeholders. */
|
|
137
|
+
verify?: {
|
|
138
|
+
start: (input: {
|
|
139
|
+
publicUrl: unknown;
|
|
140
|
+
probeOnly?: boolean;
|
|
141
|
+
}) => Promise<VerificationStartResult>;
|
|
142
|
+
check: () => Promise<VerificationCheckResult>;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export type WizardHandler = (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
146
|
+
/**
|
|
147
|
+
* Build the wizard route handler for one plugin row. The returned handler
|
|
148
|
+
* owns the full response lifecycle of every request under
|
|
149
|
+
* {@link WIZARD_ROUTE_PREFIX} and never throws.
|
|
150
|
+
*/
|
|
151
|
+
export declare function createWizardHandler(options: WizardHandlerOptions): WizardHandler;
|
|
152
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/wizard/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reverse-proxy source detection (GW-5), pure logic — the browser-facing
|
|
3
|
+
* half of the 「检测到反代从 {ip} 连过来,自动信任?」flow.
|
|
4
|
+
*
|
|
5
|
+
* The gateway (lib/lan-gate-server.cjs) records the last request that
|
|
6
|
+
* carried proxy headers from a socket it does NOT trust — almost always
|
|
7
|
+
* the user's own reverse proxy whose IP never made it into
|
|
8
|
+
* `trustedProxies` — as `lastForwardedSource: { ip, at }` in its
|
|
9
|
+
* `/lan-gate/status` answer. {@link detectForwardedSource} lifts that
|
|
10
|
+
* field out (defensively: the gateway may be old and send nothing), and
|
|
11
|
+
* {@link mergeProxyList} / {@link normalizeTrustedIp} build the merged
|
|
12
|
+
* trust list the trust-proxy route persists.
|
|
13
|
+
*
|
|
14
|
+
* Pure: no imports, no I/O — the check scripts can drive it directly.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* The recognized shape of the gateway's `lastForwardedSource`. Everything
|
|
18
|
+
* else — missing field (an older gateway), junk values — reads as "no
|
|
19
|
+
* detection".
|
|
20
|
+
*/
|
|
21
|
+
export interface ForwardedSourceInput {
|
|
22
|
+
ip?: unknown;
|
|
23
|
+
at?: unknown;
|
|
24
|
+
}
|
|
25
|
+
export interface DetectedForwardedSource {
|
|
26
|
+
ip: string;
|
|
27
|
+
at: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract the untrusted-proxy detection from one `/lan-gate/status` body.
|
|
31
|
+
* Returns null when the gateway predates the field or the field is
|
|
32
|
+
* malformed — a missing detection is the common case, never an error.
|
|
33
|
+
*/
|
|
34
|
+
export declare function detectForwardedSource(gatewayStatus: unknown): DetectedForwardedSource | null;
|
|
35
|
+
/**
|
|
36
|
+
* One trust-list entry: an IP literal, normalized the way the gateway
|
|
37
|
+
* normalizes socket peers (`::ffff:` IPv4-in-IPv6 unwrapped). Refuses
|
|
38
|
+
* anything that is not a plausible IPv4/IPv6 literal — the value goes
|
|
39
|
+
* into persisted config and later into an exact string comparison
|
|
40
|
+
* against socket peers, where a hostname or a CIDR would silently never
|
|
41
|
+
* match.
|
|
42
|
+
*/
|
|
43
|
+
export declare function normalizeTrustedIp(raw: unknown): string | undefined;
|
|
44
|
+
/** Split the comma-separated trustedProxies value into entries. */
|
|
45
|
+
export declare function parseProxyList(value: unknown): string[];
|
|
46
|
+
/**
|
|
47
|
+
* Append one IP to the comma-separated list, preserving order, skipping
|
|
48
|
+
* duplicates (the trust-proxy route answers "already trusted" instead of
|
|
49
|
+
* rewriting). Normalization is the caller's job — the route normalizes
|
|
50
|
+
* before merging.
|
|
51
|
+
*/
|
|
52
|
+
export declare function mergeProxyList(current: unknown, ip: string): string;
|
|
53
|
+
//# sourceMappingURL=source-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-detect.d.ts","sourceRoot":"","sources":["../../../src/wizard/source-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,EAAE,CAAC,EAAE,OAAO,CAAA;CACb;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI,CAQ5F;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAcnE;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAInE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard status projection (GW-1): declared ingress config + observed
|
|
3
|
+
* runtime facts → one sanitized JSON shape the browser may see.
|
|
4
|
+
*
|
|
5
|
+
* This module is the SECURITY BOUNDARY for everything the wizard surfaces
|
|
6
|
+
* on `GET /_dsh/zen-remote/admin/wizard/status`. The two properties it must
|
|
7
|
+
* hold, regardless of what the callers hand it:
|
|
8
|
+
*
|
|
9
|
+
* 1. No secret material. The Cloudflare API token and the cloudflared
|
|
10
|
+
* tunnel token never enter this module — the runtime side reports only
|
|
11
|
+
* `*Configured` booleans (the files live 0600 under
|
|
12
|
+
* `<DSH_HOME>/zen-remote-ingress/`, and their contents stay there).
|
|
13
|
+
* 2. No file paths. The runtime side knows where binaries, token files
|
|
14
|
+
* and the Caddyfile live; the projection carries none of it — every
|
|
15
|
+
* output field is built from a whitelist below, and input objects are
|
|
16
|
+
* never spread through.
|
|
17
|
+
*
|
|
18
|
+
* Pure logic on purpose: zero imports, so the check scripts and the tests
|
|
19
|
+
* can drive it through Node's strip-only type stripping, and the wizard
|
|
20
|
+
* routes can call it per request without re-resolving anything.
|
|
21
|
+
*
|
|
22
|
+
* Every input is coerced defensively. The declared side normally arrives
|
|
23
|
+
* from `resolveConfig(...).values` (already legal), but the projection is
|
|
24
|
+
* also the last line of defense for the wire: an off-enum mode answers
|
|
25
|
+
* `'off'`, a junk port answers the 443 default, a non-string domain answers
|
|
26
|
+
* `''` — same transparency discipline as the config resolver, applied at
|
|
27
|
+
* the rendering edge.
|
|
28
|
+
*/
|
|
29
|
+
/** The ingress modes `resolveConfig` can legally produce. */
|
|
30
|
+
export declare const WIZARD_INGRESS_MODES: readonly ["off", "caddy", "external", "cloudflared"];
|
|
31
|
+
export type WizardIngressMode = (typeof WIZARD_INGRESS_MODES)[number];
|
|
32
|
+
/**
|
|
33
|
+
* The declared slice of the resolved config. Loose (`unknown`) on purpose:
|
|
34
|
+
* the projection is what guarantees the wire shape, not the caller's typing.
|
|
35
|
+
*/
|
|
36
|
+
export interface WizardDeclaredInput {
|
|
37
|
+
ingressMode?: unknown;
|
|
38
|
+
ingressDomain?: unknown;
|
|
39
|
+
ingressHttpsPort?: unknown;
|
|
40
|
+
ingressPublicUrl?: unknown;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* One probe / verification memory the wizard back-end keeps. Only these
|
|
44
|
+
* three fields are recognized; everything else on the record (URLs probed,
|
|
45
|
+
* error details, headers) is dropped at the boundary.
|
|
46
|
+
*/
|
|
47
|
+
export interface WizardRecordInput {
|
|
48
|
+
result?: unknown;
|
|
49
|
+
deviceId?: unknown;
|
|
50
|
+
at?: unknown;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The gateway's own detection of an untrusted reverse proxy (GW-5): the
|
|
54
|
+
* socket peer of the last request that carried proxy headers from an IP
|
|
55
|
+
* outside `trustedProxies` — almost certainly the user's own proxy, and
|
|
56
|
+
* the one IP the trust-proxy flow offers to add. Whitelist-projected like
|
|
57
|
+
* everything else.
|
|
58
|
+
*/
|
|
59
|
+
export interface WizardForwardedSourceInput {
|
|
60
|
+
ip?: unknown;
|
|
61
|
+
at?: unknown;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Runtime facts the wizard back-end observes live. Everything is optional —
|
|
65
|
+
* a composition that has not started any ingress process simply omits the
|
|
66
|
+
* fields. Token presence is reported as booleans only; port as the gateway
|
|
67
|
+
* child's ACTUAL listening port (it may differ from the configured one).
|
|
68
|
+
*/
|
|
69
|
+
export interface WizardRuntimeInput {
|
|
70
|
+
cfTokenConfigured?: unknown;
|
|
71
|
+
tunnelTokenConfigured?: unknown;
|
|
72
|
+
caddyRunning?: unknown;
|
|
73
|
+
cloudflaredRunning?: unknown;
|
|
74
|
+
gatewayActualPort?: unknown;
|
|
75
|
+
lanAddress?: unknown;
|
|
76
|
+
lastHostProbe?: WizardRecordInput | null;
|
|
77
|
+
lastExternalVerification?: WizardRecordInput | null;
|
|
78
|
+
lastForwardedSource?: WizardForwardedSourceInput | null;
|
|
79
|
+
}
|
|
80
|
+
/** One projected probe / verification memory, or null when there is none. */
|
|
81
|
+
export interface WizardStatusRecord {
|
|
82
|
+
result: string;
|
|
83
|
+
deviceId: string | null;
|
|
84
|
+
at: number | null;
|
|
85
|
+
}
|
|
86
|
+
/** One projected untrusted-proxy detection, or null when none is pending. */
|
|
87
|
+
export interface WizardStatusForwardedSource {
|
|
88
|
+
ip: string;
|
|
89
|
+
at: number;
|
|
90
|
+
}
|
|
91
|
+
/** The full sanitized status the wizard status route answers with. */
|
|
92
|
+
export interface WizardStatus {
|
|
93
|
+
ok: true;
|
|
94
|
+
mode: WizardIngressMode;
|
|
95
|
+
domain: string;
|
|
96
|
+
httpsPort: number;
|
|
97
|
+
publicUrl: string;
|
|
98
|
+
cfTokenConfigured: boolean;
|
|
99
|
+
tunnelTokenConfigured: boolean;
|
|
100
|
+
caddyRunning: boolean;
|
|
101
|
+
cloudflaredRunning: boolean;
|
|
102
|
+
gatewayActualPort: number | null;
|
|
103
|
+
lanAddress?: string;
|
|
104
|
+
lastHostProbe: WizardStatusRecord | null;
|
|
105
|
+
lastExternalVerification: WizardStatusRecord | null;
|
|
106
|
+
lastForwardedSource: WizardStatusForwardedSource | null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Build the sanitized wizard status. Both arguments are optional so a
|
|
110
|
+
* composition can answer before anything is configured; the all-empty
|
|
111
|
+
* answer is the honest "wizard not started" state (`mode: 'off'`, no ports,
|
|
112
|
+
* no tokens configured, no memories).
|
|
113
|
+
*/
|
|
114
|
+
export declare function projectWizardStatus(declared?: WizardDeclaredInput, runtime?: WizardRuntimeInput): WizardStatus;
|
|
115
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/wizard/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB,sDAAuD,CAAA;AAExF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAErE;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,EAAE,CAAC,EAAE,OAAO,CAAA;CACb;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,EAAE,CAAC,EAAE,OAAO,CAAA;CACb;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACxC,wBAAwB,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACnD,mBAAmB,CAAC,EAAE,0BAA0B,GAAG,IAAI,CAAA;CACxD;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;CAClB;AAED,6EAA6E;AAC7E,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED,sEAAsE;AACtE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,IAAI,CAAA;IACR,IAAI,EAAE,iBAAiB,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,qBAAqB,EAAE,OAAO,CAAA;IAC9B,YAAY,EAAE,OAAO,CAAA;IACrB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAAA;IACxC,wBAAwB,EAAE,kBAAkB,GAAG,IAAI,CAAA;IACnD,mBAAmB,EAAE,2BAA2B,GAAG,IAAI,CAAA;CACxD;AAyCD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,GAAE,mBAAwB,EAAE,OAAO,GAAE,kBAAuB,GAAG,YAAY,CAiBtH"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard token storage (GW-13a): the secrets that must never enter the
|
|
3
|
+
* plugin row or any wire response live as 0600 files under
|
|
4
|
+
* `<DSH_HOME>/zen-remote-ingress/`, written through a temp-file rename so
|
|
5
|
+
* a crash mid-write can never leave a half token at the real path. The
|
|
6
|
+
* tunnel-token half lives in cloudflared.ts (it is the cloudflared
|
|
7
|
+
* process's own input); this module owns the shared Cloudflare API token.
|
|
8
|
+
*
|
|
9
|
+
* Reads answer presence or hand the raw string ONLY to in-process callers
|
|
10
|
+
* (the Caddy manager's env) — nothing here is ever logged or serialized
|
|
11
|
+
* into a response.
|
|
12
|
+
*/
|
|
13
|
+
/** `<DSH_HOME>/zen-remote-ingress/cf-api-token`. */
|
|
14
|
+
export declare function cfTokenPath(dshHome: string): string;
|
|
15
|
+
/** Atomic 0600 write (temp sibling + rename), with a direct-write fallback
|
|
16
|
+
* on Windows if an existing file or antivirus scan refuses `renameSync` with
|
|
17
|
+
* EPERM/EACCES. */
|
|
18
|
+
export declare function writeCfTokenFile(dshHome: string, token: string): string;
|
|
19
|
+
/** The stored token, or undefined when absent/empty. Callers feed it to the
|
|
20
|
+
* Caddy manager's environment; it must never reach a response or a log. */
|
|
21
|
+
export declare function readCfTokenFile(dshHome: string): string | undefined;
|
|
22
|
+
/** Whether a non-empty token file exists (the projection's boolean only). */
|
|
23
|
+
export declare function cfTokenConfigured(dshHome: string): boolean;
|
|
24
|
+
/** Delete the stored token (the DELETE route; callers stop the processes
|
|
25
|
+
* that consume it first). */
|
|
26
|
+
export declare function deleteCfTokenFile(dshHome: string): void;
|
|
27
|
+
//# sourceMappingURL=token-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../../src/wizard/token-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;mBAEmB;AACnB,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBvE;AAED;2EAC2E;AAC3E,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOnE;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM1D;AAED;6BAC6B;AAC7B,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEvD"}
|