@camstack/server 1.2.572 → 1.2.574
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/agent/agent-http-auth.js +59 -6
- package/dist/agent/agent-http.js +94 -16
- package/dist/agent/agent-mesh-join.js +2 -0
- package/dist/agent/agent-node-certificates.js +5 -0
- package/dist/agent/agent-pairing-local.js +108 -0
- package/dist/agent/agent-pairing-routes.js +87 -0
- package/dist/agent/agent-pairing-store.js +105 -0
- package/dist/agent/main.js +65 -0
- package/dist/api/core/agent-pairing.router.js +264 -0
- package/dist/api/core/certificates.router.js +2 -2
- package/dist/api/trpc/generated-cap-routers.js +9 -0
- package/dist/api/trpc/trpc.router.js +7 -0
- package/dist/core/agent/agent-pairing-http.js +150 -0
- package/dist/core/agent/hub-agent-pairing.js +123 -0
- package/dist/core/agent/node-certificates-client.js +1 -0
- package/dist/core/moleculer/hub-mesh-guard.js +1 -0
- package/dist/core/moleculer/moleculer.service.js +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HubAgentPairing = void 0;
|
|
4
|
+
/** A browse takes seconds; a list asked within this window reuses the last scan. */
|
|
5
|
+
const SCAN_REUSE_MS = 4_000;
|
|
6
|
+
/** A typed address is remembered this long without being heard again. */
|
|
7
|
+
const ADDRESS_MEMORY_MS = 30 * 60_000;
|
|
8
|
+
const DEFAULT_PORT = 4444;
|
|
9
|
+
class HubAgentPairing {
|
|
10
|
+
deps;
|
|
11
|
+
scanned = null;
|
|
12
|
+
scanning = null;
|
|
13
|
+
manual = new Map();
|
|
14
|
+
timer = null;
|
|
15
|
+
now;
|
|
16
|
+
constructor(deps) {
|
|
17
|
+
this.deps = deps;
|
|
18
|
+
this.now = deps.now ?? Date.now;
|
|
19
|
+
}
|
|
20
|
+
/** Start advancing active pairings in the background. Idempotent. */
|
|
21
|
+
start() {
|
|
22
|
+
if (this.timer !== null)
|
|
23
|
+
return;
|
|
24
|
+
this.timer = setInterval(() => void this.advanceActive(), this.deps.pollMs ?? 2_000);
|
|
25
|
+
this.timer.unref?.();
|
|
26
|
+
}
|
|
27
|
+
stop() {
|
|
28
|
+
if (this.timer !== null)
|
|
29
|
+
clearInterval(this.timer);
|
|
30
|
+
this.timer = null;
|
|
31
|
+
}
|
|
32
|
+
/** Agents found on the LAN plus the addresses the operator typed. */
|
|
33
|
+
async listDiscovered(options = {}) {
|
|
34
|
+
const found = await this.scan(options.refresh === true);
|
|
35
|
+
const byKey = new Map();
|
|
36
|
+
for (const a of found) {
|
|
37
|
+
byKey.set(`${a.host}:${a.port}`, this.describe(a.nodeId, a.host, a.port, a, 'mdns'));
|
|
38
|
+
}
|
|
39
|
+
const at = this.now();
|
|
40
|
+
for (const [key, m] of this.manual) {
|
|
41
|
+
if (at - m.seenAt > ADDRESS_MEMORY_MS) {
|
|
42
|
+
this.manual.delete(key);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (byKey.has(key))
|
|
46
|
+
continue;
|
|
47
|
+
byKey.set(key, this.describe(m.nodeId, m.endpoint.host, m.endpoint.port, { version: m.version, state: m.state, fingerprint: null }, 'address'));
|
|
48
|
+
}
|
|
49
|
+
return { agents: [...byKey.values()], scannedAt: this.scanned?.at ?? null };
|
|
50
|
+
}
|
|
51
|
+
/** Probe an address the operator typed; remembered so it shows in the list. */
|
|
52
|
+
async addByAddress(host, port = DEFAULT_PORT) {
|
|
53
|
+
const endpoint = { host, port };
|
|
54
|
+
const hello = await this.deps.transport.hello(endpoint);
|
|
55
|
+
this.manual.set(`${host}:${port}`, {
|
|
56
|
+
endpoint,
|
|
57
|
+
nodeId: hello.nodeId,
|
|
58
|
+
version: hello.version,
|
|
59
|
+
state: hello.state,
|
|
60
|
+
seenAt: this.now(),
|
|
61
|
+
});
|
|
62
|
+
return this.describe(hello.nodeId, host, port, { version: hello.version, state: hello.state, fingerprint: null }, 'address');
|
|
63
|
+
}
|
|
64
|
+
async begin(endpoint) {
|
|
65
|
+
const view = await this.deps.pairing.begin(endpoint);
|
|
66
|
+
this.start();
|
|
67
|
+
return view;
|
|
68
|
+
}
|
|
69
|
+
get(pairingId) {
|
|
70
|
+
return this.deps.pairing.advance(pairingId);
|
|
71
|
+
}
|
|
72
|
+
list() {
|
|
73
|
+
return this.deps.pairing.list();
|
|
74
|
+
}
|
|
75
|
+
confirm(pairingId, code) {
|
|
76
|
+
return this.deps.pairing.confirm(pairingId, code);
|
|
77
|
+
}
|
|
78
|
+
reject(pairingId) {
|
|
79
|
+
return this.deps.pairing.reject(pairingId);
|
|
80
|
+
}
|
|
81
|
+
async advanceActive() {
|
|
82
|
+
for (const id of this.deps.pairing.activeIds()) {
|
|
83
|
+
await this.deps.pairing.advance(id).catch((err) => this.deps.log.warn('pairing could not be advanced', {
|
|
84
|
+
meta: { pairingId: id, error: err instanceof Error ? err.message : String(err) },
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async scan(refresh) {
|
|
89
|
+
const last = this.scanned;
|
|
90
|
+
if (!refresh && last !== null && this.now() - last.at < SCAN_REUSE_MS)
|
|
91
|
+
return last.agents;
|
|
92
|
+
if (this.scanning !== null)
|
|
93
|
+
return this.scanning;
|
|
94
|
+
const running = this.deps
|
|
95
|
+
.browse()
|
|
96
|
+
.then((agents) => {
|
|
97
|
+
this.scanned = { at: this.now(), agents };
|
|
98
|
+
return agents;
|
|
99
|
+
})
|
|
100
|
+
.finally(() => {
|
|
101
|
+
this.scanning = null;
|
|
102
|
+
});
|
|
103
|
+
this.scanning = running;
|
|
104
|
+
return running;
|
|
105
|
+
}
|
|
106
|
+
describe(nodeId, host, port, facts, source) {
|
|
107
|
+
const active = this.deps.pairing
|
|
108
|
+
.list()
|
|
109
|
+
.find((p) => p.nodeId === nodeId && (p.state === 'awaiting-confirmation' || p.state === 'completing'));
|
|
110
|
+
return {
|
|
111
|
+
nodeId,
|
|
112
|
+
host,
|
|
113
|
+
port,
|
|
114
|
+
version: facts.version,
|
|
115
|
+
state: facts.state,
|
|
116
|
+
fingerprint: facts.fingerprint,
|
|
117
|
+
source,
|
|
118
|
+
connected: this.deps.isNodeConnected(nodeId),
|
|
119
|
+
pairing: active ?? null,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.HubAgentPairing = HubAgentPairing;
|
|
@@ -32,6 +32,7 @@ function createNodeCertificatesClient(moleculer, nodeId) {
|
|
|
32
32
|
installMeshLeaf: (input) => call('installMeshLeaf', m.installMeshLeaf.output, input),
|
|
33
33
|
confirmMeshLeaf: (input) => call('confirmMeshLeaf', m.confirmMeshLeaf.output, input),
|
|
34
34
|
rollbackMeshLeaf: () => call('rollbackMeshLeaf', m.rollbackMeshLeaf.output, {}),
|
|
35
|
+
forgetHub: () => call('forgetHub', m.forgetHub.output, {}),
|
|
35
36
|
prepareHttpsCertificate: () => call('prepareHttpsCertificate', m.prepareHttpsCertificate.output, {}),
|
|
36
37
|
installHttpsCertificate: (input) => call('installHttpsCertificate', m.installHttpsCertificate.output, input),
|
|
37
38
|
};
|
|
@@ -34,6 +34,7 @@ class HubMeshGuard {
|
|
|
34
34
|
ownNodeId,
|
|
35
35
|
gate: system_1.getProcessClusterSecretGate,
|
|
36
36
|
mode: system_1.getProcessMeshAuthMode,
|
|
37
|
+
isVerifiedPeer: system_1.isProcessVerifiedMeshPeer,
|
|
37
38
|
onAuthenticated: (nodeId) => {
|
|
38
39
|
this.logger.info('node authenticated to the mesh (challenge–response)', {
|
|
39
40
|
meta: { nodeId },
|
|
@@ -711,6 +711,7 @@ class MoleculerService {
|
|
|
711
711
|
});
|
|
712
712
|
(0, system_1.setProcessMeshPeerTransportLookup)({
|
|
713
713
|
transportOf: (nodeId) => (0, system_1.getBrokerTlsTransporter)(this.broker)?.peerTransport(nodeId),
|
|
714
|
+
isVerifiedPeer: (nodeId) => (0, system_1.getBrokerTlsTransporter)(this.broker)?.verifiedPeer(nodeId) !== undefined,
|
|
714
715
|
peerLeaf: (nodeId) => (0, system_1.getBrokerTlsTransporter)(this.broker)?.peerLeaf(nodeId),
|
|
715
716
|
dropPeer: (nodeId) => (0, system_1.getBrokerTlsTransporter)(this.broker)?.dropPeer(nodeId) ?? 0,
|
|
716
717
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.574",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
6
|
"files": [
|
|
@@ -38,18 +38,18 @@
|
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@camstack/addon-admin-ui": "1.2.
|
|
42
|
-
"@camstack/addon-agent-ui": "1.2.
|
|
41
|
+
"@camstack/addon-admin-ui": "1.2.424",
|
|
42
|
+
"@camstack/addon-agent-ui": "1.2.233",
|
|
43
43
|
"@camstack/addon-auth": "1.2.144",
|
|
44
44
|
"@camstack/addon-decoder-nodeav": "1.2.123",
|
|
45
45
|
"@camstack/addon-notifiers": "1.2.134",
|
|
46
|
-
"@camstack/addon-pipeline": "1.2.
|
|
46
|
+
"@camstack/addon-pipeline": "1.2.369",
|
|
47
47
|
"@camstack/addon-pipeline-orchestrator": "1.2.321",
|
|
48
48
|
"@camstack/addon-post-analysis": "1.2.369",
|
|
49
|
-
"@camstack/develop": "0.1.
|
|
49
|
+
"@camstack/develop": "0.1.10",
|
|
50
50
|
"@camstack/sdk": "1.2.131",
|
|
51
|
-
"@camstack/system": "1.2.
|
|
52
|
-
"@camstack/types": "1.2.
|
|
51
|
+
"@camstack/system": "1.2.433",
|
|
52
|
+
"@camstack/types": "1.2.369",
|
|
53
53
|
"@camstack/ui-library": "1.2.289",
|
|
54
54
|
"@fastify/compress": "^9.0.0",
|
|
55
55
|
"@fastify/cookie": "^11.0.2",
|