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,112 @@
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
+ import { hostOf } from '../config.js';
15
+ /** Integers in [1, 65535] only. */
16
+ function portOf(value) {
17
+ return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= 65535 ? value : undefined;
18
+ }
19
+ function validatedParts(input) {
20
+ const domain = hostOf(input.domain);
21
+ if (domain === undefined)
22
+ return { error: { ok: false, error: 'bad-domain' } };
23
+ const upstream = hostOf(input.upstreamHost);
24
+ if (upstream === undefined)
25
+ return { error: { ok: false, error: 'bad-upstream-host' } };
26
+ const port = portOf(input.upstreamPort);
27
+ if (port === undefined)
28
+ return { error: { ok: false, error: 'bad-upstream-port' } };
29
+ return { domain, upstream, port };
30
+ }
31
+ /**
32
+ * nginx: a complete server block. The WebSocket upgrade map sits outside
33
+ * the server (http-level context) — the snippet says so in a comment, the
34
+ * user pastes it into the http/server scope their setup offers. Long
35
+ * idle tunnels need the 3600s read/send timeouts, uploads the 128m
36
+ * client body cap, and streaming the buffering switch — all three are
37
+ * the shapes DSH's relay traffic actually needs.
38
+ */
39
+ export function nginxSnippet(input) {
40
+ const parts = validatedParts(input);
41
+ if ('error' in parts)
42
+ return parts.error;
43
+ const { domain, upstream, port } = parts;
44
+ const text = [
45
+ '# 这段放在 http {} 层(若已有同名 map 则跳过)',
46
+ 'map $http_upgrade $connection_upgrade {',
47
+ ' default upgrade;',
48
+ " '' close;",
49
+ '}',
50
+ '',
51
+ 'server {',
52
+ ' listen 443 ssl;',
53
+ ` server_name ${domain};`,
54
+ '',
55
+ ' location / {',
56
+ ` proxy_pass http://${upstream}:${port};`,
57
+ ' proxy_http_version 1.1;',
58
+ ' proxy_set_header Upgrade $http_upgrade;',
59
+ ' proxy_set_header Connection $connection_upgrade;',
60
+ ' proxy_set_header Host $host;',
61
+ ' proxy_set_header X-Real-IP $remote_addr;',
62
+ ' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;',
63
+ ' proxy_set_header X-Forwarded-Proto $scheme;',
64
+ ' proxy_buffering off;',
65
+ ' client_max_body_size 128m;',
66
+ ' proxy_read_timeout 3600s;',
67
+ ' proxy_send_timeout 3600s;',
68
+ ' }',
69
+ '}',
70
+ '',
71
+ ].join('\n');
72
+ return { ok: true, text };
73
+ }
74
+ /**
75
+ * Caddy (user-operated, not the wizard-managed one): the site block is
76
+ * one `reverse_proxy` line — Caddy routes the rest itself.
77
+ */
78
+ export function caddySnippet(input) {
79
+ const parts = validatedParts(input);
80
+ if ('error' in parts)
81
+ return parts.error;
82
+ const { domain, upstream, port } = parts;
83
+ const text = [
84
+ `${domain} {`,
85
+ ` reverse_proxy ${upstream}:${port}`,
86
+ '}',
87
+ '',
88
+ ].join('\n');
89
+ return { ok: true, text };
90
+ }
91
+ /**
92
+ * Lucky (Web 服务反代) three steps: listen 443, proxy to the upstream,
93
+ * flip the catch-all switch. Text only — Lucky has no config file format
94
+ * to generate.
95
+ */
96
+ export function luckySteps(input) {
97
+ const upstream = hostOf(input.upstreamHost);
98
+ if (upstream === undefined)
99
+ return { ok: false, error: 'bad-upstream-host' };
100
+ const port = portOf(input.upstreamPort);
101
+ if (port === undefined)
102
+ return { ok: false, error: 'bad-upstream-port' };
103
+ return {
104
+ ok: true,
105
+ steps: [
106
+ '在 Lucky 的「Web 服务」里新建一条规则,监听 443 端口,绑定你的域名。',
107
+ `后端(反代目标)填 http://${upstream}:${port},开启 WebSocket 支持。`,
108
+ '打开「万事大吉」开关(放行全部路径),保存即可生效。',
109
+ ],
110
+ };
111
+ }
112
+ //# sourceMappingURL=proxy-snippets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-snippets.js","sourceRoot":"","sources":["../../src/wizard/proxy-snippets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAgBrC,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,SAAS,cAAc,CAAC,KAAmB;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACnC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAA;IAC9E,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC3C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAA;IACvF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACvC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAA;IACnF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,KAAmB;IAC9C,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IACnC,IAAI,OAAO,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,KAAK,CAAA;IACxC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;IACxC,MAAM,IAAI,GAAG;QACX,iCAAiC;QACjC,yCAAyC;QACzC,sBAAsB;QACtB,oBAAoB;QACpB,GAAG;QACH,EAAE;QACF,UAAU;QACV,qBAAqB;QACrB,mBAAmB,MAAM,GAAG;QAC5B,EAAE;QACF,kBAAkB;QAClB,6BAA6B,QAAQ,IAAI,IAAI,GAAG;QAChD,iCAAiC;QACjC,iDAAiD;QACjD,0DAA0D;QAC1D,sCAAsC;QACtC,kDAAkD;QAClD,sEAAsE;QACtE,qDAAqD;QACrD,8BAA8B;QAC9B,oCAAoC;QACpC,mCAAmC;QACnC,mCAAmC;QACnC,OAAO;QACP,GAAG;QACH,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAmB;IAC9C,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IACnC,IAAI,OAAO,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,KAAK,CAAA;IACxC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;IACxC,MAAM,IAAI,GAAG;QACX,GAAG,MAAM,IAAI;QACb,qBAAqB,QAAQ,IAAI,IAAI,EAAE;QACvC,GAAG;QACH,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACZ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAC3B,CAAC;AAMD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAuD;IAChF,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC3C,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAA;IAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACvC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAA;IACxE,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK,EAAE;YACL,4CAA4C;YAC5C,oBAAoB,QAAQ,IAAI,IAAI,mBAAmB;YACvD,4BAA4B;SAC7B;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,462 @@
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 { responseJson, sameOriginPost } from '../http.js';
32
+ import { hostOf } from '../config.js';
33
+ import { normalizeTrustedIp, mergeProxyList, parseProxyList } from './source-detect.js';
34
+ import { projectWizardStatus } from './status.js';
35
+ /** Prefix all wizard routes live under (one webServer prefix registration;
36
+ * the host web server matches longest-prefix-first, so these win over the
37
+ * plain admin prefix registration). */
38
+ export const WIZARD_ROUTE_PREFIX = '/_dsh/zen-remote/admin/wizard';
39
+ /** GET: the sanitized wizard status projection. */
40
+ export const WIZARD_STATUS_ROUTE = `${WIZARD_ROUTE_PREFIX}/status`;
41
+ /** POST `{ip}`: merge one detected reverse-proxy IP into the persisted
42
+ * trustedProxies (GW-5). */
43
+ export const WIZARD_TRUST_PROXY_ROUTE = `${WIZARD_ROUTE_PREFIX}/trust-proxy`;
44
+ /** POST `{publicUrl}`: start the final verification — mint the web pairing
45
+ * code (GW-9). GET: poll its status. */
46
+ export const WIZARD_VERIFY_ROUTE = `${WIZARD_ROUTE_PREFIX}/verify`;
47
+ /** POST `{token}`: store the Cloudflare API token 0600 on this machine;
48
+ * DELETE: stop the consumers and remove it (GW-13a). */
49
+ export const WIZARD_CF_TOKEN_ROUTE = `${WIZARD_ROUTE_PREFIX}/cf-token`;
50
+ /** POST `{token}`: store the cloudflared connector token (GW-13a). */
51
+ export const WIZARD_TUNNEL_TOKEN_ROUTE = `${WIZARD_ROUTE_PREFIX}/tunnel-token`;
52
+ /** POST: start the managed Caddy from the saved row config; POST (stop)
53
+ * terminates it; GET answers its three-state (GW-13a). */
54
+ export const WIZARD_CADDY_START_ROUTE = `${WIZARD_ROUTE_PREFIX}/caddy/start`;
55
+ export const WIZARD_CADDY_STOP_ROUTE = `${WIZARD_ROUTE_PREFIX}/caddy/stop`;
56
+ export const WIZARD_CADDY_STATUS_ROUTE = `${WIZARD_ROUTE_PREFIX}/caddy/status`;
57
+ /** POST `{domain}`: the zone/account probe the migration card re-checks;
58
+ * POST `{domain, tunnelId?}`: the full tunnel setup; POST (stop) and GET
59
+ * (three-state) mirror the Caddy pair (GW-13b). */
60
+ export const WIZARD_TUNNEL_CHECK_ROUTE = `${WIZARD_ROUTE_PREFIX}/tunnel/check-domain`;
61
+ export const WIZARD_TUNNEL_SETUP_ROUTE = `${WIZARD_ROUTE_PREFIX}/tunnel/setup`;
62
+ export const WIZARD_TUNNEL_STOP_ROUTE = `${WIZARD_ROUTE_PREFIX}/tunnel/stop`;
63
+ export const WIZARD_TUNNEL_STATUS_ROUTE = `${WIZARD_ROUTE_PREFIX}/tunnel/status`;
64
+ /** Inbound body cap — the wizard forms send a few hundred bytes. */
65
+ const MAX_BODY_BYTES = 16 * 1024;
66
+ /**
67
+ * Read the whole body under the cap and demand one JSON object. An empty
68
+ * body counts as `{}`. Answers null for anything malformed — the route
69
+ * maps that to 400.
70
+ */
71
+ async function readJsonObject(req) {
72
+ const declared = req.headers['content-length'];
73
+ const expected = declared === undefined ? undefined : Number(declared);
74
+ if (expected !== undefined && Number.isSafeInteger(expected) && expected > MAX_BODY_BYTES)
75
+ return null;
76
+ const chunks = [];
77
+ let size = 0;
78
+ for await (const chunk of req) {
79
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
80
+ size += bytes.length;
81
+ if (size > MAX_BODY_BYTES)
82
+ return null;
83
+ chunks.push(bytes);
84
+ }
85
+ const text = Buffer.concat(chunks).toString('utf8');
86
+ if (text.trim() === '')
87
+ return {};
88
+ try {
89
+ const parsed = JSON.parse(text);
90
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
91
+ return null;
92
+ return parsed;
93
+ }
94
+ catch {
95
+ return null;
96
+ }
97
+ }
98
+ /**
99
+ * Build the wizard route handler for one plugin row. The returned handler
100
+ * owns the full response lifecycle of every request under
101
+ * {@link WIZARD_ROUTE_PREFIX} and never throws.
102
+ */
103
+ export function createWizardHandler(options) {
104
+ return async (req, res) => {
105
+ // EVERYTHING rides inside the one guard (GW-fix-1/L1): a malformed
106
+ // req.url explodes in `new URL`, and a broken connection service can
107
+ // throw out of admit — neither may escape as an unhandled rejection,
108
+ // the handler owns the full response lifecycle, always.
109
+ try {
110
+ // Wall 1 first: DSH's own admission.
111
+ const admission = options.admit(req);
112
+ if ('rejection' in admission) {
113
+ responseJson(res, admission.rejection, {
114
+ ok: false,
115
+ error: { code: admission.rejection === 401 ? 'unauthorized' : 'forbidden' },
116
+ });
117
+ return;
118
+ }
119
+ const url = new URL(req.url ?? '/', 'http://dsh.internal');
120
+ const route = url.pathname;
121
+ const method = req.method ?? 'GET';
122
+ // Wall 2, on EVERY wizard route before anything else: unlike
123
+ // admin/status there is no remote-readable exception — the wizard is
124
+ // a server-owner surface, GET included. This runs BEFORE same-origin
125
+ // because a forwarded request presents as same-origin (the gateway
126
+ // rewrites Origin/Host); the marker is the identifying signal.
127
+ if (req.headers['x-zen-remote-via'] !== undefined) {
128
+ responseJson(res, 403, {
129
+ ok: false,
130
+ error: { code: 'via-gateway', message: '配置引导只能在服务端本机操作' },
131
+ });
132
+ return;
133
+ }
134
+ if (route === WIZARD_STATUS_ROUTE && method === 'GET') {
135
+ let runtime = {};
136
+ try {
137
+ runtime = (await options.getRuntime?.()) ?? {};
138
+ }
139
+ catch {
140
+ // A broken runtime probe is "no information", never a failed read.
141
+ runtime = {};
142
+ }
143
+ responseJson(res, 200, projectWizardStatus(options.getConfig().values, runtime));
144
+ return;
145
+ }
146
+ if (route === WIZARD_TRUST_PROXY_ROUTE && method === 'POST') {
147
+ if (!sameOriginPost(req)) {
148
+ responseJson(res, 403, {
149
+ ok: false,
150
+ error: { code: 'origin-rejected', message: 'The request must originate from this DSH Web application' },
151
+ });
152
+ return;
153
+ }
154
+ const trust = options.trustProxy;
155
+ // A wiring that predates GW-5 has no persister: same answer as the
156
+ // other unwired verbs.
157
+ if (trust === undefined) {
158
+ responseJson(res, 501, { ok: false, error: { code: 'not-implemented', message: 'This wizard step is not wired up yet' } });
159
+ return;
160
+ }
161
+ const body = await readJsonObject(req);
162
+ if (body === null) {
163
+ responseJson(res, 400, { ok: false, error: { code: 'bad-request', message: 'request body must be a JSON object' } });
164
+ return;
165
+ }
166
+ const ip = normalizeTrustedIp(body.ip);
167
+ if (ip === undefined) {
168
+ responseJson(res, 400, { ok: false, error: { code: 'bad-ip', message: 'ip must be an IPv4 or IPv6 literal' } });
169
+ return;
170
+ }
171
+ let resolved;
172
+ try {
173
+ resolved = trust.resolved();
174
+ }
175
+ catch {
176
+ resolved = { value: '', source: 'default' };
177
+ }
178
+ // env / row values SHADOW the file layer the persister writes: a
179
+ // write there would silently do nothing. Refuse honestly instead.
180
+ if (resolved.source === 'env' || resolved.source === 'row') {
181
+ responseJson(res, 409, {
182
+ ok: false,
183
+ error: {
184
+ code: 'proxy-list-shadowed',
185
+ message: `trustedProxies 目前由${resolved.source === 'env' ? '环境变量' : '插件行配置'}提供,请先清掉那边的值再自动信任`,
186
+ },
187
+ });
188
+ return;
189
+ }
190
+ if (parseProxyList(resolved.value).includes(ip)) {
191
+ responseJson(res, 200, { ok: true, added: false });
192
+ return;
193
+ }
194
+ const merged = mergeProxyList(resolved.value, ip);
195
+ // GW-fix-2/L2: the persister re-reads the persisted surface and
196
+ // refuses when it moved since `resolved()` — two 信任 clicks in
197
+ // quick succession must not lose either IP.
198
+ const landed = await trust.write(resolved.value, merged);
199
+ if (landed === false) {
200
+ responseJson(res, 409, {
201
+ ok: false,
202
+ error: { code: 'trust-list-changed', message: '信任列表刚被其他操作修改,请刷新后重试' },
203
+ });
204
+ return;
205
+ }
206
+ responseJson(res, 200, { ok: true, added: true });
207
+ return;
208
+ }
209
+ if (route === WIZARD_CF_TOKEN_ROUTE && (method === 'POST' || method === 'DELETE')) {
210
+ if (!sameOriginPost(req)) {
211
+ responseJson(res, 403, {
212
+ ok: false,
213
+ error: { code: 'origin-rejected', message: 'The request must originate from this DSH Web application' },
214
+ });
215
+ return;
216
+ }
217
+ const store = options.tokenStore;
218
+ if (store === undefined) {
219
+ responseJson(res, 501, { ok: false, error: { code: 'not-implemented', message: 'This wizard step is not wired up yet' } });
220
+ return;
221
+ }
222
+ if (method === 'DELETE') {
223
+ store.deleteCfToken();
224
+ responseJson(res, 200, { ok: true, configured: false });
225
+ return;
226
+ }
227
+ const body = await readJsonObject(req);
228
+ const token = typeof body?.token === 'string' ? body.token.trim() : '';
229
+ if (token === '') {
230
+ responseJson(res, 400, { ok: false, error: { code: 'bad-token', message: 'token must be a non-empty string' } });
231
+ return;
232
+ }
233
+ store.writeCfToken(token);
234
+ responseJson(res, 200, { ok: true, configured: true });
235
+ return;
236
+ }
237
+ if (route === WIZARD_TUNNEL_TOKEN_ROUTE && method === 'POST') {
238
+ if (!sameOriginPost(req)) {
239
+ responseJson(res, 403, {
240
+ ok: false,
241
+ error: { code: 'origin-rejected', message: 'The request must originate from this DSH Web application' },
242
+ });
243
+ return;
244
+ }
245
+ const store = options.tokenStore;
246
+ if (store === undefined) {
247
+ responseJson(res, 501, { ok: false, error: { code: 'not-implemented', message: 'This wizard step is not wired up yet' } });
248
+ return;
249
+ }
250
+ const body = await readJsonObject(req);
251
+ const token = typeof body?.token === 'string' ? body.token.trim() : '';
252
+ if (token === '') {
253
+ responseJson(res, 400, { ok: false, error: { code: 'bad-token', message: 'token must be a non-empty string' } });
254
+ return;
255
+ }
256
+ store.writeTunnelToken(token);
257
+ responseJson(res, 200, { ok: true, configured: true });
258
+ return;
259
+ }
260
+ if (route.startsWith(`${WIZARD_ROUTE_PREFIX}/caddy/`)) {
261
+ // Walls first, then the method shape, then (and only then) the
262
+ // wiring check — a 501 must never answer before the walls, and a
263
+ // wrong method on a wired route must still read 405.
264
+ if (method === 'POST' && !sameOriginPost(req)) {
265
+ responseJson(res, 403, {
266
+ ok: false,
267
+ error: { code: 'origin-rejected', message: 'The request must originate from this DSH Web application' },
268
+ });
269
+ return;
270
+ }
271
+ if (method !== 'GET' && method !== 'POST') {
272
+ res.setHeader('Allow', 'GET, POST');
273
+ responseJson(res, 405, { ok: false, error: { code: 'method-not-allowed', message: 'Use GET or POST' } });
274
+ return;
275
+ }
276
+ const caddy = options.caddy;
277
+ if (caddy === undefined) {
278
+ responseJson(res, 501, { ok: false, error: { code: 'not-implemented', message: 'This wizard step is not wired up yet' } });
279
+ return;
280
+ }
281
+ if (route === WIZARD_CADDY_STATUS_ROUTE && method === 'GET') {
282
+ responseJson(res, 200, { ok: true, state: caddy.status() });
283
+ return;
284
+ }
285
+ if (route === WIZARD_CADDY_STOP_ROUTE && method !== 'POST') {
286
+ // GW-fix-4/H2: a GET must never stop a process, even by accident.
287
+ res.setHeader('Allow', 'GET, POST');
288
+ responseJson(res, 405, { ok: false, error: { code: 'method-not-allowed', message: 'Use POST to stop' } });
289
+ return;
290
+ }
291
+ if (route === WIZARD_CADDY_STOP_ROUTE) {
292
+ caddy.stop();
293
+ responseJson(res, 200, { ok: true, state: caddy.status() });
294
+ return;
295
+ }
296
+ if (route === WIZARD_CADDY_START_ROUTE && method === 'POST') {
297
+ const body = await readJsonObject(req);
298
+ const values = options.getConfig().values;
299
+ const rawDomain = typeof body?.domain === 'string' && body.domain.trim() !== ''
300
+ ? body.domain.trim()
301
+ : values.ingressDomain;
302
+ const domain = hostOf(rawDomain);
303
+ if (domain === undefined) {
304
+ responseJson(res, 400, { ok: false, error: { code: 'no-domain', message: '保存一个有效的公开域名后再启动' } });
305
+ return;
306
+ }
307
+ const rawPort = typeof body?.httpsPort === 'number' && Number.isSafeInteger(body.httpsPort) && body.httpsPort >= 1 && body.httpsPort <= 65535
308
+ ? body.httpsPort
309
+ : values.ingressHttpsPort;
310
+ let runtime = {};
311
+ try {
312
+ runtime = (await options.getRuntime?.()) ?? {};
313
+ }
314
+ catch {
315
+ runtime = {};
316
+ }
317
+ const gatewayPort = typeof runtime.gatewayActualPort === 'number' ? runtime.gatewayActualPort : values.port;
318
+ const result = await caddy.start({ domain, httpsPort: rawPort, gatewayPort });
319
+ // The start result may carry a failure detail — never the token.
320
+ responseJson(res, 200, { ok: result.ok, ...(result.ok ? { caddyfile: result.caddyfile } : { error: result.error, detail: result.detail, installUrl: result.installUrl }) });
321
+ return;
322
+ }
323
+ responseJson(res, 404, { ok: false, error: { code: 'not-found', message: 'Unknown wizard route' } });
324
+ return;
325
+ }
326
+ if (route.startsWith(`${WIZARD_ROUTE_PREFIX}/tunnel/`)) {
327
+ // Same discipline as the caddy block: walls, then method shape,
328
+ // then the wiring check.
329
+ if (method === 'POST' && !sameOriginPost(req)) {
330
+ responseJson(res, 403, {
331
+ ok: false,
332
+ error: { code: 'origin-rejected', message: 'The request must originate from this DSH Web application' },
333
+ });
334
+ return;
335
+ }
336
+ if (method !== 'GET' && method !== 'POST') {
337
+ res.setHeader('Allow', 'GET, POST');
338
+ responseJson(res, 405, { ok: false, error: { code: 'method-not-allowed', message: 'Use GET or POST' } });
339
+ return;
340
+ }
341
+ const tunnel = options.tunnel;
342
+ if (tunnel === undefined) {
343
+ responseJson(res, 501, { ok: false, error: { code: 'not-implemented', message: 'This wizard step is not wired up yet' } });
344
+ return;
345
+ }
346
+ if (route === WIZARD_TUNNEL_STATUS_ROUTE && method === 'GET') {
347
+ responseJson(res, 200, { ok: true, state: tunnel.status() });
348
+ return;
349
+ }
350
+ if (method !== 'POST') {
351
+ res.setHeader('Allow', 'GET, POST');
352
+ responseJson(res, 405, { ok: false, error: { code: 'method-not-allowed', message: 'Use GET or POST' } });
353
+ return;
354
+ }
355
+ const body = await readJsonObject(req);
356
+ const domain = typeof body?.domain === 'string' ? body.domain : '';
357
+ if (route === WIZARD_TUNNEL_CHECK_ROUTE) {
358
+ const result = await tunnel.checkDomain(domain);
359
+ responseJson(res, 200, { ok: result.ok, ...(result.ok ? { onCloudflare: result.onCloudflare, zoneId: result.zoneId } : { reason: result.reason, detail: result.detail }) });
360
+ return;
361
+ }
362
+ if (route === WIZARD_TUNNEL_STOP_ROUTE && method !== 'POST') {
363
+ res.setHeader('Allow', 'GET, POST');
364
+ responseJson(res, 405, { ok: false, error: { code: 'method-not-allowed', message: 'Use POST to stop' } });
365
+ return;
366
+ }
367
+ if (route === WIZARD_TUNNEL_STOP_ROUTE) {
368
+ tunnel.stop();
369
+ responseJson(res, 200, { ok: true, state: tunnel.status() });
370
+ return;
371
+ }
372
+ if (route === WIZARD_TUNNEL_SETUP_ROUTE) {
373
+ const tunnelId = typeof body?.tunnelId === 'string' && body.tunnelId !== '' ? body.tunnelId : undefined;
374
+ const result = await tunnel.setup({ domain, tunnelId });
375
+ // The setup answer never carries the connector token — only its
376
+ // file path (a server-local fact) and the conflict list.
377
+ if (result.ok) {
378
+ responseJson(res, 200, { ok: true, tunnelId: result.tunnelId, publicUrl: result.publicUrl });
379
+ }
380
+ else {
381
+ responseJson(res, 200, {
382
+ ok: false,
383
+ reason: result.reason,
384
+ ...(result.detail !== undefined ? { detail: result.detail } : {}),
385
+ ...(result.existing !== undefined ? { existing: result.existing } : {}),
386
+ ...(result.installUrl !== undefined ? { installUrl: result.installUrl } : {}),
387
+ });
388
+ }
389
+ return;
390
+ }
391
+ responseJson(res, 404, { ok: false, error: { code: 'not-found', message: 'Unknown wizard route' } });
392
+ return;
393
+ }
394
+ if (route === WIZARD_VERIFY_ROUTE && (method === 'POST' || method === 'GET')) {
395
+ // Wall 3 applies to the POST; the GET is read-only polling. Both
396
+ // answers are 200 with the orchestration's own verdict in the
397
+ // body — the UI branches on `ok` / `result`, not on status codes.
398
+ if (method === 'POST' && !sameOriginPost(req)) {
399
+ responseJson(res, 403, {
400
+ ok: false,
401
+ error: { code: 'origin-rejected', message: 'The request must originate from this DSH Web application' },
402
+ });
403
+ return;
404
+ }
405
+ const verify = options.verify;
406
+ if (verify === undefined) {
407
+ responseJson(res, 501, { ok: false, error: { code: 'not-implemented', message: 'This wizard step is not wired up yet' } });
408
+ return;
409
+ }
410
+ if (method === 'GET') {
411
+ responseJson(res, 200, await verify.check());
412
+ return;
413
+ }
414
+ const body = await readJsonObject(req);
415
+ if (body === null) {
416
+ responseJson(res, 400, { ok: false, error: { code: 'bad-request', message: 'request body must be a JSON object' } });
417
+ return;
418
+ }
419
+ responseJson(res, 200, await verify.start({
420
+ publicUrl: body.publicUrl,
421
+ ...(body.probeOnly === true ? { probeOnly: true } : {}),
422
+ }));
423
+ return;
424
+ }
425
+ if (route.startsWith(`${WIZARD_ROUTE_PREFIX}/`)) {
426
+ if (method === 'POST') {
427
+ if (!sameOriginPost(req)) {
428
+ responseJson(res, 403, {
429
+ ok: false,
430
+ error: { code: 'origin-rejected', message: 'The request must originate from this DSH Web application' },
431
+ });
432
+ return;
433
+ }
434
+ // Skeleton placeholder: later tasks mount the real verbs here.
435
+ responseJson(res, 501, {
436
+ ok: false,
437
+ error: { code: 'not-implemented', message: 'This wizard step is not wired up yet' },
438
+ });
439
+ return;
440
+ }
441
+ if (method === 'GET') {
442
+ // Unknown GET under the wizard prefix: 404, after the walls.
443
+ responseJson(res, 404, { ok: false, error: { code: 'not-found', message: 'Unknown wizard route' } });
444
+ return;
445
+ }
446
+ res.setHeader('Allow', 'GET, POST');
447
+ responseJson(res, 405, { ok: false, error: { code: 'method-not-allowed', message: 'Use GET or POST' } });
448
+ return;
449
+ }
450
+ responseJson(res, 404, { ok: false, error: { code: 'not-found', message: 'Unknown wizard route' } });
451
+ }
452
+ catch {
453
+ if (!res.headersSent) {
454
+ responseJson(res, 500, { ok: false, error: { code: 'internal', message: 'The wizard route failed' } });
455
+ }
456
+ else {
457
+ res.destroy();
458
+ }
459
+ }
460
+ };
461
+ }
462
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/wizard/routes.ts"],"names":[],"mappings":"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"}