@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.
- package/README.md +347 -423
- package/dist/bin/host.d.ts +6 -3
- package/dist/bin/host.js +332 -524
- package/dist/bin/host.js.map +1 -1
- package/dist/bin/join-output.d.ts +56 -0
- package/dist/bin/join-output.js +92 -0
- package/dist/bin/join-output.js.map +1 -0
- package/dist/bin/nat-output.d.ts +54 -0
- package/dist/bin/nat-output.js +138 -0
- package/dist/bin/nat-output.js.map +1 -0
- package/dist/bin/ui-access.d.ts +22 -0
- package/dist/bin/ui-access.js +44 -0
- package/dist/bin/ui-access.js.map +1 -0
- package/dist/hosted/claim-details.d.ts +66 -0
- package/dist/hosted/claim-details.js +60 -0
- package/dist/hosted/claim-details.js.map +1 -0
- package/dist/hosted/hosted-node-service.d.ts +325 -0
- package/dist/hosted/hosted-node-service.js +678 -0
- package/dist/hosted/hosted-node-service.js.map +1 -0
- package/dist/hosted/hosted-node-store.d.ts +40 -0
- package/dist/hosted/hosted-node-store.js +126 -0
- package/dist/hosted/hosted-node-store.js.map +1 -0
- package/dist/{donation/donation-supervisor.d.ts → hosted/hosted-node-supervisor.d.ts} +70 -53
- package/dist/hosted/hosted-node-supervisor.js +396 -0
- package/dist/hosted/hosted-node-supervisor.js.map +1 -0
- package/dist/hosted/hosted-node-watcher.d.ts +95 -0
- package/dist/hosted/hosted-node-watcher.js +260 -0
- package/dist/hosted/hosted-node-watcher.js.map +1 -0
- package/dist/hosted/index.d.ts +16 -0
- package/dist/hosted/index.js +13 -0
- package/dist/hosted/index.js.map +1 -0
- package/dist/hosted/node-status.d.ts +51 -0
- package/dist/hosted/node-status.js +77 -0
- package/dist/hosted/node-status.js.map +1 -0
- package/dist/hosted/types.d.ts +141 -0
- package/dist/hosted/types.js +22 -0
- package/dist/hosted/types.js.map +1 -0
- package/dist/index.d.ts +12 -24
- package/dist/index.js +9 -19
- package/dist/index.js.map +1 -1
- package/dist/installer/config.d.ts +27 -34
- package/dist/installer/config.js +46 -15
- package/dist/installer/config.js.map +1 -1
- package/dist/installer/index.d.ts +9 -19
- package/dist/installer/index.js +21 -85
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/paths.d.ts +0 -2
- package/dist/installer/paths.js +0 -4
- package/dist/installer/paths.js.map +1 -1
- package/dist/installer/wizard.d.ts +12 -9
- package/dist/installer/wizard.js +15 -14
- package/dist/installer/wizard.js.map +1 -1
- package/dist/nat/address-resolver.d.ts +18 -17
- package/dist/nat/address-resolver.js +79 -25
- package/dist/nat/address-resolver.js.map +1 -1
- package/dist/nat/address-watch.d.ts +37 -0
- package/dist/nat/address-watch.js +84 -0
- package/dist/nat/address-watch.js.map +1 -0
- package/dist/nat/ddns/duckdns.d.ts +2 -1
- package/dist/nat/ddns/duckdns.js +5 -1
- package/dist/nat/ddns/duckdns.js.map +1 -1
- package/dist/nat/ddns/index.d.ts +6 -0
- package/dist/nat/ddns/index.js.map +1 -1
- package/dist/nat/index.d.ts +13 -9
- package/dist/nat/index.js +7 -5
- package/dist/nat/index.js.map +1 -1
- package/dist/nat/nat-service.d.ts +220 -77
- package/dist/nat/nat-service.js +653 -239
- package/dist/nat/nat-service.js.map +1 -1
- package/dist/nat/nat-store.d.ts +12 -5
- package/dist/nat/nat-store.js +124 -29
- package/dist/nat/nat-store.js.map +1 -1
- package/dist/nat/network-mode.d.ts +19 -0
- package/dist/nat/network-mode.js +32 -0
- package/dist/nat/network-mode.js.map +1 -0
- package/dist/nat/port-mapper.d.ts +83 -79
- package/dist/nat/port-mapper.js +148 -189
- package/dist/nat/port-mapper.js.map +1 -1
- package/dist/nat/reachability.d.ts +32 -15
- package/dist/nat/reachability.js +110 -22
- package/dist/nat/reachability.js.map +1 -1
- package/dist/nat/types.d.ts +98 -27
- package/dist/nat/types.js +8 -5
- package/dist/nat/types.js.map +1 -1
- package/dist/orchestrator/host-process-orchestrator.d.ts +32 -74
- package/dist/orchestrator/host-process-orchestrator.js +84 -233
- package/dist/orchestrator/host-process-orchestrator.js.map +1 -1
- package/dist/{installer/identity.d.ts → orchestrator/identity-file.d.ts} +5 -5
- package/dist/{installer/identity.js → orchestrator/identity-file.js} +6 -6
- package/dist/orchestrator/identity-file.js.map +1 -0
- package/dist/orchestrator/index.d.ts +2 -3
- package/dist/orchestrator/index.js +1 -1
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/node-identity.d.ts +6 -6
- package/dist/orchestrator/node-identity.js +7 -7
- package/dist/orchestrator/node-identity.js.map +1 -1
- package/dist/orchestrator/port-allocator.d.ts +5 -6
- package/dist/orchestrator/port-allocator.js +9 -11
- package/dist/orchestrator/port-allocator.js.map +1 -1
- package/dist/orchestrator/state-store.d.ts +3 -5
- package/dist/orchestrator/state-store.js +2 -10
- package/dist/orchestrator/state-store.js.map +1 -1
- package/dist/orchestrator/types.d.ts +33 -22
- package/dist/orchestrator/types.js.map +1 -1
- package/dist/package-version.d.ts +1 -0
- package/dist/package-version.js +4 -0
- package/dist/package-version.js.map +1 -0
- package/dist/server/error-handler.d.ts +5 -25
- package/dist/server/error-handler.js +11 -74
- package/dist/server/error-handler.js.map +1 -1
- package/dist/server/events/types.d.ts +7 -11
- package/dist/server/events/types.js +2 -1
- package/dist/server/events/types.js.map +1 -1
- package/dist/server/index.d.ts +11 -37
- package/dist/server/index.js +30 -48
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/hosted-nodes.d.ts +28 -0
- package/dist/server/routes/hosted-nodes.js +68 -0
- package/dist/server/routes/hosted-nodes.js.map +1 -0
- package/dist/server/routes/nat.d.ts +4 -1
- package/dist/server/routes/nat.js +13 -2
- package/dist/server/routes/nat.js.map +1 -1
- package/dist/server/routes/nodes.d.ts +6 -20
- package/dist/server/routes/nodes.js +7 -86
- package/dist/server/routes/nodes.js.map +1 -1
- package/dist/server/routes/settings.d.ts +3 -7
- package/dist/server/routes/settings.js +18 -8
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/status.d.ts +2 -25
- package/dist/server/routes/status.js +3 -43
- package/dist/server/routes/status.js.map +1 -1
- package/dist/server/server.js +8 -8
- package/dist/server/settings-store.d.ts +2 -2
- package/dist/server/settings-store.js +2 -2
- package/dist/server/static.js +1 -2
- package/dist/server/static.js.map +1 -1
- package/dist/ui/assets/index-BHd8CWZA.css +1 -0
- package/dist/ui/assets/index-Ccr2GjPT.js +23 -0
- package/dist/ui/assets/index-Ccr2GjPT.js.map +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/update/index.d.ts +2 -2
- package/dist/update/index.js +2 -2
- package/dist/update/store.d.ts +1 -1
- package/dist/update/store.js +1 -1
- package/dist/update/types.d.ts +1 -1
- package/dist/update/types.js +1 -1
- package/package.json +5 -7
- package/src/__tests__/cli-nat.smoke.test.ts +219 -212
- package/src/__tests__/cli.smoke.test.ts +2 -2
- package/src/__tests__/global-setup.ts +2 -3
- package/src/__tests__/orchestrator-claim-secret.test.ts +111 -0
- package/src/__tests__/orchestrator-env-scrub.test.ts +160 -163
- package/src/__tests__/orchestrator-handle-contract.ts +134 -134
- package/src/__tests__/orchestrator-node-identity.test.ts +177 -203
- package/src/__tests__/orchestrator-ports.test.ts +124 -143
- package/src/__tests__/orchestrator-push.test.ts +138 -146
- package/src/__tests__/orchestrator.test.ts +1017 -1063
- package/src/__tests__/ui-access.test.ts +30 -0
- package/src/bin/host.ts +397 -572
- package/src/bin/join-output.ts +120 -0
- package/src/bin/nat-output.ts +188 -0
- package/src/bin/ui-access.ts +50 -0
- package/src/{donation → hosted}/__tests__/fake-orchestrator.test.ts +172 -173
- package/src/{donation → hosted}/__tests__/fake-orchestrator.ts +43 -23
- package/src/hosted/__tests__/hosted-node-service.test.ts +708 -0
- package/src/hosted/__tests__/hosted-node-supervisor.test.ts +475 -0
- package/src/hosted/__tests__/test-invitation.ts +33 -0
- package/src/hosted/claim-details.ts +103 -0
- package/src/hosted/hosted-node-service.ts +814 -0
- package/src/hosted/hosted-node-store.ts +144 -0
- package/src/hosted/hosted-node-supervisor.ts +439 -0
- package/src/hosted/hosted-node-watcher.ts +288 -0
- package/src/hosted/index.ts +53 -0
- package/src/hosted/node-status.ts +97 -0
- package/src/hosted/types.ts +160 -0
- package/src/index.ts +72 -91
- package/src/installer/__tests__/config.test.ts +15 -40
- package/src/installer/__tests__/installer.smoke.test.ts +184 -263
- package/src/installer/__tests__/wizard.test.ts +25 -13
- package/src/installer/config.ts +201 -175
- package/src/installer/index.ts +252 -327
- package/src/installer/paths.ts +104 -109
- package/src/installer/wizard.ts +24 -26
- package/src/nat/__tests__/address-resolver.test.ts +107 -82
- package/src/nat/__tests__/nat-service.test.ts +608 -515
- package/src/nat/__tests__/nat-store.test.ts +49 -12
- package/src/nat/__tests__/network-mode.test.ts +38 -0
- package/src/nat/__tests__/port-mapper.test.ts +30 -191
- package/src/nat/__tests__/reachability.test.ts +96 -13
- package/src/nat/address-resolver.ts +94 -52
- package/src/nat/address-watch.ts +92 -0
- package/src/nat/ddns/duckdns.ts +5 -1
- package/src/nat/ddns/index.ts +6 -0
- package/src/nat/index.ts +33 -13
- package/src/nat/nat-service.ts +942 -501
- package/src/nat/nat-store.ts +126 -31
- package/src/nat/network-mode.ts +36 -0
- package/src/nat/port-mapper.ts +241 -329
- package/src/nat/reachability.ts +155 -34
- package/src/nat/types.ts +110 -37
- package/src/{installer/__tests__/identity.test.ts → orchestrator/__tests__/identity-file.test.ts} +34 -34
- package/src/orchestrator/__tests__/node-identity.test.ts +62 -62
- package/src/orchestrator/host-process-orchestrator.ts +1089 -1260
- package/src/{installer/identity.ts → orchestrator/identity-file.ts} +56 -56
- package/src/orchestrator/index.ts +9 -10
- package/src/orchestrator/node-identity.ts +41 -41
- package/src/orchestrator/port-allocator.ts +71 -73
- package/src/orchestrator/state-store.ts +76 -90
- package/src/orchestrator/types.ts +34 -23
- package/src/package-version.ts +4 -0
- package/src/server/__tests__/bus.test.ts +38 -38
- package/src/server/__tests__/error-handler.test.ts +81 -118
- package/src/server/__tests__/fakes.ts +15 -18
- package/src/server/__tests__/hosted-nodes-route.test.ts +161 -0
- package/src/server/__tests__/nodes-route.test.ts +114 -283
- package/src/server/__tests__/publishers.test.ts +193 -180
- package/src/server/__tests__/server.smoke.test.ts +134 -223
- package/src/server/__tests__/settings-route.test.ts +210 -195
- package/src/server/__tests__/sse-route.test.ts +119 -119
- package/src/server/__tests__/status-route.test.ts +82 -121
- package/src/server/error-handler.ts +112 -178
- package/src/server/events/types.ts +20 -24
- package/src/server/index.ts +223 -267
- package/src/server/routes/hosted-nodes.ts +83 -0
- package/src/server/routes/nat.ts +75 -63
- package/src/server/routes/nodes.ts +96 -188
- package/src/server/routes/settings.ts +20 -15
- package/src/server/routes/status.ts +5 -67
- package/src/server/server.ts +8 -8
- package/src/server/settings-store.ts +2 -2
- package/src/server/static.ts +1 -2
- package/src/update/index.ts +2 -2
- package/src/update/store.ts +1 -1
- package/src/update/types.ts +1 -1
- package/dist/auth/duration.d.ts +0 -1
- package/dist/auth/duration.js +0 -32
- package/dist/auth/duration.js.map +0 -1
- package/dist/auth/index.d.ts +0 -11
- package/dist/auth/index.js +0 -9
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/self-label.d.ts +0 -36
- package/dist/auth/self-label.js +0 -57
- package/dist/auth/self-label.js.map +0 -1
- package/dist/auth/trust-circle-store.d.ts +0 -26
- package/dist/auth/trust-circle-store.js +0 -129
- package/dist/auth/trust-circle-store.js.map +0 -1
- package/dist/auth/trust-circle.d.ts +0 -156
- package/dist/auth/trust-circle.js +0 -307
- package/dist/auth/trust-circle.js.map +0 -1
- package/dist/auth/types.d.ts +0 -84
- package/dist/auth/types.js +0 -24
- package/dist/auth/types.js.map +0 -1
- package/dist/donation/donation-service.d.ts +0 -389
- package/dist/donation/donation-service.js +0 -828
- package/dist/donation/donation-service.js.map +0 -1
- package/dist/donation/donation-store.d.ts +0 -51
- package/dist/donation/donation-store.js +0 -152
- package/dist/donation/donation-store.js.map +0 -1
- package/dist/donation/donation-supervisor.js +0 -364
- package/dist/donation/donation-supervisor.js.map +0 -1
- package/dist/donation/grant-service.d.ts +0 -80
- package/dist/donation/grant-service.js +0 -210
- package/dist/donation/grant-service.js.map +0 -1
- package/dist/donation/grant-store.d.ts +0 -38
- package/dist/donation/grant-store.js +0 -135
- package/dist/donation/grant-store.js.map +0 -1
- package/dist/donation/index.d.ts +0 -20
- package/dist/donation/index.js +0 -17
- package/dist/donation/index.js.map +0 -1
- package/dist/donation/types.d.ts +0 -224
- package/dist/donation/types.js +0 -40
- package/dist/donation/types.js.map +0 -1
- package/dist/installer/identity.js.map +0 -1
- package/dist/owner/index.d.ts +0 -11
- package/dist/owner/index.js +0 -11
- package/dist/owner/index.js.map +0 -1
- package/dist/owner/owner-node-client.d.ts +0 -110
- package/dist/owner/owner-node-client.js +0 -184
- package/dist/owner/owner-node-client.js.map +0 -1
- package/dist/server/routes/bootstrap-node-validation.d.ts +0 -115
- package/dist/server/routes/bootstrap-node-validation.js +0 -197
- package/dist/server/routes/bootstrap-node-validation.js.map +0 -1
- package/dist/server/routes/grants-admin.d.ts +0 -29
- package/dist/server/routes/grants-admin.js +0 -58
- package/dist/server/routes/grants-admin.js.map +0 -1
- package/dist/server/routes/grants.d.ts +0 -28
- package/dist/server/routes/grants.js +0 -165
- package/dist/server/routes/grants.js.map +0 -1
- package/dist/server/routes/provision-request-validation.d.ts +0 -45
- package/dist/server/routes/provision-request-validation.js +0 -97
- package/dist/server/routes/provision-request-validation.js.map +0 -1
- package/dist/server/routes/strands.d.ts +0 -20
- package/dist/server/routes/strands.js +0 -38
- package/dist/server/routes/strands.js.map +0 -1
- package/dist/server/routes/trust-circle.d.ts +0 -17
- package/dist/server/routes/trust-circle.js +0 -35
- package/dist/server/routes/trust-circle.js.map +0 -1
- package/dist/strands/index.d.ts +0 -7
- package/dist/strands/index.js +0 -6
- package/dist/strands/index.js.map +0 -1
- package/dist/strands/strand-service.d.ts +0 -50
- package/dist/strands/strand-service.js +0 -103
- package/dist/strands/strand-service.js.map +0 -1
- package/dist/strands/types.d.ts +0 -93
- package/dist/strands/types.js +0 -23
- package/dist/strands/types.js.map +0 -1
- package/dist/ui/assets/index-C6nELNfC.js +0 -23
- package/dist/ui/assets/index-C6nELNfC.js.map +0 -1
- package/dist/ui/assets/index-TtIYSeZO.css +0 -1
- package/src/__tests__/cli-invite.smoke.test.ts +0 -192
- package/src/__tests__/host-owner.smoke.test.ts +0 -123
- package/src/__tests__/orchestrator-owner.test.ts +0 -234
- package/src/__tests__/orchestrator-pin-keys.test.ts +0 -152
- package/src/auth/__tests__/duration.test.ts +0 -28
- package/src/auth/__tests__/self-label.test.ts +0 -85
- package/src/auth/__tests__/trust-circle-integration.test.ts +0 -152
- package/src/auth/__tests__/trust-circle-store.test.ts +0 -115
- package/src/auth/__tests__/trust-circle.test.ts +0 -445
- package/src/auth/duration.ts +0 -33
- package/src/auth/index.ts +0 -21
- package/src/auth/self-label.ts +0 -74
- package/src/auth/trust-circle-store.ts +0 -155
- package/src/auth/trust-circle.ts +0 -395
- package/src/auth/types.ts +0 -99
- package/src/donation/__tests__/donation-service.test.ts +0 -1193
- package/src/donation/__tests__/donation-supervisor.test.ts +0 -548
- package/src/donation/__tests__/grant-service.test.ts +0 -213
- package/src/donation/__tests__/grant-store.test.ts +0 -113
- package/src/donation/donation-service.ts +0 -1033
- package/src/donation/donation-store.ts +0 -176
- package/src/donation/donation-supervisor.ts +0 -411
- package/src/donation/grant-service.ts +0 -252
- package/src/donation/grant-store.ts +0 -152
- package/src/donation/index.ts +0 -65
- package/src/donation/types.ts +0 -260
- package/src/owner/__tests__/owner-node-client.test.ts +0 -194
- package/src/owner/index.ts +0 -12
- package/src/owner/owner-node-client.ts +0 -259
- package/src/server/__tests__/bootstrap-node-validation.test.ts +0 -138
- package/src/server/__tests__/grants-admin-route.test.ts +0 -171
- package/src/server/__tests__/grants-route.test.ts +0 -394
- package/src/server/__tests__/strands-route.test.ts +0 -234
- package/src/server/routes/bootstrap-node-validation.ts +0 -206
- package/src/server/routes/grants-admin.ts +0 -74
- package/src/server/routes/grants.ts +0 -193
- package/src/server/routes/provision-request-validation.ts +0 -105
- package/src/server/routes/strands.ts +0 -54
- package/src/server/routes/trust-circle.ts +0 -49
- package/src/strands/__tests__/strand-service.test.ts +0 -165
- package/src/strands/index.ts +0 -14
- package/src/strands/strand-service.ts +0 -135
- package/src/strands/types.ts +0 -102
package/src/installer/config.ts
CHANGED
|
@@ -1,175 +1,201 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `host.config.json` schema + I/O.
|
|
3
|
-
*
|
|
4
|
-
* This file captures the wizard's output. Subsystems (
|
|
5
|
-
* orchestrator) each own their own files under `<dataDir>/`; this is NOT
|
|
6
|
-
* an umbrella config.
|
|
7
|
-
*
|
|
8
|
-
* Schema version:
|
|
9
|
-
* does not match `CURRENT_VERSION` is rejected on read rather than
|
|
10
|
-
* reinterpreted, so a future incompatible layout fails loudly instead of
|
|
11
|
-
* being silently misread.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
*
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
) {
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `host.config.json` schema + I/O.
|
|
3
|
+
*
|
|
4
|
+
* This file captures the wizard's output. Subsystems (hosted nodes, NAT,
|
|
5
|
+
* orchestrator) each own their own files under `<dataDir>/`; this is NOT
|
|
6
|
+
* an umbrella config.
|
|
7
|
+
*
|
|
8
|
+
* Schema version: 3. `version` is a forward guard — a file whose version
|
|
9
|
+
* does not match `CURRENT_VERSION` is rejected on read rather than
|
|
10
|
+
* reinterpreted, so a future incompatible layout fails loudly instead of
|
|
11
|
+
* being silently misread.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
15
|
+
import { isIP } from 'node:net';
|
|
16
|
+
import { dirname } from 'node:path';
|
|
17
|
+
|
|
18
|
+
import { destinationPeerIdOf } from '@serfab/cadre-core';
|
|
19
|
+
|
|
20
|
+
export interface UpdatesConfig {
|
|
21
|
+
/** When true, the daily-check timer auto-applies updates. Default false. */
|
|
22
|
+
autoApply: boolean;
|
|
23
|
+
/** Optional override for the manifest URL (env var still wins). */
|
|
24
|
+
manifestUrl?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Non-secret push (FCM/APNs) settings. The actual private keys (and the FCM
|
|
29
|
+
* service-account / APNs key identifiers) live in the secret store — see
|
|
30
|
+
* `src/push/`. Only these app-config bits, which are safe to keep in plaintext
|
|
31
|
+
* `host.config.json`, are stored here. Absent ⇒ push is not configured.
|
|
32
|
+
*/
|
|
33
|
+
export interface PushSettings {
|
|
34
|
+
/** APNs app-config (the `.p8` private key + key/team ids stay in the secret store). */
|
|
35
|
+
apns?: {
|
|
36
|
+
/** App bundle id → APNs `apns-topic` header. */
|
|
37
|
+
bundleId: string;
|
|
38
|
+
/** `true` → production APNs host; false/undefined → sandbox (dev/TestFlight). */
|
|
39
|
+
production?: boolean;
|
|
40
|
+
};
|
|
41
|
+
/** Per-(peer,strand) anti-spam cooldown (ms) forwarded into the node's push block. */
|
|
42
|
+
cooldownMs?: number;
|
|
43
|
+
/** Per-strand burst-coalescing window (ms) forwarded into the node's push block. */
|
|
44
|
+
debounceMs?: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Which addresses a hosted node's QR code carries (cadre-core's `selectNodeClaimAddresses`).
|
|
49
|
+
* Absent ⇒ `{ lan: 'auto' }`. Read on every claim-code request, so an edit applies to the
|
|
50
|
+
* next code shown.
|
|
51
|
+
*/
|
|
52
|
+
export interface ClaimAddressSettings {
|
|
53
|
+
/**
|
|
54
|
+
* The LAN address a phone at home dials: `'auto'` (the address on the router's subnet, else
|
|
55
|
+
* the machine's primary one; none in public-IP mode), `'none'` (public addresses only), or an
|
|
56
|
+
* IP address. Other private addresses (Docker bridges, VPNs) are left out either way.
|
|
57
|
+
*/
|
|
58
|
+
lan?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Exact addresses to put in every code instead, for an operator who knows better than the
|
|
61
|
+
* rule, such as one name behind a proxy. Each names no destination peer (a relay address ends
|
|
62
|
+
* at its `/p2p-circuit` hop); every node's code appends its own peer id.
|
|
63
|
+
*/
|
|
64
|
+
addrs?: string[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Why a `claimAddresses` value is unacceptable, naming the field; undefined when it is fine. */
|
|
68
|
+
export function claimAddressSettingsProblem(value: unknown): string | undefined {
|
|
69
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return '"claimAddresses" must be an object';
|
|
70
|
+
const o = value as Record<string, unknown>;
|
|
71
|
+
for (const key of Object.keys(o)) {
|
|
72
|
+
if (key !== 'lan' && key !== 'addrs') return `Unknown setting "claimAddresses.${key}"`;
|
|
73
|
+
}
|
|
74
|
+
if (o.lan !== undefined) {
|
|
75
|
+
if (typeof o.lan !== 'string' || (o.lan !== 'auto' && o.lan !== 'none' && isIP(o.lan) === 0)) {
|
|
76
|
+
return '"claimAddresses.lan" must be "auto", "none" or an IP address';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (o.addrs !== undefined) {
|
|
80
|
+
if (!Array.isArray(o.addrs) || !o.addrs.every((a) => typeof a === 'string')) {
|
|
81
|
+
return '"claimAddresses.addrs" must be a list of multiaddr strings';
|
|
82
|
+
}
|
|
83
|
+
for (const addr of o.addrs as string[]) {
|
|
84
|
+
const problem = exactClaimAddressProblem(addr);
|
|
85
|
+
if (problem) return `"claimAddresses.addrs" entry "${addr}" ${problem}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Why one `claimAddresses.addrs` entry is unacceptable. It must not name its destination peer:
|
|
93
|
+
* the list is host-wide and each hosted node's code appends its own peer id, so a named one
|
|
94
|
+
* would be some other node's address in every code but that node's.
|
|
95
|
+
*/
|
|
96
|
+
function exactClaimAddressProblem(addr: string): string | undefined {
|
|
97
|
+
let destination: string | null;
|
|
98
|
+
try {
|
|
99
|
+
destination = destinationPeerIdOf(addr.trim());
|
|
100
|
+
} catch {
|
|
101
|
+
return 'is not a valid multiaddr';
|
|
102
|
+
}
|
|
103
|
+
return destination === null ? undefined : 'must not end in /p2p/<peer id>: each node\'s own id is appended';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface HostConfigFile {
|
|
107
|
+
version: 3;
|
|
108
|
+
/** A stable per-install id, for log correlation. */
|
|
109
|
+
installId: string;
|
|
110
|
+
/** Localhost-only management UI + API listener port. */
|
|
111
|
+
uiPort: number;
|
|
112
|
+
/** Self-reference (convenient for service-host ExecStart). */
|
|
113
|
+
dataDir: string;
|
|
114
|
+
/** Whether UPnP/NAT-PMP should be attempted at start time. */
|
|
115
|
+
upnpEnabled: boolean;
|
|
116
|
+
/** ISO timestamp the wizard wrote this file. */
|
|
117
|
+
installedAt: string;
|
|
118
|
+
/** Installer (= package) version that wrote this file. */
|
|
119
|
+
installerVersion: string;
|
|
120
|
+
/** Update-flow settings; defaults: { autoApply: false }. */
|
|
121
|
+
updates: UpdatesConfig;
|
|
122
|
+
/**
|
|
123
|
+
* Non-secret push settings (bundle id, sandbox/prod toggle, cooldown/debounce).
|
|
124
|
+
* Optional — absent when push is not configured. Private keys never live here;
|
|
125
|
+
* they are read from the secret store at node-spawn time (`src/push/`).
|
|
126
|
+
*/
|
|
127
|
+
push?: PushSettings;
|
|
128
|
+
/** Which addresses claim codes carry; absent ⇒ automatic. */
|
|
129
|
+
claimAddresses?: ClaimAddressSettings;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const CURRENT_VERSION = 3;
|
|
133
|
+
|
|
134
|
+
export function writeHostConfig(filePath: string, cfg: HostConfigFile): void {
|
|
135
|
+
if (cfg.version !== CURRENT_VERSION) {
|
|
136
|
+
throw new Error(`Refusing to write host.config.json with version=${cfg.version} (current: ${CURRENT_VERSION})`);
|
|
137
|
+
}
|
|
138
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
139
|
+
writeFileSync(filePath, JSON.stringify(cfg, null, 2) + '\n', 'utf8');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Apply a partial patch to the persisted config (read-modify-write). */
|
|
143
|
+
export function updateHostConfig(
|
|
144
|
+
filePath: string,
|
|
145
|
+
patch: Partial<Omit<HostConfigFile, 'version'>>,
|
|
146
|
+
): HostConfigFile {
|
|
147
|
+
const current = readHostConfig(filePath);
|
|
148
|
+
const next: HostConfigFile = {
|
|
149
|
+
...current,
|
|
150
|
+
...patch,
|
|
151
|
+
updates: { ...current.updates, ...(patch.updates ?? {}) },
|
|
152
|
+
version: CURRENT_VERSION,
|
|
153
|
+
};
|
|
154
|
+
writeHostConfig(filePath, next);
|
|
155
|
+
return next;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function readHostConfig(filePath: string): HostConfigFile {
|
|
159
|
+
const raw = readFileSync(filePath, 'utf8');
|
|
160
|
+
let parsed: unknown;
|
|
161
|
+
try {
|
|
162
|
+
parsed = JSON.parse(raw);
|
|
163
|
+
} catch (err) {
|
|
164
|
+
throw new Error(`Failed to parse host.config.json at ${filePath}: ${(err as Error).message}`, { cause: err });
|
|
165
|
+
}
|
|
166
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
167
|
+
throw new Error(`host.config.json at ${filePath} is not a JSON object`);
|
|
168
|
+
}
|
|
169
|
+
const obj = parsed as Record<string, unknown>;
|
|
170
|
+
if (obj.version !== CURRENT_VERSION) {
|
|
171
|
+
throw new Error(
|
|
172
|
+
`host.config.json at ${filePath} has unsupported version=${obj.version} (this build expects ${CURRENT_VERSION})`,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
if (!isHostConfigShape(obj)) {
|
|
176
|
+
throw new Error(`host.config.json at ${filePath} is missing required fields`);
|
|
177
|
+
}
|
|
178
|
+
const claimAddressesProblem = obj.claimAddresses === undefined ? undefined : claimAddressSettingsProblem(obj.claimAddresses);
|
|
179
|
+
if (claimAddressesProblem) throw new Error(`host.config.json at ${filePath}: ${claimAddressesProblem}`);
|
|
180
|
+
return obj;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function isHostConfigShape(v: unknown): v is HostConfigFile {
|
|
184
|
+
if (!v || typeof v !== 'object') return false;
|
|
185
|
+
const o = v as Record<string, unknown>;
|
|
186
|
+
if (
|
|
187
|
+
typeof o.installId !== 'string' ||
|
|
188
|
+
typeof o.uiPort !== 'number' ||
|
|
189
|
+
typeof o.dataDir !== 'string' ||
|
|
190
|
+
typeof o.upnpEnabled !== 'boolean' ||
|
|
191
|
+
typeof o.installedAt !== 'string' ||
|
|
192
|
+
typeof o.installerVersion !== 'string'
|
|
193
|
+
) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
const updates = o.updates as Record<string, unknown> | undefined;
|
|
197
|
+
if (!updates || typeof updates !== 'object') return false;
|
|
198
|
+
if (typeof updates.autoApply !== 'boolean') return false;
|
|
199
|
+
if (updates.manifestUrl !== undefined && typeof updates.manifestUrl !== 'string') return false;
|
|
200
|
+
return true;
|
|
201
|
+
}
|