@serfab/cadre-host 0.8.1 → 0.10.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/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.js +1 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/self-label.d.ts +36 -0
- package/dist/auth/self-label.js +57 -0
- package/dist/auth/self-label.js.map +1 -0
- package/dist/auth/trust-circle.d.ts +36 -9
- package/dist/auth/trust-circle.js +40 -20
- package/dist/auth/trust-circle.js.map +1 -1
- package/dist/auth/types.d.ts +2 -2
- package/dist/bin/host.js +291 -54
- package/dist/bin/host.js.map +1 -1
- package/dist/donation/__tests__/fake-orchestrator.d.ts +103 -0
- package/dist/donation/__tests__/fake-orchestrator.js +180 -0
- package/dist/donation/__tests__/fake-orchestrator.js.map +1 -0
- package/dist/donation/donation-service.d.ts +361 -0
- package/dist/donation/donation-service.js +763 -0
- package/dist/donation/donation-service.js.map +1 -0
- package/dist/donation/donation-store.d.ts +49 -0
- package/dist/donation/donation-store.js +148 -0
- package/dist/donation/donation-store.js.map +1 -0
- package/dist/donation/donation-supervisor.d.ts +167 -0
- package/dist/donation/donation-supervisor.js +341 -0
- package/dist/donation/donation-supervisor.js.map +1 -0
- package/dist/donation/grant-service.d.ts +71 -0
- package/dist/donation/grant-service.js +163 -0
- package/dist/donation/grant-service.js.map +1 -0
- package/dist/donation/grant-store.d.ts +38 -0
- package/dist/donation/grant-store.js +135 -0
- package/dist/donation/grant-store.js.map +1 -0
- package/dist/donation/index.d.ts +20 -0
- package/dist/donation/index.js +17 -0
- package/dist/donation/index.js.map +1 -0
- package/dist/donation/types.d.ts +201 -0
- package/dist/donation/types.js +40 -0
- package/dist/donation/types.js.map +1 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/installer/config.d.ts +26 -0
- package/dist/installer/config.js +13 -0
- package/dist/installer/config.js.map +1 -1
- package/dist/installer/index.d.ts +2 -0
- package/dist/installer/index.js +3 -0
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/wizard.d.ts +4 -0
- package/dist/installer/wizard.js +5 -1
- package/dist/installer/wizard.js.map +1 -1
- package/dist/nat/nat-service.d.ts +5 -5
- package/dist/nat/nat-service.js +9 -9
- package/dist/nat/nat-service.js.map +1 -1
- package/dist/nat/types.d.ts +1 -1
- package/dist/orchestrator/host-process-orchestrator.d.ts +144 -32
- package/dist/orchestrator/host-process-orchestrator.js +397 -128
- package/dist/orchestrator/host-process-orchestrator.js.map +1 -1
- package/dist/orchestrator/index.d.ts +3 -3
- package/dist/orchestrator/index.js +1 -1
- package/dist/orchestrator/index.js.map +1 -1
- package/dist/orchestrator/node-identity.d.ts +26 -0
- package/dist/orchestrator/node-identity.js +36 -0
- package/dist/orchestrator/node-identity.js.map +1 -0
- package/dist/orchestrator/port-allocator.d.ts +14 -0
- package/dist/orchestrator/port-allocator.js +45 -0
- package/dist/orchestrator/port-allocator.js.map +1 -1
- package/dist/orchestrator/state-store.d.ts +5 -5
- package/dist/orchestrator/state-store.js +2 -2
- package/dist/orchestrator/state-store.js.map +1 -1
- package/dist/orchestrator/types.d.ts +8 -8
- package/dist/owner/index.d.ts +11 -0
- package/dist/owner/index.js +11 -0
- package/dist/owner/index.js.map +1 -0
- package/dist/owner/owner-node-client.d.ts +110 -0
- package/dist/{authority/authority-node-client.js → owner/owner-node-client.js} +58 -17
- package/dist/owner/owner-node-client.js.map +1 -0
- package/dist/server/error-handler.d.ts +22 -1
- package/dist/server/error-handler.js +64 -1
- package/dist/server/error-handler.js.map +1 -1
- package/dist/server/events/types.d.ts +3 -0
- package/dist/server/index.d.ts +33 -2
- package/dist/server/index.js +43 -16
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/grants-admin.d.ts +17 -0
- package/dist/server/routes/grants-admin.js +32 -0
- package/dist/server/routes/grants-admin.js.map +1 -0
- package/dist/server/routes/grants.d.ts +28 -0
- package/dist/server/routes/grants.js +182 -0
- package/dist/server/routes/grants.js.map +1 -0
- package/dist/server/routes/nodes.d.ts +5 -4
- package/dist/server/routes/nodes.js +19 -18
- package/dist/server/routes/nodes.js.map +1 -1
- package/dist/server/routes/settings.d.ts +6 -1
- package/dist/server/routes/settings.js +5 -2
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/status.d.ts +8 -4
- package/dist/server/routes/status.js +9 -4
- package/dist/server/routes/status.js.map +1 -1
- package/dist/server/routes/strands.d.ts +20 -0
- package/dist/server/routes/strands.js +38 -0
- package/dist/server/routes/strands.js.map +1 -0
- package/dist/strands/index.d.ts +7 -0
- package/dist/strands/index.js +6 -0
- package/dist/strands/index.js.map +1 -0
- package/dist/strands/strand-service.d.ts +50 -0
- package/dist/strands/strand-service.js +103 -0
- package/dist/strands/strand-service.js.map +1 -0
- package/dist/strands/types.d.ts +93 -0
- package/dist/strands/types.js +23 -0
- package/dist/strands/types.js.map +1 -0
- package/dist/ui/assets/index-BVoqLjyX.css +1 -0
- package/dist/ui/assets/index-C-iks41M.js +17 -0
- package/dist/ui/assets/index-C-iks41M.js.map +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/update/release-key.d.ts +1 -1
- package/dist/update/release-key.js +8 -6
- package/dist/update/release-key.js.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/build-targets.test.ts +26 -0
- package/src/__tests__/global-setup.ts +51 -0
- package/src/__tests__/{host-authority.smoke.test.ts → host-owner.smoke.test.ts} +7 -7
- package/src/__tests__/orchestrator-env-scrub.test.ts +140 -0
- package/src/__tests__/orchestrator-node-identity.test.ts +204 -0
- package/src/__tests__/{orchestrator-authority.test.ts → orchestrator-owner.test.ts} +33 -33
- package/src/__tests__/orchestrator-pin-keys.test.ts +153 -0
- package/src/__tests__/orchestrator-push.test.ts +10 -10
- package/src/__tests__/orchestrator.test.ts +387 -6
- package/src/auth/__tests__/self-label.test.ts +85 -0
- package/src/auth/__tests__/trust-circle-integration.test.ts +152 -147
- package/src/auth/__tests__/trust-circle.test.ts +55 -11
- package/src/auth/index.ts +2 -0
- package/src/auth/self-label.ts +74 -0
- package/src/auth/trust-circle.ts +54 -22
- package/src/auth/types.ts +2 -2
- package/src/bin/host.ts +1299 -1038
- package/src/donation/__tests__/donation-service.test.ts +1068 -0
- package/src/donation/__tests__/donation-supervisor.test.ts +510 -0
- package/src/donation/__tests__/fake-orchestrator.test.ts +168 -0
- package/src/donation/__tests__/fake-orchestrator.ts +225 -0
- package/src/donation/__tests__/grant-service.test.ts +213 -0
- package/src/donation/__tests__/grant-store.test.ts +113 -0
- package/src/donation/donation-service.ts +962 -0
- package/src/donation/donation-store.ts +171 -0
- package/src/donation/donation-supervisor.ts +388 -0
- package/src/donation/grant-service.ts +200 -0
- package/src/donation/grant-store.ts +152 -0
- package/src/donation/index.ts +64 -0
- package/src/donation/types.ts +243 -0
- package/src/index.ts +51 -5
- package/src/installer/__tests__/config.test.ts +27 -1
- package/src/installer/__tests__/installer.smoke.test.ts +31 -1
- package/src/installer/__tests__/wizard.test.ts +5 -1
- package/src/installer/config.ts +34 -0
- package/src/installer/index.ts +5 -0
- package/src/installer/wizard.ts +12 -1
- package/src/nat/__tests__/nat-service.test.ts +5 -5
- package/src/nat/nat-service.ts +10 -10
- package/src/nat/types.ts +1 -1
- package/src/orchestrator/__tests__/node-identity.test.ts +62 -0
- package/src/orchestrator/host-process-orchestrator.ts +401 -134
- package/src/orchestrator/index.ts +3 -3
- package/src/orchestrator/node-identity.ts +40 -0
- package/src/orchestrator/port-allocator.ts +48 -0
- package/src/orchestrator/state-store.ts +7 -7
- package/src/orchestrator/types.ts +8 -8
- package/src/{authority/__tests__/authority-node-client.test.ts → owner/__tests__/owner-node-client.test.ts} +45 -17
- package/src/owner/index.ts +12 -0
- package/src/{authority/authority-node-client.ts → owner/owner-node-client.ts} +83 -23
- package/src/server/__tests__/error-handler.test.ts +22 -0
- package/src/server/__tests__/grants-admin-route.test.ts +73 -0
- package/src/server/__tests__/grants-route.test.ts +263 -0
- package/src/server/__tests__/nodes-route.test.ts +25 -25
- package/src/server/__tests__/server.smoke.test.ts +75 -0
- package/src/server/__tests__/settings-route.test.ts +17 -0
- package/src/server/__tests__/status-route.test.ts +21 -0
- package/src/server/__tests__/strands-route.test.ts +233 -0
- package/src/server/error-handler.ts +67 -1
- package/src/server/events/types.ts +1 -0
- package/src/server/index.ts +75 -17
- package/src/server/routes/grants-admin.ts +41 -0
- package/src/server/routes/grants.ts +210 -0
- package/src/server/routes/nodes.ts +19 -18
- package/src/server/routes/settings.ts +11 -3
- package/src/server/routes/status.ts +18 -8
- package/src/server/routes/strands.ts +54 -0
- package/src/strands/__tests__/strand-service.test.ts +165 -0
- package/src/strands/index.ts +14 -0
- package/src/strands/strand-service.ts +135 -0
- package/src/strands/types.ts +102 -0
- package/src/update/__tests__/release-key.test.ts +16 -3
- package/src/update/release-key.ts +8 -6
- package/dist/authority/authority-node-client.d.ts +0 -77
- package/dist/authority/authority-node-client.js.map +0 -1
- package/dist/authority/index.d.ts +0 -11
- package/dist/authority/index.js +0 -11
- package/dist/authority/index.js.map +0 -1
- package/dist/ui/assets/index-BlMXQPSw.js +0 -14
- package/dist/ui/assets/index-BlMXQPSw.js.map +0 -1
- package/dist/ui/assets/index-BwU5mJGF.css +0 -1
- package/src/authority/index.ts +0 -12
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTTP client for the
|
|
2
|
+
* HTTP client for the owner node's loopback admin channel (the 6.6
|
|
3
3
|
* `cadre-node-admin-channel` contract).
|
|
4
4
|
*
|
|
5
5
|
* cadre-host's manager process holds no in-process `CadreNode`; it spawns the
|
|
6
|
-
* admin's
|
|
7
|
-
* and delegates all
|
|
8
|
-
* client. The client implements **
|
|
9
|
-
* the trust-circle one (`auth/trust-circle.ts`)
|
|
10
|
-
* (`nat/nat-service.ts`)
|
|
6
|
+
* admin's owner node as a managed child (see `HostProcessOrchestrator`)
|
|
7
|
+
* and delegates all owner/membership/identity operations to it over this
|
|
8
|
+
* client. The client implements **all three** trimmed `CadreNodeLike`
|
|
9
|
+
* interfaces — the trust-circle one (`auth/trust-circle.ts`), the NAT one
|
|
10
|
+
* (`nat/nat-service.ts`), and the strand one (`strands/strand-service.ts`) —
|
|
11
|
+
* plus `pushInviteAddresses` and `addDrone` (the node-donation requester side).
|
|
11
12
|
*
|
|
12
13
|
* Transport: `Authorization: Bearer <token>` against
|
|
13
14
|
* `http://127.0.0.1:<adminPort>`. Every response uses the cadre-provider
|
|
14
15
|
* envelope `{ ok: true, data }` / `{ ok: false, error: { code, message } }`.
|
|
15
16
|
* A refused connection, a transport error, or any non-2xx response surfaces
|
|
16
|
-
* as {@link
|
|
17
|
+
* as {@link OwnerNodeUnavailableError}; the trust-circle / NAT services
|
|
17
18
|
* translate that into a `node_unavailable` domain error so the management API
|
|
18
19
|
* returns a clear 503 rather than a raw 500.
|
|
19
20
|
*/
|
|
20
21
|
import debug from 'debug';
|
|
21
|
-
const log = debug('cadre:host:
|
|
22
|
+
const log = debug('cadre:host:owner-client');
|
|
22
23
|
/**
|
|
23
|
-
* Raised when the
|
|
24
|
+
* Raised when the owner node's admin channel can't be reached or returns
|
|
24
25
|
* a non-success response. Carries the node's stable error `code` when one was
|
|
25
26
|
* present in the envelope (e.g. `not_ready`, `not_authorized`).
|
|
26
27
|
*/
|
|
27
|
-
export class
|
|
28
|
+
export class OwnerNodeUnavailableError extends Error {
|
|
28
29
|
constructor(message, nodeCode) {
|
|
29
30
|
super(message);
|
|
30
|
-
this.name = '
|
|
31
|
+
this.name = 'OwnerNodeUnavailableError';
|
|
31
32
|
if (nodeCode !== undefined)
|
|
32
33
|
this.nodeCode = nodeCode;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
|
-
export class
|
|
36
|
+
export class OwnerNodeClient {
|
|
36
37
|
/**
|
|
37
38
|
* @param endpoint Either a fixed `{ baseUrl, token }` or a getter returning
|
|
38
|
-
* the current endpoint (pass `orchestrator.
|
|
39
|
+
* the current endpoint (pass `orchestrator.getOwnerAdminEndpoint`
|
|
39
40
|
* bound, so a restart's new bearer token is picked up automatically).
|
|
40
41
|
*/
|
|
41
42
|
constructor(endpoint, opts = {}) {
|
|
@@ -78,6 +79,15 @@ export class AuthorityNodeClient {
|
|
|
78
79
|
const data = await this.request('GET', `/admin/members/${encodeURIComponent(peerId)}`);
|
|
79
80
|
return data.member;
|
|
80
81
|
}
|
|
82
|
+
/** Authorized-membership surface (excludes self) — see {@link listMembers} for the addressable one. */
|
|
83
|
+
async listAuthorizedMembers() {
|
|
84
|
+
const data = await this.request('GET', '/admin/authorized-members');
|
|
85
|
+
return data.members;
|
|
86
|
+
}
|
|
87
|
+
async isAuthorizedMember(peerId) {
|
|
88
|
+
const data = await this.request('GET', `/admin/authorized-members/${encodeURIComponent(peerId)}`);
|
|
89
|
+
return data.member;
|
|
90
|
+
}
|
|
81
91
|
// --- NAT CadreNodeLike ---
|
|
82
92
|
async getPeerId() {
|
|
83
93
|
const data = await this.request('GET', '/admin/identity');
|
|
@@ -87,6 +97,37 @@ export class AuthorityNodeClient {
|
|
|
87
97
|
const data = await this.request('GET', '/admin/multiaddrs');
|
|
88
98
|
return data.multiaddrs;
|
|
89
99
|
}
|
|
100
|
+
// --- strand CadreNodeLike ---
|
|
101
|
+
/** This party's strands plus the node's current control-connection count. */
|
|
102
|
+
async listStrands() {
|
|
103
|
+
return await this.request('GET', '/admin/strands');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Remove this party's participation in one strand.
|
|
107
|
+
*
|
|
108
|
+
* `?confirm=1` is appended **only** when the caller asked for it. The node
|
|
109
|
+
* refuses an unconfirmed closed-strand removal with `confirmation_required`;
|
|
110
|
+
* that refusal is surfaced, never retried with the flag added — the row holds
|
|
111
|
+
* this party's membership key for the strand and nothing else does.
|
|
112
|
+
*/
|
|
113
|
+
async removeStrand(strandId, opts) {
|
|
114
|
+
const query = opts.confirm ? '?confirm=1' : '';
|
|
115
|
+
return await this.request('DELETE', `/admin/strands/${encodeURIComponent(strandId)}${query}`);
|
|
116
|
+
}
|
|
117
|
+
// --- drone seeding (node-donation requester side) ---
|
|
118
|
+
/**
|
|
119
|
+
* Mint a seed authorizing a drone — a provider-hosted / donated node — to join
|
|
120
|
+
* this node's cadre. The node signs the seed with its own authority key; only
|
|
121
|
+
* the signed, public `encodedSeed` is returned (the private key never leaves
|
|
122
|
+
* the node). This is the requester ("phone") side of the node-donation flow:
|
|
123
|
+
* the donor host presents the returned seed to the donated node's `POST /seed`.
|
|
124
|
+
*/
|
|
125
|
+
async addDrone(options) {
|
|
126
|
+
return await this.request('POST', '/admin/add-drone', {
|
|
127
|
+
dronePeerId: options.dronePeerId,
|
|
128
|
+
droneMultiaddrs: options.droneMultiaddrs,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
90
131
|
// --- push-model invite addresses ---
|
|
91
132
|
/** Push the NAT-resolved addresses the node should embed in future invites. */
|
|
92
133
|
async pushInviteAddresses(addresses) {
|
|
@@ -96,7 +137,7 @@ export class AuthorityNodeClient {
|
|
|
96
137
|
resolveEndpoint() {
|
|
97
138
|
const ep = typeof this.endpointSource === 'function' ? this.endpointSource() : this.endpointSource;
|
|
98
139
|
if (!ep) {
|
|
99
|
-
throw new
|
|
140
|
+
throw new OwnerNodeUnavailableError('Owner node admin endpoint is not available');
|
|
100
141
|
}
|
|
101
142
|
return ep;
|
|
102
143
|
}
|
|
@@ -115,14 +156,14 @@ export class AuthorityNodeClient {
|
|
|
115
156
|
catch (err) {
|
|
116
157
|
const message = err instanceof Error ? err.message : String(err);
|
|
117
158
|
log('admin %s %s transport error: %s', method, path, message);
|
|
118
|
-
throw new
|
|
159
|
+
throw new OwnerNodeUnavailableError(`Owner node unreachable: ${message}`);
|
|
119
160
|
}
|
|
120
161
|
const envelope = await this.parseEnvelope(res);
|
|
121
162
|
if (!res.ok || !envelope.ok) {
|
|
122
163
|
const code = envelope.error?.code;
|
|
123
164
|
const message = envelope.error?.message ?? `admin ${method} ${path} → HTTP ${res.status}`;
|
|
124
165
|
log('admin %s %s failed: [%s] %s', method, path, code ?? res.status, message);
|
|
125
|
-
throw new
|
|
166
|
+
throw new OwnerNodeUnavailableError(message, code);
|
|
126
167
|
}
|
|
127
168
|
return envelope.data;
|
|
128
169
|
}
|
|
@@ -140,4 +181,4 @@ export class AuthorityNodeClient {
|
|
|
140
181
|
return {};
|
|
141
182
|
}
|
|
142
183
|
}
|
|
143
|
-
//# sourceMappingURL=
|
|
184
|
+
//# sourceMappingURL=owner-node-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owner-node-client.js","sourceRoot":"","sources":["../../src/owner/owner-node-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Fastify error handler — translates known typed errors to stable HTTP status
|
|
3
3
|
* codes and uniform `{ ok: false, error: { code, message } }` payloads.
|
|
4
4
|
*
|
|
5
|
-
* Codes (cross-referenced with `auth/types.ts`, `nat/types.ts`, `
|
|
5
|
+
* Codes (cross-referenced with `auth/types.ts`, `nat/types.ts`, `strands/types.ts`,
|
|
6
|
+
* `update/types.ts`):
|
|
6
7
|
* - TrustCircleError
|
|
7
8
|
* invalid_label, invalid_token → 400
|
|
8
9
|
* not_found, already_redeemed → 404
|
|
@@ -16,12 +17,32 @@
|
|
|
16
17
|
* mapping_failed, router_unreachable,
|
|
17
18
|
* ip_detection_failed, ddns_update_failed → 500
|
|
18
19
|
* node_unavailable → 503
|
|
20
|
+
* - StrandError
|
|
21
|
+
* invalid_id → 400
|
|
22
|
+
* confirmation_required → 428
|
|
23
|
+
* node_unavailable → 503
|
|
24
|
+
* internal → 500
|
|
19
25
|
* - UpdateErrorException
|
|
20
26
|
* manifest_invalid, no_update_available,
|
|
21
27
|
* min_previous_version → 400
|
|
22
28
|
* apply_in_progress → 409
|
|
23
29
|
* signature_invalid, unsupported_state_version,
|
|
24
30
|
* apply_failed, rollback_failed, storage_error → 500
|
|
31
|
+
* - GrantError
|
|
32
|
+
* invalid_label, invalid_max_nodes,
|
|
33
|
+
* invalid_ttl → 400
|
|
34
|
+
* not_found → 404
|
|
35
|
+
* storage_error → 500
|
|
36
|
+
* - DonationError
|
|
37
|
+
* invalid_request → 400
|
|
38
|
+
* unauthorized → 401
|
|
39
|
+
* forbidden → 403
|
|
40
|
+
* not_found → 404
|
|
41
|
+
* invalid_state → 409
|
|
42
|
+
* quota_exceeded → 429
|
|
43
|
+
* orchestrator_error, storage_error → 500
|
|
44
|
+
* seed_failed → 502
|
|
45
|
+
* peer_unavailable → 503
|
|
25
46
|
* - everything else → 500 (code "internal")
|
|
26
47
|
*/
|
|
27
48
|
import type { FastifyInstance } from 'fastify';
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Fastify error handler — translates known typed errors to stable HTTP status
|
|
3
3
|
* codes and uniform `{ ok: false, error: { code, message } }` payloads.
|
|
4
4
|
*
|
|
5
|
-
* Codes (cross-referenced with `auth/types.ts`, `nat/types.ts`, `
|
|
5
|
+
* Codes (cross-referenced with `auth/types.ts`, `nat/types.ts`, `strands/types.ts`,
|
|
6
|
+
* `update/types.ts`):
|
|
6
7
|
* - TrustCircleError
|
|
7
8
|
* invalid_label, invalid_token → 400
|
|
8
9
|
* not_found, already_redeemed → 404
|
|
@@ -16,18 +17,40 @@
|
|
|
16
17
|
* mapping_failed, router_unreachable,
|
|
17
18
|
* ip_detection_failed, ddns_update_failed → 500
|
|
18
19
|
* node_unavailable → 503
|
|
20
|
+
* - StrandError
|
|
21
|
+
* invalid_id → 400
|
|
22
|
+
* confirmation_required → 428
|
|
23
|
+
* node_unavailable → 503
|
|
24
|
+
* internal → 500
|
|
19
25
|
* - UpdateErrorException
|
|
20
26
|
* manifest_invalid, no_update_available,
|
|
21
27
|
* min_previous_version → 400
|
|
22
28
|
* apply_in_progress → 409
|
|
23
29
|
* signature_invalid, unsupported_state_version,
|
|
24
30
|
* apply_failed, rollback_failed, storage_error → 500
|
|
31
|
+
* - GrantError
|
|
32
|
+
* invalid_label, invalid_max_nodes,
|
|
33
|
+
* invalid_ttl → 400
|
|
34
|
+
* not_found → 404
|
|
35
|
+
* storage_error → 500
|
|
36
|
+
* - DonationError
|
|
37
|
+
* invalid_request → 400
|
|
38
|
+
* unauthorized → 401
|
|
39
|
+
* forbidden → 403
|
|
40
|
+
* not_found → 404
|
|
41
|
+
* invalid_state → 409
|
|
42
|
+
* quota_exceeded → 429
|
|
43
|
+
* orchestrator_error, storage_error → 500
|
|
44
|
+
* seed_failed → 502
|
|
45
|
+
* peer_unavailable → 503
|
|
25
46
|
* - everything else → 500 (code "internal")
|
|
26
47
|
*/
|
|
27
48
|
import debug from 'debug';
|
|
28
49
|
import { TrustCircleError } from '../auth/types.js';
|
|
29
50
|
import { NatError } from '../nat/types.js';
|
|
51
|
+
import { StrandError } from '../strands/types.js';
|
|
30
52
|
import { UpdateErrorException } from '../update/types.js';
|
|
53
|
+
import { GrantError, DonationError } from '../donation/types.js';
|
|
31
54
|
const log = debug('cadre:host:error-handler');
|
|
32
55
|
const TRUST_STATUS = {
|
|
33
56
|
invalid_label: 400,
|
|
@@ -50,6 +73,37 @@ const NAT_STATUS = {
|
|
|
50
73
|
ddns_update_failed: 500,
|
|
51
74
|
node_unavailable: 503,
|
|
52
75
|
};
|
|
76
|
+
/**
|
|
77
|
+
* 428 (Precondition Required) for `confirmation_required`: the node refused a
|
|
78
|
+
* closed-strand removal because the caller had not confirmed. It is not a 400
|
|
79
|
+
* (the request was well-formed) and not a 409 (nothing conflicts) — the caller
|
|
80
|
+
* must re-send with the precondition satisfied.
|
|
81
|
+
*/
|
|
82
|
+
const STRAND_STATUS = {
|
|
83
|
+
invalid_id: 400,
|
|
84
|
+
confirmation_required: 428,
|
|
85
|
+
node_unavailable: 503,
|
|
86
|
+
internal: 500,
|
|
87
|
+
};
|
|
88
|
+
const GRANT_STATUS = {
|
|
89
|
+
invalid_label: 400,
|
|
90
|
+
invalid_max_nodes: 400,
|
|
91
|
+
invalid_ttl: 400,
|
|
92
|
+
not_found: 404,
|
|
93
|
+
storage_error: 500,
|
|
94
|
+
};
|
|
95
|
+
const DONATION_STATUS = {
|
|
96
|
+
unauthorized: 401,
|
|
97
|
+
forbidden: 403,
|
|
98
|
+
quota_exceeded: 429,
|
|
99
|
+
invalid_request: 400,
|
|
100
|
+
not_found: 404,
|
|
101
|
+
invalid_state: 409,
|
|
102
|
+
seed_failed: 502,
|
|
103
|
+
peer_unavailable: 503,
|
|
104
|
+
orchestrator_error: 500,
|
|
105
|
+
storage_error: 500,
|
|
106
|
+
};
|
|
53
107
|
const UPDATE_STATUS = {
|
|
54
108
|
manifest_invalid: 400,
|
|
55
109
|
no_update_available: 400,
|
|
@@ -83,9 +137,18 @@ function classify(err) {
|
|
|
83
137
|
if (err instanceof NatError) {
|
|
84
138
|
return { status: NAT_STATUS[err.code] ?? 500, code: err.code, message: err.message };
|
|
85
139
|
}
|
|
140
|
+
if (err instanceof StrandError) {
|
|
141
|
+
return { status: STRAND_STATUS[err.code] ?? 500, code: err.code, message: err.message };
|
|
142
|
+
}
|
|
86
143
|
if (err instanceof UpdateErrorException) {
|
|
87
144
|
return { status: UPDATE_STATUS[err.code] ?? 500, code: err.code, message: err.message };
|
|
88
145
|
}
|
|
146
|
+
if (err instanceof GrantError) {
|
|
147
|
+
return { status: GRANT_STATUS[err.code] ?? 500, code: err.code, message: err.message };
|
|
148
|
+
}
|
|
149
|
+
if (err instanceof DonationError) {
|
|
150
|
+
return { status: DONATION_STATUS[err.code] ?? 500, code: err.code, message: err.message };
|
|
151
|
+
}
|
|
89
152
|
// Fastify body-parsing / validation errors have a statusCode we should honour.
|
|
90
153
|
if (typeof err.statusCode === 'number' && err.statusCode >= 400 && err.statusCode < 600) {
|
|
91
154
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/server/error-handler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/server/error-handler.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -16,7 +16,9 @@ import type { FastifyInstance } from 'fastify';
|
|
|
16
16
|
import type { HostProcessOrchestrator } from '../orchestrator/index.js';
|
|
17
17
|
import type { TrustCircleService } from '../auth/index.js';
|
|
18
18
|
import type { NatService } from '../nat/index.js';
|
|
19
|
+
import type { StrandService } from '../strands/index.js';
|
|
19
20
|
import type { UpdateService } from '../update/index.js';
|
|
21
|
+
import type { GrantService, DonationService } from '../donation/index.js';
|
|
20
22
|
import { EventBus } from './events/bus.js';
|
|
21
23
|
import { HostSettingsStore } from './settings-store.js';
|
|
22
24
|
export interface LocalUiServerOptions {
|
|
@@ -26,10 +28,39 @@ export interface LocalUiServerOptions {
|
|
|
26
28
|
dataDir: string;
|
|
27
29
|
/** Wired dependencies — all owned by the caller. */
|
|
28
30
|
orchestrator: HostProcessOrchestrator;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Trust-circle service — present only when the host runs its own personal
|
|
33
|
+
* cadre (`ownCadre.enabled`). Absent in donor-only mode, where `/auth/*`
|
|
34
|
+
* stays unmounted and 404s.
|
|
35
|
+
*/
|
|
36
|
+
trustCircle?: TrustCircleService;
|
|
37
|
+
/**
|
|
38
|
+
* NAT service — present only when the host runs its own personal cadre.
|
|
39
|
+
* Absent in donor-only mode (loopback-only in v1), where `/nat/*` stays
|
|
40
|
+
* unmounted and 404s.
|
|
41
|
+
*/
|
|
42
|
+
nat?: NatService;
|
|
43
|
+
/**
|
|
44
|
+
* Strand service — present only when the host runs its own personal cadre.
|
|
45
|
+
* Absent in donor-only mode, where there is no owner node to ask, so
|
|
46
|
+
* `/api/strands` stays unmounted and 404s through the static handler.
|
|
47
|
+
*/
|
|
48
|
+
strands?: StrandService;
|
|
31
49
|
/** Optional — 6.4.2 lands this; nullable while still iterating. */
|
|
32
50
|
update?: UpdateService;
|
|
51
|
+
/**
|
|
52
|
+
* Donation grant layer. When present, mounts the loopback admin surface at
|
|
53
|
+
* `/grants-admin` (issue/list/revoke). Optional so existing callers/tests
|
|
54
|
+
* that don't exercise donations need not wire it.
|
|
55
|
+
*/
|
|
56
|
+
grants?: GrantService;
|
|
57
|
+
/**
|
|
58
|
+
* Donation lifecycle service. When present (alongside `grants`), mounts the
|
|
59
|
+
* bearer-gated grantee-facing provisioning surface at `/grants`
|
|
60
|
+
* (provision / peer / seed / terminate). Optional so callers/tests that don't
|
|
61
|
+
* exercise the donor path need not wire it.
|
|
62
|
+
*/
|
|
63
|
+
donations?: DonationService;
|
|
33
64
|
/** Settings I/O facade. Defaults to a new one rooted at `dataDir`. */
|
|
34
65
|
settingsStore?: HostSettingsStore;
|
|
35
66
|
/** Bus instance — pass the same one to subsystems that publish events. */
|
package/dist/server/index.js
CHANGED
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { createTrustCircleHandlers } from '../auth/index.js';
|
|
16
16
|
import { createNatHandlers } from '../nat/index.js';
|
|
17
|
+
import { createStrandHandlers } from '../strands/index.js';
|
|
17
18
|
import { createUpdateHandlers } from '../update/index.js';
|
|
19
|
+
import { createGrantAdminHandlers } from '../donation/index.js';
|
|
18
20
|
import { EventBus } from './events/bus.js';
|
|
19
21
|
import { registerSseRoute } from './events/sse-route.js';
|
|
20
22
|
import { registerErrorHandler } from './error-handler.js';
|
|
@@ -23,10 +25,13 @@ import { registerStaticMount } from './static.js';
|
|
|
23
25
|
import { buildFastify, startListening, stopListening } from './server.js';
|
|
24
26
|
import { registerNatRoutes } from './routes/nat.js';
|
|
25
27
|
import { registerTrustCircleRoutes } from './routes/trust-circle.js';
|
|
28
|
+
import { registerStrandRoutes } from './routes/strands.js';
|
|
26
29
|
import { registerUpdateRoutes } from './routes/update.js';
|
|
27
30
|
import { registerStatusRoute } from './routes/status.js';
|
|
28
31
|
import { registerNodesRoutes } from './routes/nodes.js';
|
|
29
32
|
import { registerSettingsRoutes } from './routes/settings.js';
|
|
33
|
+
import { registerGrantsAdminRoutes } from './routes/grants-admin.js';
|
|
34
|
+
import { registerGrantsRoutes } from './routes/grants.js';
|
|
30
35
|
import { HostSettingsStore } from './settings-store.js';
|
|
31
36
|
/** How often to poll UpdateService.getState() looking for new versions. */
|
|
32
37
|
const UPDATE_OBSERVER_INTERVAL_MS = 60000;
|
|
@@ -44,17 +49,36 @@ export function createLocalUiServer(opts) {
|
|
|
44
49
|
});
|
|
45
50
|
registerStatusRoute(app, {
|
|
46
51
|
orchestrator: opts.orchestrator,
|
|
47
|
-
trustCircle: opts.trustCircle,
|
|
48
|
-
nat: opts.nat,
|
|
52
|
+
...(opts.trustCircle ? { trustCircle: opts.trustCircle } : {}),
|
|
53
|
+
...(opts.nat ? { nat: opts.nat } : {}),
|
|
49
54
|
...(opts.update ? { update: opts.update } : {}),
|
|
50
55
|
});
|
|
51
56
|
registerNodesRoutes(app, { orchestrator: opts.orchestrator });
|
|
52
|
-
registerSettingsRoutes(app, { settingsStore, nat: opts.nat, ...(opts.update ? { update: opts.update } : {}) });
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
registerSettingsRoutes(app, { settingsStore, ...(opts.nat ? { nat: opts.nat } : {}), ...(opts.update ? { update: opts.update } : {}) });
|
|
58
|
+
// Trust-circle + NAT + strand surfaces exist only when the host runs its own
|
|
59
|
+
// personal cadre. In donor-only mode they're left unmounted, so `/auth/*`,
|
|
60
|
+
// `/nat/*` and `/api/strands` fall through to the static not-found handler and
|
|
61
|
+
// 404 (see static.ts).
|
|
62
|
+
if (opts.trustCircle) {
|
|
63
|
+
registerTrustCircleRoutes(app, { handlers: createTrustCircleHandlers(opts.trustCircle), events });
|
|
64
|
+
}
|
|
65
|
+
if (opts.nat) {
|
|
66
|
+
registerNatRoutes(app, { handlers: createNatHandlers(opts.nat), events });
|
|
67
|
+
}
|
|
68
|
+
if (opts.strands) {
|
|
69
|
+
registerStrandRoutes(app, { handlers: createStrandHandlers(opts.strands), events });
|
|
70
|
+
}
|
|
55
71
|
if (opts.update) {
|
|
56
72
|
registerUpdateRoutes(app, { handlers: createUpdateHandlers(opts.update), events });
|
|
57
73
|
}
|
|
74
|
+
if (opts.grants) {
|
|
75
|
+
registerGrantsAdminRoutes(app, { handlers: createGrantAdminHandlers(opts.grants) });
|
|
76
|
+
// Grantee-facing provisioning surface needs both the donation service and a
|
|
77
|
+
// grant validator (the GrantService doubles as the validator).
|
|
78
|
+
if (opts.donations) {
|
|
79
|
+
registerGrantsRoutes(app, { donations: opts.donations, grants: opts.grants });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
58
82
|
// Static mount registers as the not-found handler — declared last so the
|
|
59
83
|
// API paths above win.
|
|
60
84
|
registerStaticMount(app, { ...(opts.staticRoot !== undefined ? { rootDir: opts.staticRoot } : {}) });
|
|
@@ -85,17 +109,20 @@ export function createLocalUiServer(opts) {
|
|
|
85
109
|
});
|
|
86
110
|
}));
|
|
87
111
|
// One-shot connectivity publish — the SPA will get a sane initial
|
|
88
|
-
// signal even if no settings have changed yet this session.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
112
|
+
// signal even if no settings have changed yet this session. Skipped in
|
|
113
|
+
// donor-only mode, where there is no NatService.
|
|
114
|
+
if (opts.nat) {
|
|
115
|
+
try {
|
|
116
|
+
const snap = opts.nat.getStatus();
|
|
117
|
+
events.publish({
|
|
118
|
+
type: 'connectivity-changed',
|
|
119
|
+
portMode: snap.portMode,
|
|
120
|
+
directReachability: snap.directReachability,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// NatService.start may not have completed; harmless to skip.
|
|
125
|
+
}
|
|
99
126
|
}
|
|
100
127
|
// Update observer: poll UpdateService.getState() every 60 s and emit
|
|
101
128
|
// `update-available` when `available.version` changes. Cheap, avoids
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Donation grant **admin** HTTP routes — thin adapters around
|
|
3
|
+
* `GrantAdminHandlers` (`createGrantAdminHandlers(service)`).
|
|
4
|
+
*
|
|
5
|
+
* Mount path: `/grants-admin` — the admin surface the `cadre-host grant` CLI
|
|
6
|
+
* targets. It is **loopback, no bearer**: same-machine admin, matching
|
|
7
|
+
* cadre-host's local-UI "no login" posture (see docs/cadre-host.md §
|
|
8
|
+
* Security posture). This is distinct from the grantee-facing `/grants`
|
|
9
|
+
* provisioning surface that carries the bearer gate — that arrives in the
|
|
10
|
+
* `2-donation-service` ticket.
|
|
11
|
+
*/
|
|
12
|
+
import type { FastifyInstance } from 'fastify';
|
|
13
|
+
import type { GrantAdminHandlers } from '../../donation/types.js';
|
|
14
|
+
export interface GrantsAdminRoutesOptions {
|
|
15
|
+
handlers: GrantAdminHandlers;
|
|
16
|
+
}
|
|
17
|
+
export declare function registerGrantsAdminRoutes(app: FastifyInstance, opts: GrantsAdminRoutesOptions): void;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Donation grant **admin** HTTP routes — thin adapters around
|
|
3
|
+
* `GrantAdminHandlers` (`createGrantAdminHandlers(service)`).
|
|
4
|
+
*
|
|
5
|
+
* Mount path: `/grants-admin` — the admin surface the `cadre-host grant` CLI
|
|
6
|
+
* targets. It is **loopback, no bearer**: same-machine admin, matching
|
|
7
|
+
* cadre-host's local-UI "no login" posture (see docs/cadre-host.md §
|
|
8
|
+
* Security posture). This is distinct from the grantee-facing `/grants`
|
|
9
|
+
* provisioning surface that carries the bearer gate — that arrives in the
|
|
10
|
+
* `2-donation-service` ticket.
|
|
11
|
+
*/
|
|
12
|
+
export function registerGrantsAdminRoutes(app, opts) {
|
|
13
|
+
const { handlers } = opts;
|
|
14
|
+
app.get('/grants-admin', async () => {
|
|
15
|
+
return handlers.listGrants();
|
|
16
|
+
});
|
|
17
|
+
app.post('/grants-admin', async (request) => {
|
|
18
|
+
const body = (request.body ?? {});
|
|
19
|
+
const label = typeof body.label === 'string' ? body.label : '';
|
|
20
|
+
const args = { label };
|
|
21
|
+
if (typeof body.maxNodes === 'number')
|
|
22
|
+
args.maxNodes = body.maxNodes;
|
|
23
|
+
if (typeof body.ttlMs === 'number')
|
|
24
|
+
args.ttlMs = body.ttlMs;
|
|
25
|
+
return handlers.postGrant(args);
|
|
26
|
+
});
|
|
27
|
+
app.delete('/grants-admin/:token', async (request) => {
|
|
28
|
+
await handlers.deleteGrant(request.params.token);
|
|
29
|
+
return { ok: true };
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=grants-admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grants-admin.js","sourceRoot":"","sources":["../../../src/server/routes/grants-admin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,MAAM,UAAU,yBAAyB,CAAC,GAAoB,EAAE,IAA8B;IAC5F,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE1B,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAA6D,CAAC;QAC9F,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAyD,EAAE,KAAK,EAAE,CAAC;QAC7E,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QACrE,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5D,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAgC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAClF,MAAM,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grantee-facing donation routes — the HTTP surface an external cadre authority
|
|
3
|
+
* (a friend's phone) drives to have this host donate a node into *its* cadre.
|
|
4
|
+
*
|
|
5
|
+
* Mount path: `/grants`. Distinct from the loopback-only `/grants-admin` surface
|
|
6
|
+
* (issue/list/revoke, no bearer): this one is **bearer-gated** — every request
|
|
7
|
+
* carries `Authorization: Bearer <grant-token>`, and a grantee sees only the
|
|
8
|
+
* donations its own grant authorized (the single cross-grantee boundary,
|
|
9
|
+
* analogous to cadre-provider's per-customer ownership check).
|
|
10
|
+
*
|
|
11
|
+
* Reachability is out of scope here: in v1 this mounts on the loopback
|
|
12
|
+
* management server, same as the trust-circle / NAT surfaces. Physically exposing
|
|
13
|
+
* it to a remote phone is `backlog/feat-cadre-host-wan-grant-reachability`.
|
|
14
|
+
*
|
|
15
|
+
* Errors: handlers either send a `{ ok:false, error:{code,message} }` envelope
|
|
16
|
+
* inline (auth / body validation) or let the `DonationService` throw a
|
|
17
|
+
* `DonationError`, which `server/error-handler.ts` maps to the matching HTTP
|
|
18
|
+
* status and the same envelope.
|
|
19
|
+
*/
|
|
20
|
+
import type { FastifyInstance } from 'fastify';
|
|
21
|
+
import type { DonationService } from '../../donation/donation-service.js';
|
|
22
|
+
import type { GrantValidator } from '../../donation/types.js';
|
|
23
|
+
export interface GrantsRoutesOptions {
|
|
24
|
+
donations: DonationService;
|
|
25
|
+
/** Validates the presented bearer for non-provisioning ops (provision revalidates internally). */
|
|
26
|
+
grants: GrantValidator;
|
|
27
|
+
}
|
|
28
|
+
export declare function registerGrantsRoutes(app: FastifyInstance, opts: GrantsRoutesOptions): void;
|