@serfab/cadre-host 1.13.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/README.md +347 -423
  2. package/dist/bin/host.d.ts +6 -3
  3. package/dist/bin/host.js +332 -524
  4. package/dist/bin/host.js.map +1 -1
  5. package/dist/bin/join-output.d.ts +56 -0
  6. package/dist/bin/join-output.js +92 -0
  7. package/dist/bin/join-output.js.map +1 -0
  8. package/dist/bin/nat-output.d.ts +54 -0
  9. package/dist/bin/nat-output.js +138 -0
  10. package/dist/bin/nat-output.js.map +1 -0
  11. package/dist/bin/ui-access.d.ts +22 -0
  12. package/dist/bin/ui-access.js +44 -0
  13. package/dist/bin/ui-access.js.map +1 -0
  14. package/dist/hosted/claim-details.d.ts +66 -0
  15. package/dist/hosted/claim-details.js +60 -0
  16. package/dist/hosted/claim-details.js.map +1 -0
  17. package/dist/hosted/hosted-node-service.d.ts +325 -0
  18. package/dist/hosted/hosted-node-service.js +678 -0
  19. package/dist/hosted/hosted-node-service.js.map +1 -0
  20. package/dist/hosted/hosted-node-store.d.ts +40 -0
  21. package/dist/hosted/hosted-node-store.js +126 -0
  22. package/dist/hosted/hosted-node-store.js.map +1 -0
  23. package/dist/{donation/donation-supervisor.d.ts → hosted/hosted-node-supervisor.d.ts} +70 -53
  24. package/dist/hosted/hosted-node-supervisor.js +396 -0
  25. package/dist/hosted/hosted-node-supervisor.js.map +1 -0
  26. package/dist/hosted/hosted-node-watcher.d.ts +95 -0
  27. package/dist/hosted/hosted-node-watcher.js +260 -0
  28. package/dist/hosted/hosted-node-watcher.js.map +1 -0
  29. package/dist/hosted/index.d.ts +16 -0
  30. package/dist/hosted/index.js +13 -0
  31. package/dist/hosted/index.js.map +1 -0
  32. package/dist/hosted/node-status.d.ts +51 -0
  33. package/dist/hosted/node-status.js +77 -0
  34. package/dist/hosted/node-status.js.map +1 -0
  35. package/dist/hosted/types.d.ts +141 -0
  36. package/dist/hosted/types.js +22 -0
  37. package/dist/hosted/types.js.map +1 -0
  38. package/dist/index.d.ts +12 -24
  39. package/dist/index.js +9 -19
  40. package/dist/index.js.map +1 -1
  41. package/dist/installer/config.d.ts +27 -34
  42. package/dist/installer/config.js +46 -15
  43. package/dist/installer/config.js.map +1 -1
  44. package/dist/installer/index.d.ts +9 -19
  45. package/dist/installer/index.js +21 -85
  46. package/dist/installer/index.js.map +1 -1
  47. package/dist/installer/paths.d.ts +0 -2
  48. package/dist/installer/paths.js +0 -4
  49. package/dist/installer/paths.js.map +1 -1
  50. package/dist/installer/wizard.d.ts +12 -9
  51. package/dist/installer/wizard.js +15 -14
  52. package/dist/installer/wizard.js.map +1 -1
  53. package/dist/nat/address-resolver.d.ts +18 -17
  54. package/dist/nat/address-resolver.js +79 -25
  55. package/dist/nat/address-resolver.js.map +1 -1
  56. package/dist/nat/address-watch.d.ts +37 -0
  57. package/dist/nat/address-watch.js +84 -0
  58. package/dist/nat/address-watch.js.map +1 -0
  59. package/dist/nat/ddns/duckdns.d.ts +2 -1
  60. package/dist/nat/ddns/duckdns.js +5 -1
  61. package/dist/nat/ddns/duckdns.js.map +1 -1
  62. package/dist/nat/ddns/index.d.ts +6 -0
  63. package/dist/nat/ddns/index.js.map +1 -1
  64. package/dist/nat/index.d.ts +13 -9
  65. package/dist/nat/index.js +7 -5
  66. package/dist/nat/index.js.map +1 -1
  67. package/dist/nat/nat-service.d.ts +220 -77
  68. package/dist/nat/nat-service.js +653 -239
  69. package/dist/nat/nat-service.js.map +1 -1
  70. package/dist/nat/nat-store.d.ts +12 -5
  71. package/dist/nat/nat-store.js +124 -29
  72. package/dist/nat/nat-store.js.map +1 -1
  73. package/dist/nat/network-mode.d.ts +19 -0
  74. package/dist/nat/network-mode.js +32 -0
  75. package/dist/nat/network-mode.js.map +1 -0
  76. package/dist/nat/port-mapper.d.ts +83 -79
  77. package/dist/nat/port-mapper.js +148 -189
  78. package/dist/nat/port-mapper.js.map +1 -1
  79. package/dist/nat/reachability.d.ts +32 -15
  80. package/dist/nat/reachability.js +110 -22
  81. package/dist/nat/reachability.js.map +1 -1
  82. package/dist/nat/types.d.ts +98 -27
  83. package/dist/nat/types.js +8 -5
  84. package/dist/nat/types.js.map +1 -1
  85. package/dist/orchestrator/host-process-orchestrator.d.ts +32 -74
  86. package/dist/orchestrator/host-process-orchestrator.js +84 -233
  87. package/dist/orchestrator/host-process-orchestrator.js.map +1 -1
  88. package/dist/{installer/identity.d.ts → orchestrator/identity-file.d.ts} +5 -5
  89. package/dist/{installer/identity.js → orchestrator/identity-file.js} +6 -6
  90. package/dist/orchestrator/identity-file.js.map +1 -0
  91. package/dist/orchestrator/index.d.ts +2 -3
  92. package/dist/orchestrator/index.js +1 -1
  93. package/dist/orchestrator/index.js.map +1 -1
  94. package/dist/orchestrator/node-identity.d.ts +6 -6
  95. package/dist/orchestrator/node-identity.js +7 -7
  96. package/dist/orchestrator/node-identity.js.map +1 -1
  97. package/dist/orchestrator/port-allocator.d.ts +5 -6
  98. package/dist/orchestrator/port-allocator.js +9 -11
  99. package/dist/orchestrator/port-allocator.js.map +1 -1
  100. package/dist/orchestrator/state-store.d.ts +3 -5
  101. package/dist/orchestrator/state-store.js +2 -10
  102. package/dist/orchestrator/state-store.js.map +1 -1
  103. package/dist/orchestrator/types.d.ts +33 -22
  104. package/dist/orchestrator/types.js.map +1 -1
  105. package/dist/package-version.d.ts +1 -0
  106. package/dist/package-version.js +4 -0
  107. package/dist/package-version.js.map +1 -0
  108. package/dist/server/error-handler.d.ts +5 -25
  109. package/dist/server/error-handler.js +11 -74
  110. package/dist/server/error-handler.js.map +1 -1
  111. package/dist/server/events/types.d.ts +7 -11
  112. package/dist/server/events/types.js +2 -1
  113. package/dist/server/events/types.js.map +1 -1
  114. package/dist/server/index.d.ts +11 -37
  115. package/dist/server/index.js +30 -48
  116. package/dist/server/index.js.map +1 -1
  117. package/dist/server/routes/hosted-nodes.d.ts +28 -0
  118. package/dist/server/routes/hosted-nodes.js +68 -0
  119. package/dist/server/routes/hosted-nodes.js.map +1 -0
  120. package/dist/server/routes/nat.d.ts +4 -1
  121. package/dist/server/routes/nat.js +13 -2
  122. package/dist/server/routes/nat.js.map +1 -1
  123. package/dist/server/routes/nodes.d.ts +6 -20
  124. package/dist/server/routes/nodes.js +7 -86
  125. package/dist/server/routes/nodes.js.map +1 -1
  126. package/dist/server/routes/settings.d.ts +3 -7
  127. package/dist/server/routes/settings.js +18 -8
  128. package/dist/server/routes/settings.js.map +1 -1
  129. package/dist/server/routes/status.d.ts +2 -25
  130. package/dist/server/routes/status.js +3 -43
  131. package/dist/server/routes/status.js.map +1 -1
  132. package/dist/server/server.js +8 -8
  133. package/dist/server/settings-store.d.ts +2 -2
  134. package/dist/server/settings-store.js +2 -2
  135. package/dist/server/static.js +1 -2
  136. package/dist/server/static.js.map +1 -1
  137. package/dist/ui/assets/index-BHd8CWZA.css +1 -0
  138. package/dist/ui/assets/index-Ccr2GjPT.js +23 -0
  139. package/dist/ui/assets/index-Ccr2GjPT.js.map +1 -0
  140. package/dist/ui/index.html +2 -2
  141. package/dist/update/index.d.ts +2 -2
  142. package/dist/update/index.js +2 -2
  143. package/dist/update/store.d.ts +1 -1
  144. package/dist/update/store.js +1 -1
  145. package/dist/update/types.d.ts +1 -1
  146. package/dist/update/types.js +1 -1
  147. package/package.json +5 -7
  148. package/src/__tests__/cli-nat.smoke.test.ts +219 -212
  149. package/src/__tests__/cli.smoke.test.ts +2 -2
  150. package/src/__tests__/global-setup.ts +2 -3
  151. package/src/__tests__/orchestrator-claim-secret.test.ts +111 -0
  152. package/src/__tests__/orchestrator-env-scrub.test.ts +160 -163
  153. package/src/__tests__/orchestrator-handle-contract.ts +134 -134
  154. package/src/__tests__/orchestrator-node-identity.test.ts +177 -203
  155. package/src/__tests__/orchestrator-ports.test.ts +124 -143
  156. package/src/__tests__/orchestrator-push.test.ts +138 -146
  157. package/src/__tests__/orchestrator.test.ts +1017 -1063
  158. package/src/__tests__/ui-access.test.ts +30 -0
  159. package/src/bin/host.ts +397 -572
  160. package/src/bin/join-output.ts +120 -0
  161. package/src/bin/nat-output.ts +188 -0
  162. package/src/bin/ui-access.ts +50 -0
  163. package/src/{donation → hosted}/__tests__/fake-orchestrator.test.ts +172 -173
  164. package/src/{donation → hosted}/__tests__/fake-orchestrator.ts +43 -23
  165. package/src/hosted/__tests__/hosted-node-service.test.ts +708 -0
  166. package/src/hosted/__tests__/hosted-node-supervisor.test.ts +475 -0
  167. package/src/hosted/__tests__/test-invitation.ts +33 -0
  168. package/src/hosted/claim-details.ts +103 -0
  169. package/src/hosted/hosted-node-service.ts +814 -0
  170. package/src/hosted/hosted-node-store.ts +144 -0
  171. package/src/hosted/hosted-node-supervisor.ts +439 -0
  172. package/src/hosted/hosted-node-watcher.ts +288 -0
  173. package/src/hosted/index.ts +53 -0
  174. package/src/hosted/node-status.ts +97 -0
  175. package/src/hosted/types.ts +160 -0
  176. package/src/index.ts +72 -91
  177. package/src/installer/__tests__/config.test.ts +15 -40
  178. package/src/installer/__tests__/installer.smoke.test.ts +184 -263
  179. package/src/installer/__tests__/wizard.test.ts +25 -13
  180. package/src/installer/config.ts +201 -175
  181. package/src/installer/index.ts +252 -327
  182. package/src/installer/paths.ts +104 -109
  183. package/src/installer/wizard.ts +24 -26
  184. package/src/nat/__tests__/address-resolver.test.ts +107 -82
  185. package/src/nat/__tests__/nat-service.test.ts +608 -515
  186. package/src/nat/__tests__/nat-store.test.ts +49 -12
  187. package/src/nat/__tests__/network-mode.test.ts +38 -0
  188. package/src/nat/__tests__/port-mapper.test.ts +30 -191
  189. package/src/nat/__tests__/reachability.test.ts +96 -13
  190. package/src/nat/address-resolver.ts +94 -52
  191. package/src/nat/address-watch.ts +92 -0
  192. package/src/nat/ddns/duckdns.ts +5 -1
  193. package/src/nat/ddns/index.ts +6 -0
  194. package/src/nat/index.ts +33 -13
  195. package/src/nat/nat-service.ts +942 -501
  196. package/src/nat/nat-store.ts +126 -31
  197. package/src/nat/network-mode.ts +36 -0
  198. package/src/nat/port-mapper.ts +241 -329
  199. package/src/nat/reachability.ts +155 -34
  200. package/src/nat/types.ts +110 -37
  201. package/src/{installer/__tests__/identity.test.ts → orchestrator/__tests__/identity-file.test.ts} +34 -34
  202. package/src/orchestrator/__tests__/node-identity.test.ts +62 -62
  203. package/src/orchestrator/host-process-orchestrator.ts +1089 -1260
  204. package/src/{installer/identity.ts → orchestrator/identity-file.ts} +56 -56
  205. package/src/orchestrator/index.ts +9 -10
  206. package/src/orchestrator/node-identity.ts +41 -41
  207. package/src/orchestrator/port-allocator.ts +71 -73
  208. package/src/orchestrator/state-store.ts +76 -90
  209. package/src/orchestrator/types.ts +34 -23
  210. package/src/package-version.ts +4 -0
  211. package/src/server/__tests__/bus.test.ts +38 -38
  212. package/src/server/__tests__/error-handler.test.ts +81 -118
  213. package/src/server/__tests__/fakes.ts +15 -18
  214. package/src/server/__tests__/hosted-nodes-route.test.ts +161 -0
  215. package/src/server/__tests__/nodes-route.test.ts +114 -283
  216. package/src/server/__tests__/publishers.test.ts +193 -180
  217. package/src/server/__tests__/server.smoke.test.ts +134 -223
  218. package/src/server/__tests__/settings-route.test.ts +210 -195
  219. package/src/server/__tests__/sse-route.test.ts +119 -119
  220. package/src/server/__tests__/status-route.test.ts +82 -121
  221. package/src/server/error-handler.ts +112 -178
  222. package/src/server/events/types.ts +20 -24
  223. package/src/server/index.ts +223 -267
  224. package/src/server/routes/hosted-nodes.ts +83 -0
  225. package/src/server/routes/nat.ts +75 -63
  226. package/src/server/routes/nodes.ts +96 -188
  227. package/src/server/routes/settings.ts +20 -15
  228. package/src/server/routes/status.ts +5 -67
  229. package/src/server/server.ts +8 -8
  230. package/src/server/settings-store.ts +2 -2
  231. package/src/server/static.ts +1 -2
  232. package/src/update/index.ts +2 -2
  233. package/src/update/store.ts +1 -1
  234. package/src/update/types.ts +1 -1
  235. package/dist/auth/duration.d.ts +0 -1
  236. package/dist/auth/duration.js +0 -32
  237. package/dist/auth/duration.js.map +0 -1
  238. package/dist/auth/index.d.ts +0 -11
  239. package/dist/auth/index.js +0 -9
  240. package/dist/auth/index.js.map +0 -1
  241. package/dist/auth/self-label.d.ts +0 -36
  242. package/dist/auth/self-label.js +0 -57
  243. package/dist/auth/self-label.js.map +0 -1
  244. package/dist/auth/trust-circle-store.d.ts +0 -26
  245. package/dist/auth/trust-circle-store.js +0 -129
  246. package/dist/auth/trust-circle-store.js.map +0 -1
  247. package/dist/auth/trust-circle.d.ts +0 -156
  248. package/dist/auth/trust-circle.js +0 -307
  249. package/dist/auth/trust-circle.js.map +0 -1
  250. package/dist/auth/types.d.ts +0 -84
  251. package/dist/auth/types.js +0 -24
  252. package/dist/auth/types.js.map +0 -1
  253. package/dist/donation/donation-service.d.ts +0 -389
  254. package/dist/donation/donation-service.js +0 -828
  255. package/dist/donation/donation-service.js.map +0 -1
  256. package/dist/donation/donation-store.d.ts +0 -51
  257. package/dist/donation/donation-store.js +0 -152
  258. package/dist/donation/donation-store.js.map +0 -1
  259. package/dist/donation/donation-supervisor.js +0 -364
  260. package/dist/donation/donation-supervisor.js.map +0 -1
  261. package/dist/donation/grant-service.d.ts +0 -80
  262. package/dist/donation/grant-service.js +0 -210
  263. package/dist/donation/grant-service.js.map +0 -1
  264. package/dist/donation/grant-store.d.ts +0 -38
  265. package/dist/donation/grant-store.js +0 -135
  266. package/dist/donation/grant-store.js.map +0 -1
  267. package/dist/donation/index.d.ts +0 -20
  268. package/dist/donation/index.js +0 -17
  269. package/dist/donation/index.js.map +0 -1
  270. package/dist/donation/types.d.ts +0 -224
  271. package/dist/donation/types.js +0 -40
  272. package/dist/donation/types.js.map +0 -1
  273. package/dist/installer/identity.js.map +0 -1
  274. package/dist/owner/index.d.ts +0 -11
  275. package/dist/owner/index.js +0 -11
  276. package/dist/owner/index.js.map +0 -1
  277. package/dist/owner/owner-node-client.d.ts +0 -110
  278. package/dist/owner/owner-node-client.js +0 -184
  279. package/dist/owner/owner-node-client.js.map +0 -1
  280. package/dist/server/routes/bootstrap-node-validation.d.ts +0 -115
  281. package/dist/server/routes/bootstrap-node-validation.js +0 -197
  282. package/dist/server/routes/bootstrap-node-validation.js.map +0 -1
  283. package/dist/server/routes/grants-admin.d.ts +0 -29
  284. package/dist/server/routes/grants-admin.js +0 -58
  285. package/dist/server/routes/grants-admin.js.map +0 -1
  286. package/dist/server/routes/grants.d.ts +0 -28
  287. package/dist/server/routes/grants.js +0 -165
  288. package/dist/server/routes/grants.js.map +0 -1
  289. package/dist/server/routes/provision-request-validation.d.ts +0 -45
  290. package/dist/server/routes/provision-request-validation.js +0 -97
  291. package/dist/server/routes/provision-request-validation.js.map +0 -1
  292. package/dist/server/routes/strands.d.ts +0 -20
  293. package/dist/server/routes/strands.js +0 -38
  294. package/dist/server/routes/strands.js.map +0 -1
  295. package/dist/server/routes/trust-circle.d.ts +0 -17
  296. package/dist/server/routes/trust-circle.js +0 -35
  297. package/dist/server/routes/trust-circle.js.map +0 -1
  298. package/dist/strands/index.d.ts +0 -7
  299. package/dist/strands/index.js +0 -6
  300. package/dist/strands/index.js.map +0 -1
  301. package/dist/strands/strand-service.d.ts +0 -50
  302. package/dist/strands/strand-service.js +0 -103
  303. package/dist/strands/strand-service.js.map +0 -1
  304. package/dist/strands/types.d.ts +0 -93
  305. package/dist/strands/types.js +0 -23
  306. package/dist/strands/types.js.map +0 -1
  307. package/dist/ui/assets/index-C6nELNfC.js +0 -23
  308. package/dist/ui/assets/index-C6nELNfC.js.map +0 -1
  309. package/dist/ui/assets/index-TtIYSeZO.css +0 -1
  310. package/src/__tests__/cli-invite.smoke.test.ts +0 -192
  311. package/src/__tests__/host-owner.smoke.test.ts +0 -123
  312. package/src/__tests__/orchestrator-owner.test.ts +0 -234
  313. package/src/__tests__/orchestrator-pin-keys.test.ts +0 -152
  314. package/src/auth/__tests__/duration.test.ts +0 -28
  315. package/src/auth/__tests__/self-label.test.ts +0 -85
  316. package/src/auth/__tests__/trust-circle-integration.test.ts +0 -152
  317. package/src/auth/__tests__/trust-circle-store.test.ts +0 -115
  318. package/src/auth/__tests__/trust-circle.test.ts +0 -445
  319. package/src/auth/duration.ts +0 -33
  320. package/src/auth/index.ts +0 -21
  321. package/src/auth/self-label.ts +0 -74
  322. package/src/auth/trust-circle-store.ts +0 -155
  323. package/src/auth/trust-circle.ts +0 -395
  324. package/src/auth/types.ts +0 -99
  325. package/src/donation/__tests__/donation-service.test.ts +0 -1193
  326. package/src/donation/__tests__/donation-supervisor.test.ts +0 -548
  327. package/src/donation/__tests__/grant-service.test.ts +0 -213
  328. package/src/donation/__tests__/grant-store.test.ts +0 -113
  329. package/src/donation/donation-service.ts +0 -1033
  330. package/src/donation/donation-store.ts +0 -176
  331. package/src/donation/donation-supervisor.ts +0 -411
  332. package/src/donation/grant-service.ts +0 -252
  333. package/src/donation/grant-store.ts +0 -152
  334. package/src/donation/index.ts +0 -65
  335. package/src/donation/types.ts +0 -260
  336. package/src/owner/__tests__/owner-node-client.test.ts +0 -194
  337. package/src/owner/index.ts +0 -12
  338. package/src/owner/owner-node-client.ts +0 -259
  339. package/src/server/__tests__/bootstrap-node-validation.test.ts +0 -138
  340. package/src/server/__tests__/grants-admin-route.test.ts +0 -171
  341. package/src/server/__tests__/grants-route.test.ts +0 -394
  342. package/src/server/__tests__/strands-route.test.ts +0 -234
  343. package/src/server/routes/bootstrap-node-validation.ts +0 -206
  344. package/src/server/routes/grants-admin.ts +0 -74
  345. package/src/server/routes/grants.ts +0 -193
  346. package/src/server/routes/provision-request-validation.ts +0 -105
  347. package/src/server/routes/strands.ts +0 -54
  348. package/src/server/routes/trust-circle.ts +0 -49
  349. package/src/strands/__tests__/strand-service.test.ts +0 -165
  350. package/src/strands/index.ts +0 -14
  351. package/src/strands/strand-service.ts +0 -135
  352. package/src/strands/types.ts +0 -102
