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.
Files changed (149) hide show
  1. package/README.md +2 -2
  2. package/README.zh-CN.md +2 -2
  3. package/docs/interface.md +1 -1
  4. package/docs/remote-access.md +20 -0
  5. package/lan-gate.mjs +11 -1
  6. package/lib/adapters/dsh-better-sidebar/index.js +6 -2
  7. package/lib/adapters/dsh-better-sidebar/index.js.map +1 -1
  8. package/lib/adapters/dsh-better-sidebar/methods.js +3 -0
  9. package/lib/adapters/dsh-better-sidebar/methods.js.map +1 -1
  10. package/lib/admin-routes.js +33 -2
  11. package/lib/admin-routes.js.map +1 -1
  12. package/lib/client.js +3293 -6
  13. package/lib/config.js +70 -0
  14. package/lib/config.js.map +1 -1
  15. package/lib/index.js +232 -2
  16. package/lib/index.js.map +1 -1
  17. package/lib/intercept.js +43 -3
  18. package/lib/intercept.js.map +1 -1
  19. package/lib/lan-gate-server.cjs +58 -3
  20. package/lib/merge-streams.js +42 -12
  21. package/lib/merge-streams.js.map +1 -1
  22. package/lib/types/adapters/dsh-better-sidebar/index.d.ts +1 -1
  23. package/lib/types/adapters/dsh-better-sidebar/index.d.ts.map +1 -1
  24. package/lib/types/adapters/dsh-better-sidebar/methods.d.ts.map +1 -1
  25. package/lib/types/admin-routes.d.ts +13 -0
  26. package/lib/types/admin-routes.d.ts.map +1 -1
  27. package/lib/types/client/index.d.ts.map +1 -1
  28. package/lib/types/client/locales.d.ts +204 -1
  29. package/lib/types/client/locales.d.ts.map +1 -1
  30. package/lib/types/client/wizard/GatewayWizard.d.ts +29 -0
  31. package/lib/types/client/wizard/GatewayWizard.d.ts.map +1 -0
  32. package/lib/types/client/wizard/WizardCard.d.ts +30 -0
  33. package/lib/types/client/wizard/WizardCard.d.ts.map +1 -0
  34. package/lib/types/client/wizard/cards/MigrateCard.d.ts +15 -0
  35. package/lib/types/client/wizard/cards/MigrateCard.d.ts.map +1 -0
  36. package/lib/types/client/wizard/cards/PortForwardCard.d.ts +15 -0
  37. package/lib/types/client/wizard/cards/PortForwardCard.d.ts.map +1 -0
  38. package/lib/types/client/wizard/cards/ProxyCard.d.ts +19 -0
  39. package/lib/types/client/wizard/cards/ProxyCard.d.ts.map +1 -0
  40. package/lib/types/client/wizard/cards/TokenCard.d.ts +20 -0
  41. package/lib/types/client/wizard/cards/TokenCard.d.ts.map +1 -0
  42. package/lib/types/client/wizard/register-wizard.d.ts +51 -0
  43. package/lib/types/client/wizard/register-wizard.d.ts.map +1 -0
  44. package/lib/types/client/wizard/wizard-css.d.ts +10 -0
  45. package/lib/types/client/wizard/wizard-css.d.ts.map +1 -0
  46. package/lib/types/client-data/qr.d.ts +20 -0
  47. package/lib/types/client-data/qr.d.ts.map +1 -0
  48. package/lib/types/client-data/settings-form.d.ts +7 -2
  49. package/lib/types/client-data/settings-form.d.ts.map +1 -1
  50. package/lib/types/client-data/wizard.d.ts +247 -0
  51. package/lib/types/client-data/wizard.d.ts.map +1 -0
  52. package/lib/types/config.d.ts +27 -0
  53. package/lib/types/config.d.ts.map +1 -1
  54. package/lib/types/index.d.ts.map +1 -1
  55. package/lib/types/intercept.d.ts.map +1 -1
  56. package/lib/types/merge-streams.d.ts.map +1 -1
  57. package/lib/types/wizard/binary-io.d.ts +111 -0
  58. package/lib/types/wizard/binary-io.d.ts.map +1 -0
  59. package/lib/types/wizard/binary.d.ts +118 -0
  60. package/lib/types/wizard/binary.d.ts.map +1 -0
  61. package/lib/types/wizard/caddy-process.d.ts +101 -0
  62. package/lib/types/wizard/caddy-process.d.ts.map +1 -0
  63. package/lib/types/wizard/caddy.d.ts +53 -0
  64. package/lib/types/wizard/caddy.d.ts.map +1 -0
  65. package/lib/types/wizard/cloudflare.d.ts +112 -0
  66. package/lib/types/wizard/cloudflare.d.ts.map +1 -0
  67. package/lib/types/wizard/cloudflared.d.ts +71 -0
  68. package/lib/types/wizard/cloudflared.d.ts.map +1 -0
  69. package/lib/types/wizard/probe.d.ts +66 -0
  70. package/lib/types/wizard/probe.d.ts.map +1 -0
  71. package/lib/types/wizard/proxy-snippets.d.ts +60 -0
  72. package/lib/types/wizard/proxy-snippets.d.ts.map +1 -0
  73. package/lib/types/wizard/routes.d.ts +152 -0
  74. package/lib/types/wizard/routes.d.ts.map +1 -0
  75. package/lib/types/wizard/source-detect.d.ts +53 -0
  76. package/lib/types/wizard/source-detect.d.ts.map +1 -0
  77. package/lib/types/wizard/status.d.ts +115 -0
  78. package/lib/types/wizard/status.d.ts.map +1 -0
  79. package/lib/types/wizard/token-store.d.ts +27 -0
  80. package/lib/types/wizard/token-store.d.ts.map +1 -0
  81. package/lib/types/wizard/tunnel-orchestrator.d.ts +90 -0
  82. package/lib/types/wizard/tunnel-orchestrator.d.ts.map +1 -0
  83. package/lib/types/wizard/verify.d.ts +97 -0
  84. package/lib/types/wizard/verify.d.ts.map +1 -0
  85. package/lib/wizard/binary-io.js +386 -0
  86. package/lib/wizard/binary-io.js.map +1 -0
  87. package/lib/wizard/binary.js +138 -0
  88. package/lib/wizard/binary.js.map +1 -0
  89. package/lib/wizard/caddy-process.js +162 -0
  90. package/lib/wizard/caddy-process.js.map +1 -0
  91. package/lib/wizard/caddy.js +80 -0
  92. package/lib/wizard/caddy.js.map +1 -0
  93. package/lib/wizard/cloudflare.js +334 -0
  94. package/lib/wizard/cloudflare.js.map +1 -0
  95. package/lib/wizard/cloudflared.js +158 -0
  96. package/lib/wizard/cloudflared.js.map +1 -0
  97. package/lib/wizard/probe.js +118 -0
  98. package/lib/wizard/probe.js.map +1 -0
  99. package/lib/wizard/proxy-snippets.js +112 -0
  100. package/lib/wizard/proxy-snippets.js.map +1 -0
  101. package/lib/wizard/routes.js +462 -0
  102. package/lib/wizard/routes.js.map +1 -0
  103. package/lib/wizard/source-detect.js +77 -0
  104. package/lib/wizard/source-detect.js.map +1 -0
  105. package/lib/wizard/status.js +94 -0
  106. package/lib/wizard/status.js.map +1 -0
  107. package/lib/wizard/token-store.js +71 -0
  108. package/lib/wizard/token-store.js.map +1 -0
  109. package/lib/wizard/tunnel-orchestrator.js +155 -0
  110. package/lib/wizard/tunnel-orchestrator.js.map +1 -0
  111. package/lib/wizard/verify.js +171 -0
  112. package/lib/wizard/verify.js.map +1 -0
  113. package/package.json +37 -37
  114. package/scripts/check-settings-form.mjs +5 -4
  115. package/scripts/check-wizard-ui.mjs +690 -0
  116. package/src/adapters/dsh-better-sidebar/index.ts +6 -2
  117. package/src/adapters/dsh-better-sidebar/methods.ts +3 -0
  118. package/src/admin-routes.ts +44 -2
  119. package/src/client/index.tsx +9 -0
  120. package/src/client/locales.ts +410 -2
  121. package/src/client/wizard/GatewayWizard.tsx +2224 -0
  122. package/src/client/wizard/WizardCard.tsx +81 -0
  123. package/src/client/wizard/cards/MigrateCard.tsx +42 -0
  124. package/src/client/wizard/cards/PortForwardCard.tsx +37 -0
  125. package/src/client/wizard/cards/ProxyCard.tsx +56 -0
  126. package/src/client/wizard/cards/TokenCard.tsx +81 -0
  127. package/src/client/wizard/register-wizard.ts +99 -0
  128. package/src/client/wizard/wizard-css.ts +948 -0
  129. package/src/client-data/qr.ts +284 -0
  130. package/src/client-data/settings-form.ts +12 -3
  131. package/src/client-data/wizard.ts +432 -0
  132. package/src/config.ts +87 -0
  133. package/src/index.ts +227 -2
  134. package/src/intercept.ts +43 -3
  135. package/src/merge-streams.ts +41 -12
  136. package/src/wizard/binary-io.ts +449 -0
  137. package/src/wizard/binary.ts +177 -0
  138. package/src/wizard/caddy-process.ts +228 -0
  139. package/src/wizard/caddy.ts +97 -0
  140. package/src/wizard/cloudflare.ts +413 -0
  141. package/src/wizard/cloudflared.ts +196 -0
  142. package/src/wizard/probe.ts +161 -0
  143. package/src/wizard/proxy-snippets.ts +128 -0
  144. package/src/wizard/routes.ts +537 -0
  145. package/src/wizard/source-detect.ts +87 -0
  146. package/src/wizard/status.ts +180 -0
  147. package/src/wizard/token-store.ts +73 -0
  148. package/src/wizard/tunnel-orchestrator.ts +197 -0
  149. package/src/wizard/verify.ts +236 -0
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Ingress binary arithmetic (GW-2): platform mapping, download-URL
3
+ * construction and install-path computation for the two binaries the
4
+ * gateway wizard manages — Caddy (custom build with the Cloudflare DNS
5
+ * module, for DNS-01 certificates) and cloudflared (the tunnel client).
6
+ *
7
+ * Pure by contract: URL strings, path strings and platform facts only —
8
+ * every touch of the filesystem or the network lives in binary-io.ts, and
9
+ * the routes layer reads both. `node:path`/`node:os` here are arithmetic,
10
+ * not I/O: the same discipline as virtual-id.ts's zero-dependency rule,
11
+ * relaxed one notch because path building is this module's whole job.
12
+ *
13
+ * Platform coverage mirrors what both upstream distribution points actually
14
+ * ship: darwin/linux/windows × amd64/arm64. macOS arm64's cloudflared asset
15
+ * is a `.tgz` (the only archive shape in the set) — binary-io unpacks it.
16
+ */
17
+ import { join } from 'node:path';
18
+ import { homedir } from 'node:os';
19
+ /** This process's platform, mapped into the download points' naming. */
20
+ export function currentPlatform() {
21
+ if (process.platform === 'win32')
22
+ return { os: 'windows', arch: 'amd64' };
23
+ const arch = process.arch === 'arm64' ? 'arm64' : 'amd64';
24
+ if (process.platform === 'darwin')
25
+ return { os: 'darwin', arch };
26
+ return { os: 'linux', arch };
27
+ }
28
+ /** Caddy's custom-build API, pinned to the Cloudflare DNS module the
29
+ * DNS-01 challenge needs (plain Caddy cannot write the TXT record). */
30
+ export function caddyDownloadUrl(platform) {
31
+ return `https://caddyserver.com/api/download?os=${platform.os}&arch=${platform.arch}&p=github.com/caddy-dns/cloudflare`;
32
+ }
33
+ /**
34
+ * The Caddy asset the build API answers with, PLUS its archive shape —
35
+ * `caddyserver.com/api/download` returns a bare Mach-O/ELF binary on unix
36
+ * (`Content-Disposition: attachment; filename="caddy_<os>_<arch>_custom"`,
37
+ * `Content-Type: application/octet-stream`) and a bare `.exe` on Windows.
38
+ */
39
+ export function caddyDownload(platform) {
40
+ return { url: caddyDownloadUrl(platform), archive: platform.os === 'windows' ? 'exe' : 'none' };
41
+ }
42
+ /** cloudflared's GitHub Releases asset for one platform, plus the archive
43
+ * shape the I/O half must unwrap (darwin assets are `.tgz`, windows ships
44
+ * a bare `.exe`, linux a bare binary). */
45
+ export function cloudflaredDownload(platform) {
46
+ const base = 'https://github.com/cloudflare/cloudflared/releases/latest/download/';
47
+ if (platform.os === 'darwin')
48
+ return { url: `${base}cloudflared-darwin-${platform.arch}.tgz`, archive: 'tgz' };
49
+ if (platform.os === 'windows')
50
+ return { url: `${base}cloudflared-windows-amd64.exe`, archive: 'exe' };
51
+ return { url: `${base}cloudflared-linux-${platform.arch}`, archive: 'none' };
52
+ }
53
+ /** Both download URLs for one platform WITH their archive shapes, defaults
54
+ * to the running process's. The archive metadata — not a URL suffix — is
55
+ * what tells the I/O half how to unpack. */
56
+ export function binaryUrls(platform = currentPlatform()) {
57
+ const caddy = caddyDownload(platform);
58
+ const cloudflared = cloudflaredDownload(platform);
59
+ return { caddy: caddy.url, caddyArchive: caddy.archive, cloudflared: cloudflared.url, cloudflaredArchive: cloudflared.archive };
60
+ }
61
+ /** Official manual-install pages, surfaced by the UI when a download fails. */
62
+ export const MANUAL_INSTALL_LINKS = {
63
+ caddy: 'https://caddyserver.com/download',
64
+ cloudflared: 'https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/',
65
+ };
66
+ /** Everything ingress lives under this one directory of DSH_HOME. */
67
+ export const INGRESS_DIR_NAME = 'zen-remote-ingress';
68
+ /** `<DSH_HOME>` as the rest of the plugin resolves it (config.ts's convention). */
69
+ export function dshHomeDefault(env = process.env) {
70
+ return env.DSH_HOME ?? join(homedir(), '.dsh');
71
+ }
72
+ /** `<DSH_HOME>/zen-remote-ingress` — Caddyfile, data dir and bin/ sit here. */
73
+ export function ingressDir(dshHome) {
74
+ return join(dshHome, INGRESS_DIR_NAME);
75
+ }
76
+ /** `<DSH_HOME>/zen-remote-ingress/bin` — both binaries install here. */
77
+ export function binDir(dshHome) {
78
+ return join(ingressDir(dshHome), 'bin');
79
+ }
80
+ /** `<DSH_HOME>/zen-remote-ingress/Caddyfile` — generated, validated, then
81
+ * handed to `caddy run --config`. */
82
+ export function caddyfilePath(dshHome) {
83
+ return join(ingressDir(dshHome), 'Caddyfile');
84
+ }
85
+ /** `<DSH_HOME>/zen-remote-ingress/caddy-data` — certificates and the ACME
86
+ * account live here, kept out of the default Caddy home. */
87
+ export function caddyDataDir(dshHome) {
88
+ return join(ingressDir(dshHome), 'caddy-data');
89
+ }
90
+ /** The installed file name. Windows cannot spawn an extension-less image,
91
+ * so the `.exe` suffix is part of the install name there. */
92
+ export function binaryFileName(tool, platform = currentPlatform()) {
93
+ if (platform.os === 'windows')
94
+ return tool === 'caddy' ? 'caddy.exe' : 'cloudflared.exe';
95
+ return tool;
96
+ }
97
+ /** The absolute install path for one binary (where downloadBinary puts it). */
98
+ export function binaryInstallPath(dshHome, tool, platform = currentPlatform()) {
99
+ return join(binDir(dshHome), binaryFileName(tool, platform));
100
+ }
101
+ /** Prebuilt Caddy + `github.com/caddy-dns/cloudflare` release assets hosted
102
+ * on this repository's `caddy-cloudflare` GitHub Release (built by
103
+ * `.github/workflows/caddy-assets.yml`). Unlike `caddyserver.com/api/download`
104
+ * — which compiles on the fly and throttles downloads to ~13 KB/s — these
105
+ * static GitHub Release assets download in seconds and work with mainland
106
+ * China GitHub acceleration mirrors (`gh-proxy.com` / `ghfast.top`). */
107
+ export function caddyPrebuiltDownload(platform) {
108
+ const base = 'https://github.com/KyoMio/dsh-zen-remote/releases/download/caddy-cloudflare/';
109
+ if (platform.os === 'windows')
110
+ return { url: `${base}caddy-windows-amd64.exe`, archive: 'exe' };
111
+ return { url: `${base}caddy-${platform.os}-${platform.arch}.tgz`, archive: 'tgz' };
112
+ }
113
+ /** Mainland China GitHub release acceleration mirrors, tried first when the
114
+ * host environment is detected as mainland China (or tried as fallbacks if
115
+ * direct GitHub times out). */
116
+ export const GITHUB_MIRROR_PREFIXES = [
117
+ 'https://gh-proxy.com/',
118
+ 'https://ghfast.top/',
119
+ ];
120
+ /** Ordered candidate downloads for one binary and platform:
121
+ * - When `preferCnMirror` is true, GitHub Release URLs through mainland
122
+ * mirrors come first, followed by direct GitHub Release URL, and finally
123
+ * (for Caddy) the upstream `caddyserver.com/api/download` fallback.
124
+ * - When `preferCnMirror` is false, direct GitHub Release comes first, then
125
+ * mainland mirrors, then the upstream build API fallback. */
126
+ export function binaryDownloadCandidates(tool, platform = currentPlatform(), preferCnMirror = false) {
127
+ const primary = tool === 'caddy' ? caddyPrebuiltDownload(platform) : cloudflaredDownload(platform);
128
+ const mirrored = GITHUB_MIRROR_PREFIXES.map((prefix) => ({
129
+ url: `${prefix}${primary.url}`,
130
+ archive: primary.archive,
131
+ }));
132
+ const ordered = preferCnMirror ? [...mirrored, primary] : [primary, ...mirrored];
133
+ if (tool === 'caddy') {
134
+ ordered.push(caddyDownload(platform));
135
+ }
136
+ return ordered;
137
+ }
138
+ //# sourceMappingURL=binary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary.js","sourceRoot":"","sources":["../../src/wizard/binary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Managed-Caddy process lifecycle (GW-3). The Caddyfile's content is
3
+ * caddy.ts's job; this module owns everything with a heartbeat:
4
+ *
5
+ * start: ensureBinary (GW-2, cached after the first download) →
6
+ * generateCaddyfile (typed refusals) → write the Caddyfile as a
7
+ * `.part` sibling → `caddy validate --config <part> --adapter
8
+ * caddyfile` → only on a clean validate rename it to the real
9
+ * path → `caddy run --config <Caddyfile>`. The ticket's "validate
10
+ * before write" is honored as validate-before-PUBLISH: the final
11
+ * Caddyfile on disk only ever holds bytes Caddy accepted, and a
12
+ * failed validate leaves neither a start nor a published file.
13
+ *
14
+ * The Cloudflare API token travels in the child's ENVIRONMENT
15
+ * (`CF_API_TOKEN`, what the generated `{env.CF_API_TOKEN}` placeholder
16
+ * reads) — never in argv, which other processes on the machine can see.
17
+ *
18
+ * Idempotency: start with a live process refuses (`already-running`) —
19
+ * switching configuration stops first (design: 切换路时先停旧进程再启新的).
20
+ * stop is idempotent; an exited child clears its own slot so a later
21
+ * start works. The host wiring hands stop to ctx.effect, so the row's
22
+ * disposal kills Caddy too.
23
+ *
24
+ * The subprocess service is structural (the tests feed a recorder), and
25
+ * `fetch` is injectable for the ensureBinary step.
26
+ */
27
+ import { mkdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
28
+ import { ensureBinary, BinaryDownloadError } from './binary-io.js';
29
+ import { caddyDataDir, caddyfilePath, ingressDir } from './binary.js';
30
+ import { generateCaddyfile } from './caddy.js';
31
+ export function createCaddyManager(options) {
32
+ const { subprocess, dshHome } = options;
33
+ const maxLogBytes = options.maxLogBytes ?? 64 * 1024;
34
+ let handle = null;
35
+ let caddyfileArg;
36
+ let startedOnce = false;
37
+ // GW-fix-2/L3: a WHITELIST, not the host's full environment — the host
38
+ // process carries the relay secret and DSH's own credentials in env, and
39
+ // a child that only needs to reach the internet and the local disk has
40
+ // no business inheriting them. Include Windows system/profile variables so
41
+ // Go's TLS root-cert store and winsock initialize cleanly on Windows.
42
+ const childEnv = (cfToken) => {
43
+ const env = {};
44
+ for (const key of [
45
+ 'PATH', 'HOME', 'TMPDIR', 'LANG', 'TZ',
46
+ 'SystemRoot', 'SYSTEMROOT', 'windir', 'WINDIR',
47
+ 'USERPROFILE', 'APPDATA', 'LOCALAPPDATA', 'PROGRAMDATA', 'TEMP', 'TMP',
48
+ ]) {
49
+ if (process.env[key] !== undefined)
50
+ env[key] = process.env[key];
51
+ }
52
+ // The one secret this child needs, by env only (the Caddyfile reads
53
+ // {env.CF_API_TOKEN}) — never argv.
54
+ env.CF_API_TOKEN = cfToken;
55
+ return env;
56
+ };
57
+ const spawnChild = (argv, env) => subprocess.spawn({
58
+ argv,
59
+ cwd: dshHome,
60
+ env,
61
+ stdio: {
62
+ stdin: 'ignore',
63
+ stdout: { maxBytes: maxLogBytes },
64
+ stderr: { maxBytes: maxLogBytes },
65
+ },
66
+ graceMs: 3000,
67
+ });
68
+ return {
69
+ async start(input) {
70
+ if (handle !== null)
71
+ return { ok: false, error: 'already-running' };
72
+ const cfToken = typeof input.cfToken === 'string' && input.cfToken.trim() !== '' ? input.cfToken : undefined;
73
+ if (cfToken === undefined)
74
+ return { ok: false, error: 'missing-token' };
75
+ const generated = generateCaddyfile({ ...input, storageDir: caddyDataDir(dshHome) });
76
+ if (!generated.ok)
77
+ return { ok: false, error: 'bad-config', detail: generated.error };
78
+ let binaryPath;
79
+ try {
80
+ binaryPath = (await ensureBinary(dshHome, 'caddy', {
81
+ fetchImpl: options.fetchImpl,
82
+ platform: options.platform,
83
+ onProgress: options.onProgress,
84
+ })).path;
85
+ }
86
+ catch (error) {
87
+ if (error instanceof BinaryDownloadError) {
88
+ return { ok: false, error: 'download-failed', detail: error.message, installUrl: error.installUrl };
89
+ }
90
+ return { ok: false, error: 'download-failed', detail: String(error?.message ?? error) };
91
+ }
92
+ // Write → validate → publish: the `.part` file carries the exact
93
+ // bytes under validation, so what lands at the real path is exactly
94
+ // what Caddy accepted.
95
+ const finalPath = caddyfilePath(dshHome);
96
+ const partPath = `${finalPath}.part`;
97
+ try {
98
+ mkdirSync(ingressDir(dshHome), { recursive: true });
99
+ writeFileSync(partPath, generated.caddyfile, { mode: 0o600 });
100
+ const validate = spawnChild([binaryPath, 'validate', '--config', partPath, '--adapter', 'caddyfile'], childEnv(cfToken));
101
+ const outcome = await validate.done;
102
+ if ((outcome.exitCode ?? 1) !== 0) {
103
+ rmSync(partPath, { force: true });
104
+ return { ok: false, error: 'validate-failed' };
105
+ }
106
+ renameSync(partPath, finalPath);
107
+ }
108
+ catch (error) {
109
+ rmSync(partPath, { force: true });
110
+ return { ok: false, error: 'spawn-failed', detail: String(error?.message ?? error) };
111
+ }
112
+ const env = childEnv(cfToken);
113
+ try {
114
+ const child = spawnChild([binaryPath, 'run', '--config', finalPath], env);
115
+ handle = child;
116
+ caddyfileArg = finalPath;
117
+ startedOnce = true;
118
+ // An exited child clears its own slot: isRunning() goes honest and
119
+ // a later start() works without a manual stop.
120
+ void child.done.then(() => {
121
+ if (handle === child) {
122
+ handle = null;
123
+ caddyfileArg = undefined;
124
+ }
125
+ }).catch(() => {
126
+ if (handle === child) {
127
+ handle = null;
128
+ caddyfileArg = undefined;
129
+ }
130
+ });
131
+ return { ok: true, binaryPath, caddyfile: finalPath, alreadyRunning: false };
132
+ }
133
+ catch (error) {
134
+ handle = null;
135
+ caddyfileArg = undefined;
136
+ return { ok: false, error: 'spawn-failed', detail: String(error?.message ?? error) };
137
+ }
138
+ },
139
+ stop() {
140
+ if (handle === null)
141
+ return;
142
+ const child = handle;
143
+ handle = null;
144
+ caddyfileArg = undefined;
145
+ try {
146
+ void child.terminate();
147
+ }
148
+ catch {
149
+ // A dead child's terminate is a no-op or a throw — either way done.
150
+ }
151
+ },
152
+ isRunning: () => handle !== null,
153
+ runningCaddyfile: () => caddyfileArg,
154
+ /** Whether a start has EVER succeeded in this row's lifetime — the
155
+ * three-state status needs it to tell 已退出 (degraded) from 未启动. */
156
+ hasStarted: () => startedOnce,
157
+ };
158
+ }
159
+ /** Re-exported so the wiring (and later the routes) need one import for
160
+ * the whole ingress-directory layout. */
161
+ export { caddyDataDir, caddyfilePath, ingressDir };
162
+ //# sourceMappingURL=caddy-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caddy-process.js","sourceRoot":"","sources":["../../src/wizard/caddy-process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Caddyfile generation (GW-3), pure logic — every byte the managed Caddy
3
+ * will run comes out of {@link generateCaddyfile}, so the validation and
4
+ * the injection guards live HERE and the process half (caddy-process.ts)
5
+ * only writes, validates and spawns what this answered.
6
+ *
7
+ * Shape (design.md 路 A), with one deliberate correction to the design
8
+ * sketch: the global DNS-01 option in a real Caddyfile is `acme_dns
9
+ * <provider> <token-placeholder>` — the sketch's bare `dns cloudflare`
10
+ * line is site-block `tls` syntax and is not valid as a global option.
11
+ * The DNS-01 challenge itself is the point: the certificate is ordered
12
+ * through Cloudflare's API (the token rides the `CF_API_TOKEN`
13
+ * environment variable, never the file), so neither 80 nor 443 needs to
14
+ * be reachable from outside for issuance; only the HTTPS service port
15
+ * must be.
16
+ *
17
+ * Injection posture: every interpolated value passes a charset gate —
18
+ * the domain through config.ts's `hostOf` (the exact validator the row
19
+ * layer applies), the storage path free of control characters, quotes and
20
+ * braces (Caddyfile's block delimiters), the env-var name as a legal
21
+ * POSIX name. Nothing else from the outside world reaches the output.
22
+ */
23
+ import { hostOf } from '../config.js';
24
+ /** The default environment variable the Cloudflare token rides in on. */
25
+ export const CF_TOKEN_ENV_DEFAULT = 'CF_API_TOKEN';
26
+ /** Integers in [1, 65535] only. */
27
+ function portOf(value) {
28
+ return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= 65535 ? value : undefined;
29
+ }
30
+ /** Storage paths go into the Caddyfile quoted; anything that could break
31
+ * out of the quoting or forge a block delimiter is refused — control
32
+ * characters (newlines foremost), quotes, braces. */
33
+ function storageDirOf(value) {
34
+ if (typeof value !== 'string' || value === '')
35
+ return undefined;
36
+ // eslint-disable-next-line no-control-regex
37
+ if (/[\u0000-\u001f\u007f"{}]/.test(value))
38
+ return undefined;
39
+ return value;
40
+ }
41
+ /** Env names: POSIX uppercase convention, strictly. */
42
+ const ENV_NAME_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
43
+ /**
44
+ * Build the complete Caddyfile for the managed Caddy. Refuses (typed)
45
+ * instead of throwing so the caller can map each refusal to a form error.
46
+ */
47
+ export function generateCaddyfile(input) {
48
+ const domain = hostOf(input.domain);
49
+ if (domain === undefined)
50
+ return { ok: false, error: 'bad-domain' };
51
+ const httpsPort = portOf(input.httpsPort);
52
+ if (httpsPort === undefined)
53
+ return { ok: false, error: 'bad-https-port' };
54
+ const gatewayPort = portOf(input.gatewayPort);
55
+ if (gatewayPort === undefined)
56
+ return { ok: false, error: 'bad-gateway-port' };
57
+ const storageDir = storageDirOf(input.storageDir);
58
+ if (storageDir === undefined)
59
+ return { ok: false, error: 'bad-storage' };
60
+ const tokenEnv = typeof input.cfTokenEnvName === 'string' && ENV_NAME_PATTERN.test(input.cfTokenEnvName)
61
+ ? input.cfTokenEnvName
62
+ : CF_TOKEN_ENV_DEFAULT;
63
+ if (input.cfTokenEnvName !== undefined && input.cfTokenEnvName !== '' && tokenEnv !== input.cfTokenEnvName) {
64
+ return { ok: false, error: 'bad-token-env' };
65
+ }
66
+ const caddyfile = [
67
+ '{',
68
+ `\tacme_dns cloudflare {env.${tokenEnv}}`,
69
+ `\tstorage file_system "${storageDir}"`,
70
+ '\tadmin off',
71
+ '}',
72
+ '',
73
+ `https://${domain}:${httpsPort} {`,
74
+ `\treverse_proxy 127.0.0.1:${gatewayPort}`,
75
+ '}',
76
+ '',
77
+ ].join('\n');
78
+ return { ok: true, caddyfile, domain, httpsPort, gatewayPort };
79
+ }
80
+ //# sourceMappingURL=caddy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caddy.js","sourceRoot":"","sources":["../../src/wizard/caddy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,yEAAyE;AACzE,MAAM,CAAC,MAAM,oBAAoB,GAAG,cAAc,CAAA;AAoBlD,mCAAmC;AACnC,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACjH,CAAC;AAED;;qDAEqD;AACrD,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,SAAS,CAAA;IAC/D,4CAA4C;IAC5C,IAAI,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAC5D,OAAO,KAAK,CAAA;AACd,CAAC;AAED,uDAAuD;AACvD,MAAM,gBAAgB,GAAG,oBAAoB,CAAA;AAE7C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAqB;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACnC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAA;IACnE,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACzC,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAA;IAC1E,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IAC7C,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAA;IAC9E,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IACjD,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA;IACxE,MAAM,QAAQ,GAAG,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;QACtG,CAAC,CAAC,KAAK,CAAC,cAAc;QACtB,CAAC,CAAC,oBAAoB,CAAA;IACxB,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS,IAAI,KAAK,CAAC,cAAc,KAAK,EAAE,IAAI,QAAQ,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC;QAC3G,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAA;IAC9C,CAAC;IACD,MAAM,SAAS,GAAG;QAChB,GAAG;QACH,8BAA8B,QAAQ,GAAG;QACzC,0BAA0B,UAAU,GAAG;QACvC,aAAa;QACb,GAAG;QACH,EAAE;QACF,WAAW,MAAM,IAAI,SAAS,IAAI;QAClC,6BAA6B,WAAW,EAAE;QAC1C,GAAG;QACH,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAA;AAChE,CAAC"}