@lensmcp/cluster 1.16.14 → 1.16.15
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/server.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAkB,qBAAqB,EAAsB,MAAM,SAAS,CAAC;AAkDxH,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/server.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAkB,qBAAqB,EAAsB,MAAM,SAAS,CAAC;AAkDxH,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA0OxB"}
|
|
@@ -140,6 +140,10 @@ async function startGateway(options, context) {
|
|
|
140
140
|
// REGISTERS its fragment here instead of fighting for :443, and the daemon HOSTS its services (spawns
|
|
141
141
|
// them, model A) + its dashboard (planning/multi-workspace-gateway.md P3). Harmless for a lone gateway.
|
|
142
142
|
const dashboardReapers = new Map();
|
|
143
|
+
// Assigned after the TLS servers are built (below) — re-mints the gateway cert with the CURRENT route
|
|
144
|
+
// hosts and hot-swaps it, so a workspace that registers AFTER boot gets its hostnames into the cert SANs
|
|
145
|
+
// (otherwise the browser sees ERR_CERT_COMMON_NAME_INVALID for the new workspace's hosts).
|
|
146
|
+
let refreshCert = () => { };
|
|
143
147
|
let controlServer;
|
|
144
148
|
try {
|
|
145
149
|
controlServer = (0, control_1.startControlServer)({
|
|
@@ -151,10 +155,12 @@ async function startGateway(options, context) {
|
|
|
151
155
|
const reap = lens.hostWorkspaceDashboard(fragment);
|
|
152
156
|
if (reap)
|
|
153
157
|
dashboardReapers.set(fragment.wsKey, reap);
|
|
158
|
+
refreshCert(); // the new workspace's hosts must join the gateway cert SANs
|
|
154
159
|
},
|
|
155
160
|
onUnregister: (fragment) => {
|
|
156
161
|
dashboardReapers.get(fragment.wsKey)?.();
|
|
157
162
|
dashboardReapers.delete(fragment.wsKey);
|
|
163
|
+
refreshCert();
|
|
158
164
|
},
|
|
159
165
|
});
|
|
160
166
|
}
|
|
@@ -214,12 +220,15 @@ async function startGateway(options, context) {
|
|
|
214
220
|
// --- TLS + listeners --------------------------------------------------------
|
|
215
221
|
let pem;
|
|
216
222
|
let caPath;
|
|
223
|
+
let mintCert;
|
|
217
224
|
if (https) {
|
|
218
225
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
219
226
|
const basicSsl = require('../../../basic-ssl');
|
|
220
227
|
const cacheDir = (0, service_keys_1.gatewayCacheDir)(context.root);
|
|
221
|
-
|
|
222
|
-
|
|
228
|
+
// SANs = the CURRENT route hosts. `rt.routes` is rebuilt live on register, so a re-mint (refreshCert
|
|
229
|
+
// below) automatically includes a newly-registered workspace's hostnames.
|
|
230
|
+
mintCert = () => basicSsl.getCertificateSync(cacheDir, 'gateway', rt.routes.map((r) => r.host).filter((h) => !!h));
|
|
231
|
+
pem = mintCert();
|
|
223
232
|
caPath = basicSsl.caCertPath(cacheDir);
|
|
224
233
|
}
|
|
225
234
|
const servers = [];
|
|
@@ -253,6 +262,18 @@ async function startGateway(options, context) {
|
|
|
253
262
|
});
|
|
254
263
|
servers.push(server);
|
|
255
264
|
}
|
|
265
|
+
// Now that the TLS servers exist, wire the live cert refresh: on a workspace register/unregister the
|
|
266
|
+
// control endpoint calls this to re-mint the gateway cert with the CURRENT route hosts and hot-swap it
|
|
267
|
+
// into every HTTP/2 secure server (setSecureContext), so a dynamically-registered workspace's hostnames
|
|
268
|
+
// are covered (no ERR_CERT_COMMON_NAME_INVALID).
|
|
269
|
+
if (mintCert) {
|
|
270
|
+
refreshCert = () => {
|
|
271
|
+
const fresh = mintCert();
|
|
272
|
+
for (const s of servers) {
|
|
273
|
+
s.setSecureContext?.({ key: fresh, cert: fresh });
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}
|
|
256
277
|
console.log('[gateway] Routes:');
|
|
257
278
|
for (const r of routes) {
|
|
258
279
|
const dest = r.pool ? `pods@${r.pool.dir}` : r.target;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/cluster",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.15",
|
|
4
4
|
"description": "Run your Nx workspace as a local production cluster: pods on unix sockets with true HMR, one https gateway with per-project domains, scale-from-zero, autoscale, idle-kill, local-CA TLS — observed by the LensMCP lens.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@lensmcp/node-instrumentation": "1.16.
|
|
69
|
-
"@lensmcp/nx-plugin": "1.16.
|
|
68
|
+
"@lensmcp/node-instrumentation": "1.16.15",
|
|
69
|
+
"@lensmcp/nx-plugin": "1.16.15",
|
|
70
70
|
"fork-ts-checker-webpack-plugin": "^9.0.0",
|
|
71
71
|
"glob": "^11.0.0",
|
|
72
72
|
"http-proxy": "^1.18.0",
|