@@ -25,8 +25,6 @@ export declare function defaultHostJs(): string;
25
25
  export declare function defaultServiceDir(): string;
26
26
  /** Where the wizard writes the JSON config. */
27
27
  export declare function configPath(dataDir: string): string;
28
- /** Where the wizard writes the Ed25519 identity. */
29
- export declare function identityPath(dataDir: string): string;
30
28
  /** Logs directory (used by launchd / NSSM unit templates). */
31
29
  export declare function logsDir(dataDir: string): string;
32
30
  /** Per-platform install dir for the rendered service unit file. */
@@ -55,10 +55,6 @@ export function defaultServiceDir() {
55
55
  export function configPath(dataDir) {
56
56
  return join(dataDir, 'host.config.json');
57
57
  }
58
- /** Where the wizard writes the Ed25519 identity. */
59
- export function identityPath(dataDir) {
60
- return join(dataDir, 'identity.key');
61
- }
62
58
  /** Logs directory (used by launchd / NSSM unit templates). */
63
59
  export function logsDir(dataDir) {
64
60
  return join(dataDir, 'logs');
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/installer/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/installer/paths.ts"],"names":[],"mappings":"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"}
@@ -9,27 +9,30 @@ import type { SupportedPlatform } from './platform.js';
9
9
  export interface WizardDefaults {
10
10
  dataDir: string;
11
11
  uiPort: number;
12
- libp2pPort: number;
13
12
  upnpEnabled: boolean;
14
- /** Also run the host's own personal cadre here (founder persona). Default false. */
15
- ownCadre: boolean;
13
+ /** Values a command-line flag already supplied: the wizard does not ask for them again. */
14
+ given?: {
15
+ dataDir?: boolean;
16
+ uiPort?: boolean;
17
+ upnpEnabled?: boolean;
18
+ };
19
+ /**
20
+ * The public IPv4 an interface holds (`publicInterfaceAddress`), when one does: the machine is
21
+ * reached directly (a VPS), so there is no router to ask about UPnP.
22
+ */
23
+ publicInterfaceIp?: string | null;
16
24
  }
17
25
  export interface WizardAnswers {
18
26
  dataDir: string;
19
27
  uiPort: number;
20
- libp2pPort: number;
21
28
  upnpEnabled: boolean;
22
- configureDdns: boolean;
23
- /** Also run the host's own personal cadre here (founder persona). */
24
- ownCadre: boolean;
25
29
  }
26
30
  export declare const DEFAULT_UI_PORT = 8765;
27
- export declare const DEFAULT_LIBP2P_PORT = 4001;
28
31
  export declare function defaultsForPlatform(platform: SupportedPlatform): WizardDefaults;
29
32
  /**
30
33
  * Drive the wizard with a function that returns the next user answer for
31
34
  * a prompt. Used both by the readline-backed `runWizard` and by tests.
32
35
  */
33
- export declare function runWizardWith(defaults: WizardDefaults, ask: (label: string, fallback: string) => Promise<string>): Promise<WizardAnswers>;
36
+ export declare function runWizardWith(defaults: WizardDefaults, ask: (label: string, fallback: string) => Promise<string>, say?: (line: string) => void): Promise<WizardAnswers>;
34
37
  /** Production entrypoint — drives the wizard over stdin/stdout. */
35
38
  export declare function runWizard(defaults: WizardDefaults): Promise<WizardAnswers>;
@@ -8,36 +8,37 @@
8
8
  import { createInterface } from 'node:readline';
9
9
  import { defaultDataDir } from './paths.js';
10
10
  export const DEFAULT_UI_PORT = 8765;
11
- export const DEFAULT_LIBP2P_PORT = 4001;
12
11
  export function defaultsForPlatform(platform) {
13
12
  return {
14
13
  dataDir: defaultDataDir(platform),
15
14
  uiPort: DEFAULT_UI_PORT,
16
- libp2pPort: DEFAULT_LIBP2P_PORT,
17
15
  upnpEnabled: true,
18
- ownCadre: false,
19
16
  };
20
17
  }
21
18
  /**
22
19
  * Drive the wizard with a function that returns the next user answer for
23
20
  * a prompt. Used both by the readline-backed `runWizard` and by tests.
24
21
  */
25
- export async function runWizardWith(defaults, ask) {
26
- const dataDir = (await ask('Data directory', defaults.dataDir)).trim() || defaults.dataDir;
27
- const uiPort = parsePort(await ask('UI port (localhost only)', String(defaults.uiPort)), defaults.uiPort);
28
- const libp2pPort = parsePort(await ask('Cadre libp2p port', String(defaults.libp2pPort)), defaults.libp2pPort);
29
- const upnpEnabled = parseBool(await ask('Attempt UPnP port mapping on this network? [Y/n]', defaults.upnpEnabled ? 'Y' : 'n'), defaults.upnpEnabled);
30
- const configureDdns = parseBool(await ask('Configure DDNS now? [y/N]', 'N'), false);
31
- // Founder persona (opt-in). Most installs just donate nodes to friends and
32
- // answer no — a no leaves cadre-host donor-only (no owner node, no /auth+/nat).
33
- const ownCadre = parseBool(await ask('Also run your own personal cadre on this machine? (most people just donating nodes to friends say no) [y/N]', defaults.ownCadre ? 'Y' : 'N'), defaults.ownCadre);
34
- return { dataDir, uiPort, libp2pPort, upnpEnabled, configureDdns, ownCadre };
22
+ export async function runWizardWith(defaults, ask, say = () => { }) {
23
+ const given = defaults.given ?? {};
24
+ const dataDir = given.dataDir ? defaults.dataDir : (await ask('Data directory', defaults.dataDir)).trim() || defaults.dataDir;
25
+ const uiPort = given.uiPort
26
+ ? defaults.uiPort
27
+ : parsePort(await ask('UI port (localhost only)', String(defaults.uiPort)), defaults.uiPort);
28
+ let upnpEnabled = defaults.upnpEnabled;
29
+ if (defaults.publicInterfaceIp) {
30
+ say(`This machine has a public IP address (${defaults.publicInterfaceIp}), so it is reached directly: no router, no UPnP.`);
31
+ }
32
+ else if (!given.upnpEnabled) {
33
+ upnpEnabled = parseBool(await ask('This machine is behind a router. Ask it to map ports automatically (UPnP)? [Y/n]', defaults.upnpEnabled ? 'Y' : 'n'), defaults.upnpEnabled);
34
+ }
35
+ return { dataDir, uiPort, upnpEnabled };
35
36
  }
36
37
  /** Production entrypoint — drives the wizard over stdin/stdout. */
37
38
  export async function runWizard(defaults) {
38
39
  const rl = createInterface({ input: process.stdin, output: process.stdout });
39
40
  try {
40
- return await runWizardWith(defaults, async (label, fallback) => prompt(rl, label, fallback));
41
+ return await runWizardWith(defaults, async (label, fallback) => prompt(rl, label, fallback), (line) => console.log(line));
41
42
  }
42
43
  finally {
43
44
  rl.close();
@@ -1 +1 @@
1
- {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/installer/wizard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/installer/wizard.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,24 @@
1
1
  /**
2
- * Build the multiaddrs that should be embedded in invites.
2
+ * Build the public multiaddrs of one hosted node from the host's current
3
+ * understanding of its dialable surface.
3
4
  *
4
- * Inputs are the host's currently-best understanding of its dialable surface:
5
- * - DDNS hostname (`/dns4/<hostname>/...`) when configured AND reachable.
6
- * - Raw external IP (`/ip4/<ip>/...`) when no DDNS but reachable.
7
- * - Whatever libp2p reports otherwise — which would include a `/p2p-circuit/`
8
- * address once cadre-host passes a relay to its owner node; it passes none
9
- * yet (docs/cadre-host.md → "NAT and DDNS", item 2).
10
- *
11
- * This is intentionally a pure function so it's trivial to unit-test, and so
12
- * the NatService can be the only place that knows about settings → multiaddrs.
5
+ * Pure so it's trivial to unit-test, and so `NatService` is the only place
6
+ * that turns settings and routes into addresses. The addresses carry no
7
+ * `/p2p/` suffix: the node appends its own (cadre-core `normalizeSelfAddrs`,
8
+ * libp2p for announce addresses). The node's own LAN addresses are not here
9
+ * either — libp2p reports those itself.
13
10
  */
14
- export interface BuildInviteAddressesInput {
15
- peerId: string;
16
- externalPort: number;
11
+ import type { PortRoute } from './types.js';
12
+ export interface PublicAddressInput {
17
13
  ddnsHostname: string | null;
14
+ /** Last known public IPv4; null when unknown. */
18
15
  externalIp: string | null;
19
- reachable: boolean;
20
- /** Multiaddrs reported by the underlying libp2p node. */
21
- libp2pAddrs: string[];
16
+ cgnatDetected: boolean;
17
+ tcp: PortRoute;
18
+ ws: PortRoute | null;
22
19
  }
23
- export declare function buildInviteAddresses(input: BuildInviteAddressesInput): string[];
20
+ export declare function buildPublicAddresses(input: PublicAddressInput): string[];
21
+ /** True for a hostname of dot-separated RFC 1123 labels, at most 253 characters. */
22
+ export declare function isDnsHostname(s: string): boolean;
23
+ /** True for a dotted-quad IPv4 outside every non-public range above. */
24
+ export declare function isPublicIpv4(s: string): boolean;
@@ -1,31 +1,85 @@
1
- export function buildInviteAddresses(input) {
2
- const suffix = `/p2p/${input.peerId}`;
3
- // DNS path-of-truth: stable across IP changes.
4
- if (input.reachable && input.ddnsHostname) {
5
- return [`/dns4/${input.ddnsHostname}/tcp/${input.externalPort}${suffix}`];
6
- }
7
- // Raw IPv4: works when we know our external IP.
8
- if (input.reachable && input.externalIp && isIpv4(input.externalIp)) {
9
- return [`/ip4/${input.externalIp}/tcp/${input.externalPort}${suffix}`];
10
- }
11
- // Fallback: whatever libp2p sees. Strip any addresses that lack the
12
- // peer suffix and append it for clarity, but otherwise pass through.
13
- return input.libp2pAddrs.map((a) => withPeerSuffix(a, input.peerId));
1
+ /**
2
+ * Build the public multiaddrs of one hosted node from the host's current
3
+ * understanding of its dialable surface.
4
+ *
5
+ * Pure so it's trivial to unit-test, and so `NatService` is the only place
6
+ * that turns settings and routes into addresses. The addresses carry no
7
+ * `/p2p/` suffix: the node appends its own (cadre-core `normalizeSelfAddrs`,
8
+ * libp2p for announce addresses). The node's own LAN addresses are not here
9
+ * either — libp2p reports those itself.
10
+ */
11
+ export function buildPublicAddresses(input) {
12
+ const host = publicHost(input);
13
+ if (!host)
14
+ return [];
15
+ const out = [];
16
+ const tcpPort = routedPort(input.tcp, input.cgnatDetected);
17
+ if (tcpPort !== null)
18
+ out.push(`${host}/tcp/${tcpPort}`);
19
+ const wsPort = input.ws ? routedPort(input.ws, input.cgnatDetected) : null;
20
+ if (wsPort !== null)
21
+ out.push(`${host}/tcp/${wsPort}/ws`);
22
+ return out;
14
23
  }
15
- function withPeerSuffix(addr, peerId) {
16
- if (addr.includes(`/p2p/${peerId}`))
17
- return addr;
18
- if (addr.includes('/p2p/'))
19
- return addr; // already has *some* peer
20
- return `${addr}/p2p/${peerId}`;
24
+ /**
25
+ * `/dns4/<hostname>` when a DDNS hostname is configured (externally managed
26
+ * included), else `/ip4/<externalIp>` when that is a public IPv4, else none.
27
+ *
28
+ * A hostname that is not a DNS name is skipped rather than used: these addresses
29
+ * reach each node as `CADRE_APPEND_ANNOUNCE_ADDRS`, a comma-separated list that
30
+ * cadre-core validates at start, so one bad entry (a pasted URL, a comma) would
31
+ * stop every hosted node from starting.
32
+ */
33
+ function publicHost(input) {
34
+ if (input.ddnsHostname && isDnsHostname(input.ddnsHostname))
35
+ return `/dns4/${input.ddnsHostname}`;
36
+ if (input.externalIp && isPublicIpv4(input.externalIp))
37
+ return `/ip4/${input.externalIp}`;
38
+ return null;
21
39
  }
22
- function isIpv4(s) {
40
+ /** One RFC 1123 label: letters, digits and inner hyphens, 1–63 characters. */
41
+ const DNS_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i;
42
+ /** True for a hostname of dot-separated RFC 1123 labels, at most 253 characters. */
43
+ export function isDnsHostname(s) {
44
+ return s.length <= 253 && s.split('.').every((label) => DNS_LABEL.test(label));
45
+ }
46
+ /**
47
+ * Under CGNAT a UPnP route produces nothing: the router's mapping is on a
48
+ * carrier-private address. A manual route still does, since the user asserted
49
+ * the forward (the CGNAT check can misfire).
50
+ */
51
+ function routedPort(route, cgnatDetected) {
52
+ if (route.externalPort === null || route.source === null)
53
+ return null;
54
+ if (cgnatDetected && route.source === 'upnp')
55
+ return null;
56
+ return route.externalPort;
57
+ }
58
+ /** Private, carrier-grade, loopback, link-local, multicast and reserved IPv4 ranges. */
59
+ const NON_PUBLIC_IPV4 = [
60
+ [0x00000000, 8], // 0.0.0.0/8
61
+ [0x0a000000, 8], // 10.0.0.0/8
62
+ [0x64400000, 10], // 100.64.0.0/10 (carrier-grade NAT)
63
+ [0x7f000000, 8], // 127.0.0.0/8
64
+ [0xa9fe0000, 16], // 169.254.0.0/16
65
+ [0xac100000, 12], // 172.16.0.0/12
66
+ [0xc0a80000, 16], // 192.168.0.0/16
67
+ [0xe0000000, 4], // 224.0.0.0/4 (multicast)
68
+ [0xf0000000, 4], // 240.0.0.0/4 (reserved, broadcast)
69
+ ];
70
+ /** True for a dotted-quad IPv4 outside every non-public range above. */
71
+ export function isPublicIpv4(s) {
72
+ const octets = parseIpv4(s);
73
+ if (!octets)
74
+ return false;
75
+ const value = ((octets[0] << 24) | (octets[1] << 16) | (octets[2] << 8) | octets[3]) >>> 0;
76
+ return !NON_PUBLIC_IPV4.some(([base, prefix]) => (value >>> (32 - prefix)) === (base >>> (32 - prefix)));
77
+ }
78
+ function parseIpv4(s) {
23
79
  const m = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(s);
24
80
  if (!m)
25
- return false;
26
- return m.slice(1).every((octet) => {
27
- const n = Number(octet);
28
- return n >= 0 && n <= 255;
29
- });
81
+ return null;
82
+ const octets = m.slice(1).map(Number);
83
+ return octets.every((n) => n >= 0 && n <= 255) ? octets : null;
30
84
  }
31
85
  //# sourceMappingURL=address-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"address-resolver.js","sourceRoot":"","sources":["../../src/nat/address-resolver.ts"],"names":[],"mappings":"AAuBA,MAAM,UAAU,oBAAoB,CAAC,KAAgC;IACnE,MAAM,MAAM,GAAG,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;IACtC,+CAA+C;IAC/C,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QAC1C,OAAO,CAAC,SAAS,KAAK,CAAC,YAAY,QAAQ,KAAK,CAAC,YAAY,GAAG,MAAM,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,gDAAgD;IAChD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QACpE,OAAO,CAAC,QAAQ,KAAK,CAAC,UAAU,QAAQ,KAAK,CAAC,YAAY,GAAG,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,oEAAoE;IACpE,qEAAqE;IACrE,OAAO,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,MAAc;IAClD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,MAAM,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC,CAAE,0BAA0B;IACpE,OAAO,GAAG,IAAI,QAAQ,MAAM,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACvB,MAAM,CAAC,GAAG,8CAA8C,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"address-resolver.js","sourceRoot":"","sources":["../../src/nat/address-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { ManagedNodeInfo } from '../orchestrator/types.js';
2
+ /**
3
+ * The shortest gap between two address restarts of one node. Bounds a flapping
4
+ * router (a mapping that keeps failing and coming back) to one restart per node
5
+ * per window; a difference found inside the window waits for the first check
6
+ * after it ends.
7
+ */
8
+ export declare const NAT_ADDRESS_RESTART_MIN_INTERVAL_MS: number;
9
+ /** Asked to restart one node so it starts announcing its current public addresses. */
10
+ export type NodeAddressesStaleListener = (nodeId: string) => void | Promise<void>;
11
+ /**
12
+ * Notices a running node whose announced public addresses differ from the ones
13
+ * it should announce now, and asks its listeners to restart that node. A node
14
+ * learns its public addresses only at start (`CADRE_APPEND_ANNOUNCE_ADDRS`), so
15
+ * a restart is how a changed mapping, forward, DDNS hostname or external IP
16
+ * reaches it.
17
+ */
18
+ export declare class AddressWatch {
19
+ private readonly now;
20
+ private readonly listeners;
21
+ /** When each node was last asked to restart (ms since epoch). */
22
+ private readonly lastRestartAt;
23
+ constructor(now: () => number);
24
+ /** Register a restart listener. Returns an unsubscribe fn. */
25
+ subscribe(listener: NodeAddressesStaleListener): () => void;
26
+ /**
27
+ * Compare every running node's announced addresses with `expected(node)`, as
28
+ * sets, and ask for a restart of each that differs and was not restarted
29
+ * within {@link NAT_ADDRESS_RESTART_MIN_INTERVAL_MS}.
30
+ */
31
+ check(nodes: ManagedNodeInfo[], expected: (node: ManagedNodeInfo) => string[]): void;
32
+ /** A terminated node's id may come back as a fresh node, which owes nothing to the old window. */
33
+ private forgetMissing;
34
+ private restartedRecently;
35
+ /** Fire-and-forget: a restart takes seconds and must not hold up the NAT pass that found it. */
36
+ private notify;
37
+ }
@@ -0,0 +1,84 @@
1
+ import debug from 'debug';
2
+ const log = debug('cadre:host:nat-address-watch');
3
+ /**
4
+ * The shortest gap between two address restarts of one node. Bounds a flapping
5
+ * router (a mapping that keeps failing and coming back) to one restart per node
6
+ * per window; a difference found inside the window waits for the first check
7
+ * after it ends.
8
+ */
9
+ export const NAT_ADDRESS_RESTART_MIN_INTERVAL_MS = 10 * 60000;
10
+ /**
11
+ * Notices a running node whose announced public addresses differ from the ones
12
+ * it should announce now, and asks its listeners to restart that node. A node
13
+ * learns its public addresses only at start (`CADRE_APPEND_ANNOUNCE_ADDRS`), so
14
+ * a restart is how a changed mapping, forward, DDNS hostname or external IP
15
+ * reaches it.
16
+ */
17
+ export class AddressWatch {
18
+ constructor(now) {
19
+ this.now = now;
20
+ this.listeners = new Set();
21
+ /** When each node was last asked to restart (ms since epoch). */
22
+ this.lastRestartAt = new Map();
23
+ }
24
+ /** Register a restart listener. Returns an unsubscribe fn. */
25
+ subscribe(listener) {
26
+ this.listeners.add(listener);
27
+ return () => { this.listeners.delete(listener); };
28
+ }
29
+ /**
30
+ * Compare every running node's announced addresses with `expected(node)`, as
31
+ * sets, and ask for a restart of each that differs and was not restarted
32
+ * within {@link NAT_ADDRESS_RESTART_MIN_INTERVAL_MS}.
33
+ */
34
+ check(nodes, expected) {
35
+ this.forgetMissing(nodes);
36
+ if (this.listeners.size === 0)
37
+ return;
38
+ for (const node of nodes) {
39
+ if (node.status !== 'running')
40
+ continue;
41
+ if (sameAddressSet(node.announcedAddrs, expected(node)))
42
+ continue;
43
+ if (this.restartedRecently(node.id)) {
44
+ log('node %s announces stale addresses; restart deferred by the rate limit', node.id);
45
+ continue;
46
+ }
47
+ this.lastRestartAt.set(node.id, this.now());
48
+ log('node %s announces stale addresses; asking for a restart', node.id);
49
+ this.notify(node.id);
50
+ }
51
+ }
52
+ /** A terminated node's id may come back as a fresh node, which owes nothing to the old window. */
53
+ forgetMissing(nodes) {
54
+ const listed = new Set(nodes.map((n) => n.id));
55
+ for (const id of this.lastRestartAt.keys()) {
56
+ if (!listed.has(id))
57
+ this.lastRestartAt.delete(id);
58
+ }
59
+ }
60
+ restartedRecently(nodeId) {
61
+ const last = this.lastRestartAt.get(nodeId);
62
+ return last !== undefined && this.now() - last < NAT_ADDRESS_RESTART_MIN_INTERVAL_MS;
63
+ }
64
+ /** Fire-and-forget: a restart takes seconds and must not hold up the NAT pass that found it. */
65
+ notify(nodeId) {
66
+ for (const listener of this.listeners) {
67
+ try {
68
+ void Promise.resolve(listener(nodeId)).catch((err) => { logRestartFailure(nodeId, err); });
69
+ }
70
+ catch (err) {
71
+ logRestartFailure(nodeId, err);
72
+ }
73
+ }
74
+ }
75
+ }
76
+ function sameAddressSet(a, b) {
77
+ const left = new Set(a);
78
+ const right = new Set(b);
79
+ return left.size === right.size && [...left].every((addr) => right.has(addr));
80
+ }
81
+ function logRestartFailure(nodeId, err) {
82
+ log('address restart of node %s failed: %s', nodeId, err instanceof Error ? err.message : String(err));
83
+ }
84
+ //# sourceMappingURL=address-watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address-watch.js","sourceRoot":"","sources":["../../src/nat/address-watch.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ import type { DdnsProvider } from './index.js';
7
7
  * Response is plain text — `OK` on success, `KO` on failure.
8
8
  *
9
9
  * `hostname` may be supplied as the bare subdomain (`foo`) or the FQDN
10
- * (`foo.duckdns.org`); we strip the suffix.
10
+ * (`foo.duckdns.org`); the update strips the suffix, and `qualifyHostname`
11
+ * adds it.
11
12
  */
12
13
  export declare const duckDnsProvider: DdnsProvider;
@@ -9,7 +9,8 @@ const log = debug('cadre:host:nat-ddns:duckdns');
9
9
  * Response is plain text — `OK` on success, `KO` on failure.
10
10
  *
11
11
  * `hostname` may be supplied as the bare subdomain (`foo`) or the FQDN
12
- * (`foo.duckdns.org`); we strip the suffix.
12
+ * (`foo.duckdns.org`); the update strips the suffix, and `qualifyHostname`
13
+ * adds it.
13
14
  */
14
15
  export const duckDnsProvider = {
15
16
  id: 'duckdns',
@@ -17,6 +18,9 @@ export const duckDnsProvider = {
17
18
  configFields: [
18
19
  { key: 'token', label: 'DuckDNS token', secret: true },
19
20
  ],
21
+ qualifyHostname(hostname) {
22
+ return `${stripSuffix(hostname)}${SUFFIX}`;
23
+ },
20
24
  async update(config, hostname, ip, deps) {
21
25
  const token = config['token'];
22
26
  if (!token) {
@@ -1 +1 @@
1
- {"version":3,"file":"duckdns.js","sourceRoot":"","sources":["../../../src/nat/ddns/duckdns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,MAAM,GAAG,GAAG,KAAK,CAAC,6BAA6B,CAAC,CAAC;AAEjD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,eAAe,GAAiB;IAC3C,EAAE,EAAE,SAAS;IACb,WAAW,EAAE,SAAS;IACtB,YAAY,EAAE;QACZ,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE;KACvD;IACD,KAAK,CAAC,MAAM,CACV,MAA8B,EAC9B,QAAgB,EAChB,EAAU,EACV,IAAsB;QAEtB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,QAAQ,CAAC,0BAA0B,EAAE,yCAAyC,CAAC,CAAC;QAC5F,CAAC;QACD,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,QAAQ,CAAC,gBAAgB,EAAE,qDAAqD,QAAQ,IAAI,CAAC,CAAC;QAC1G,CAAC;QAED,MAAM,GAAG,GAAG,0CAA0C,kBAAkB,CAAC,SAAS,CAAC,UAAU,kBAAkB,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;QACtJ,GAAG,CAAC,wBAAwB,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAE7C,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,QAAQ,CAChB,oBAAoB,EACpB,2BAA4B,GAAa,CAAC,OAAO,EAAE,CACpD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAChB,oBAAoB,EACpB,gBAAgB,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,CAChD,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAChB,oBAAoB,EACpB,qBAAqB,IAAI,IAAI,SAAS,mBAAmB,CAC1D,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,GAAG,cAAc,CAAC;AAE9B,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"duckdns.js","sourceRoot":"","sources":["../../../src/nat/ddns/duckdns.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,MAAM,GAAG,GAAG,KAAK,CAAC,6BAA6B,CAAC,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAiB;IAC3C,EAAE,EAAE,SAAS;IACb,WAAW,EAAE,SAAS;IACtB,YAAY,EAAE;QACZ,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE;KACvD;IACD,eAAe,CAAC,QAAgB;QAC9B,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,CAAC;IAC7C,CAAC;IACD,KAAK,CAAC,MAAM,CACV,MAA8B,EAC9B,QAAgB,EAChB,EAAU,EACV,IAAsB;QAEtB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,QAAQ,CAAC,0BAA0B,EAAE,yCAAyC,CAAC,CAAC;QAC5F,CAAC;QACD,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,QAAQ,CAAC,gBAAgB,EAAE,qDAAqD,QAAQ,IAAI,CAAC,CAAC;QAC1G,CAAC;QAED,MAAM,GAAG,GAAG,0CAA0C,kBAAkB,CAAC,SAAS,CAAC,UAAU,kBAAkB,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;QACtJ,GAAG,CAAC,wBAAwB,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAE7C,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,QAAQ,CAChB,oBAAoB,EACpB,2BAA4B,GAAa,CAAC,OAAO,EAAE,CACpD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,QAAQ,CAChB,oBAAoB,EACpB,gBAAgB,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,CAChD,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,QAAQ,CAChB,oBAAoB,EACpB,qBAAqB,IAAI,IAAI,SAAS,mBAAmB,CAC1D,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,GAAG,cAAc,CAAC;AAE9B,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -16,6 +16,12 @@ export interface DdnsProvider {
16
16
  readonly id: string;
17
17
  readonly displayName: string;
18
18
  readonly configFields: ReadonlyArray<DdnsConfigField>;
19
+ /**
20
+ * The fully qualified name the provider publishes for a hostname as the user
21
+ * typed it. Stored in place of the typed form because hosted nodes announce the
22
+ * stored hostname as `/dns4/<hostname>`, so it has to resolve on its own.
23
+ */
24
+ qualifyHostname(hostname: string): string;
19
25
  /** Push `ip` for `hostname`. Throws NatError(ddns_update_failed) on failure. */
20
26
  update(config: Record<string, string>, hostname: string, ip: string, deps: DdnsProviderDeps): Promise<void>;
21
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nat/ddns/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AA6B/C,+BAA+B;AAC/B,MAAM,CAAC,MAAM,iBAAiB,GAA2C;IACvE,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF,qFAAqF;AACrF,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,MAAM,CAAC,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,QAAQ,CAChB,uBAAuB,EACvB,0BAA0B,UAAU,eAAe,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,aAAa;IAC3B,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAC1C,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nat/ddns/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAmC/C,+BAA+B;AAC/B,MAAM,CAAC,MAAM,iBAAiB,GAA2C;IACvE,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF,qFAAqF;AACrF,MAAM,UAAU,WAAW,CAAC,UAAkB;IAC5C,MAAM,CAAC,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,QAAQ,CAChB,uBAAuB,EACvB,0BAA0B,UAAU,eAAe,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,aAAa;IAC3B,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAC1C,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
@@ -2,20 +2,24 @@
2
2
  * NAT / DDNS substrate for cadre-host.
3
3
  *
4
4
  * See ./nat-service.ts for the top-level orchestrator and `docs/cadre-host.md`
5
- * for integration notes (the long-running process owner is `cadre-host-local-ui`).
5
+ * for integration notes (the long-running process owner is `cadre-host start`).
6
6
  */
7
- export { NatService, createNatHandlers } from './nat-service.js';
8
- export type { NatServiceOptions, CadreNodeLike, AddressesChangedListener } from './nat-service.js';
7
+ export { NatService, createNatHandlers, NAT_UNMAP_GRACE_MS, NAT_RECONCILE_INTERVAL_MS, NAT_IP_REDETECT_INTERVAL_MS, } from './nat-service.js';
8
+ export type { NatServiceOptions, NatNodeSource, NatChangeListener } from './nat-service.js';
9
+ export { NAT_ADDRESS_RESTART_MIN_INTERVAL_MS } from './address-watch.js';
10
+ export type { NodeAddressesStaleListener } from './address-watch.js';
9
11
  export { NatStore } from './nat-store.js';
10
12
  export { NatError, } from './types.js';
11
- export type { NatStatusSnapshot, NatDdnsStatus, NatSettingsFile, NatDdnsSettings, NatHandlers, NatErrorCode, PortForwardMode, DirectReachability, DdnsProviderInfo, DdnsConfigField, } from './types.js';
13
+ export type { NatStatusSnapshot, NatGatewayStatus, NatDdnsStatus, NatNetworkStatus, NetworkMode, NetworkSetting, NatSettingsFile, NatDdnsSettings, NatHandlers, NatErrorCode, DirectReachability, NodeReachability, NodeVerdict, PortKind, PortRoute, PortRouteSource, ManualForward, ManualForwardPatch, DdnsProviderInfo, DdnsConfigField, } from './types.js';
12
14
  export { ExternalIpDetector, isPlausibleIp, } from './external-ip.js';
13
15
  export type { ExternalIpResult, RouterIpProbe, ExternalIpDetectorOptions, } from './external-ip.js';
14
- export { PortMapperService, createDefaultPortMapper, DEFAULT_LEASE_TTL_MS, DEFAULT_REFRESH_MS, } from './port-mapper.js';
15
- export type { PortMapper, PortMappingResult, PortMapOptions, PortMapperState, PortMapperServiceOptions, } from './port-mapper.js';
16
- export { evaluateReachability } from './reachability.js';
17
- export { buildInviteAddresses } from './address-resolver.js';
18
- export type { BuildInviteAddressesInput } from './address-resolver.js';
16
+ export { UpnpPortMapper, pickLanAddress, DEFAULT_LEASE_TTL_MS, DEFAULT_REFRESH_MS, GATEWAY_DISCOVERY_TIMEOUT_MS, } from './port-mapper.js';
17
+ export type { PortMapper, GatewayInfo, PortMapRequest, PortMapResult, } from './port-mapper.js';
18
+ export { evaluateNodeReachability, evaluateHostReachability } from './reachability.js';
19
+ export type { NodeVerdictInput, NodeVerdictResult } from './reachability.js';
20
+ export { buildPublicAddresses, isPublicIpv4 } from './address-resolver.js';
21
+ export { publicInterfaceAddress, effectiveNetworkMode } from './network-mode.js';
22
+ export type { PublicAddressInput } from './address-resolver.js';
19
23
  export { BUILTIN_PROVIDERS, getProvider, listProviders, duckDnsProvider, DdnsUpdater, } from './ddns/index.js';
20
24
  export type { DdnsProvider, DdnsProviderDeps, DdnsUpdaterOptions, DdnsUpdateOutcome, } from './ddns/index.js';
21
25
  export { KeytarSecretsStore, FileSecretsStore, createSecretsStore, ddnsAccount, KEYTAR_SERVICE, } from './secrets/index.js';
package/dist/nat/index.js CHANGED
@@ -2,15 +2,17 @@
2
2
  * NAT / DDNS substrate for cadre-host.
3
3
  *
4
4
  * See ./nat-service.ts for the top-level orchestrator and `docs/cadre-host.md`
5
- * for integration notes (the long-running process owner is `cadre-host-local-ui`).
5
+ * for integration notes (the long-running process owner is `cadre-host start`).
6
6
  */
7
- export { NatService, createNatHandlers } from './nat-service.js';
7
+ export { NatService, createNatHandlers, NAT_UNMAP_GRACE_MS, NAT_RECONCILE_INTERVAL_MS, NAT_IP_REDETECT_INTERVAL_MS, } from './nat-service.js';
8
+ export { NAT_ADDRESS_RESTART_MIN_INTERVAL_MS } from './address-watch.js';
8
9
  export { NatStore } from './nat-store.js';
9
10
  export { NatError, } from './types.js';
10
11
  export { ExternalIpDetector, isPlausibleIp, } from './external-ip.js';
11
- export { PortMapperService, createDefaultPortMapper, DEFAULT_LEASE_TTL_MS, DEFAULT_REFRESH_MS, } from './port-mapper.js';
12
- export { evaluateReachability } from './reachability.js';
13
- export { buildInviteAddresses } from './address-resolver.js';
12
+ export { UpnpPortMapper, pickLanAddress, DEFAULT_LEASE_TTL_MS, DEFAULT_REFRESH_MS, GATEWAY_DISCOVERY_TIMEOUT_MS, } from './port-mapper.js';
13
+ export { evaluateNodeReachability, evaluateHostReachability } from './reachability.js';
14
+ export { buildPublicAddresses, isPublicIpv4 } from './address-resolver.js';
15
+ export { publicInterfaceAddress, effectiveNetworkMode } from './network-mode.js';
14
16
  export { BUILTIN_PROVIDERS, getProvider, listProviders, duckDnsProvider, DdnsUpdater, } from './ddns/index.js';
15
17
  export { KeytarSecretsStore, FileSecretsStore, createSecretsStore, ddnsAccount, KEYTAR_SERVICE, } from './secrets/index.js';
16
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nat/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EACL,QAAQ,GACT,MAAM,YAAY,CAAC;AAapB,OAAO,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,eAAe,EACf,WAAW,GACZ,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,cAAc,GACf,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nat/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,mCAAmC,EAAE,MAAM,oBAAoB,CAAC;AAEzE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EACL,QAAQ,GACT,MAAM,YAAY,CAAC;AAuBpB,OAAO,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACL,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAO1B,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAEvF,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEjF,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,eAAe,EACf,WAAW,GACZ,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,cAAc,GACf,MAAM,oBAAoB,CAAC"}