@serve.zone/dcrouter 6.7.0 → 6.9.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_serve/bundle.js +2423 -2389
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +12 -0
- package/dist_ts/opsserver/handlers/certificate.handler.js +127 -1
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +25 -9
- package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +11 -2
- package/dist_ts/remoteingress/classes.remoteingress-manager.js +31 -7
- package/dist_ts_interfaces/data/remoteingress.d.ts +7 -1
- package/dist_ts_interfaces/requests/certificate.d.ts +50 -0
- package/dist_ts_interfaces/requests/remoteingress.d.ts +2 -0
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +31 -0
- package/dist_ts_web/appstate.js +73 -1
- package/dist_ts_web/elements/ops-view-certificates.d.ts +1 -0
- package/dist_ts_web/elements/ops-view-certificates.js +123 -1
- package/dist_ts_web/elements/ops-view-remoteingress.js +73 -8
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/opsserver/handlers/certificate.handler.ts +180 -0
- package/ts/opsserver/handlers/remoteingress.handler.ts +24 -7
- package/ts/remoteingress/classes.remoteingress-manager.ts +29 -5
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +110 -0
- package/ts_web/elements/ops-view-certificates.ts +125 -0
- package/ts_web/elements/ops-view-remoteingress.ts +74 -7
|
@@ -149,6 +149,17 @@ let OpsViewRemoteIngress = (() => {
|
|
|
149
149
|
background: ${cssManager.bdTheme('#eff6ff', '#172554')};
|
|
150
150
|
color: ${cssManager.bdTheme('#1e40af', '#60a5fa')};
|
|
151
151
|
}
|
|
152
|
+
|
|
153
|
+
.portBadge.manual {
|
|
154
|
+
background: ${cssManager.bdTheme('#eff6ff', '#172554')};
|
|
155
|
+
color: ${cssManager.bdTheme('#1e40af', '#60a5fa')};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.portBadge.derived {
|
|
159
|
+
background: ${cssManager.bdTheme('#ecfdf5', '#022c22')};
|
|
160
|
+
color: ${cssManager.bdTheme('#047857', '#34d399')};
|
|
161
|
+
border: 1px dashed ${cssManager.bdTheme('#6ee7b7', '#065f46')};
|
|
162
|
+
}
|
|
152
163
|
`,
|
|
153
164
|
];
|
|
154
165
|
render() {
|
|
@@ -235,7 +246,8 @@ let OpsViewRemoteIngress = (() => {
|
|
|
235
246
|
content: html `
|
|
236
247
|
<dees-form>
|
|
237
248
|
<dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
|
|
238
|
-
<dees-input-text .key=${'listenPorts'} .label=${'
|
|
249
|
+
<dees-input-text .key=${'listenPorts'} .label=${'Additional Manual Ports (comma-separated, optional)'}></dees-input-text>
|
|
250
|
+
<dees-input-checkbox .key=${'autoDerivePorts'} .label=${'Auto-derive ports from routes'} .value=${true}></dees-input-checkbox>
|
|
239
251
|
<dees-input-text .key=${'tags'} .label=${'Tags (comma-separated, optional)'}></dees-input-text>
|
|
240
252
|
</dees-form>
|
|
241
253
|
`,
|
|
@@ -260,10 +272,11 @@ let OpsViewRemoteIngress = (() => {
|
|
|
260
272
|
const listenPorts = portsStr
|
|
261
273
|
? portsStr.split(',').map((p) => parseInt(p.trim(), 10)).filter((p) => !isNaN(p))
|
|
262
274
|
: undefined;
|
|
275
|
+
const autoDerivePorts = formData.autoDerivePorts !== false;
|
|
263
276
|
const tags = formData.tags
|
|
264
277
|
? formData.tags.split(',').map((t) => t.trim()).filter(Boolean)
|
|
265
278
|
: undefined;
|
|
266
|
-
await appstate.remoteIngressStatePart.dispatchAction(appstate.createRemoteIngressAction, { name, listenPorts, tags });
|
|
279
|
+
await appstate.remoteIngressStatePart.dispatchAction(appstate.createRemoteIngressAction, { name, listenPorts, autoDerivePorts, tags });
|
|
267
280
|
await modalArg.destroy();
|
|
268
281
|
},
|
|
269
282
|
},
|
|
@@ -291,6 +304,59 @@ let OpsViewRemoteIngress = (() => {
|
|
|
291
304
|
await appstate.remoteIngressStatePart.dispatchAction(appstate.toggleRemoteIngressAction, { id: edge.id, enabled: false });
|
|
292
305
|
},
|
|
293
306
|
},
|
|
307
|
+
{
|
|
308
|
+
name: 'Edit',
|
|
309
|
+
iconName: 'lucide:pencil',
|
|
310
|
+
type: ['inRow', 'contextmenu'],
|
|
311
|
+
actionFunc: async (actionData) => {
|
|
312
|
+
const edge = actionData.item;
|
|
313
|
+
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
314
|
+
await DeesModal.createAndShow({
|
|
315
|
+
heading: `Edit Edge: ${edge.name}`,
|
|
316
|
+
content: html `
|
|
317
|
+
<dees-form>
|
|
318
|
+
<dees-input-text .key=${'name'} .label=${'Name'} .value=${edge.name}></dees-input-text>
|
|
319
|
+
<dees-input-text .key=${'listenPorts'} .label=${'Manual Ports (comma-separated)'} .value=${(edge.listenPorts || []).join(', ')}></dees-input-text>
|
|
320
|
+
<dees-input-checkbox .key=${'autoDerivePorts'} .label=${'Auto-derive ports from routes'} .value=${edge.autoDerivePorts !== false}></dees-input-checkbox>
|
|
321
|
+
<dees-input-text .key=${'tags'} .label=${'Tags (comma-separated)'} .value=${(edge.tags || []).join(', ')}></dees-input-text>
|
|
322
|
+
</dees-form>
|
|
323
|
+
`,
|
|
324
|
+
menuOptions: [
|
|
325
|
+
{
|
|
326
|
+
name: 'Cancel',
|
|
327
|
+
iconName: 'lucide:x',
|
|
328
|
+
action: async (modalArg) => await modalArg.destroy(),
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
name: 'Save',
|
|
332
|
+
iconName: 'lucide:check',
|
|
333
|
+
action: async (modalArg) => {
|
|
334
|
+
const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
|
|
335
|
+
if (!form)
|
|
336
|
+
return;
|
|
337
|
+
const formData = await form.collectFormData();
|
|
338
|
+
const portsStr = formData.listenPorts?.trim();
|
|
339
|
+
const listenPorts = portsStr
|
|
340
|
+
? portsStr.split(',').map((p) => parseInt(p.trim(), 10)).filter((p) => !isNaN(p))
|
|
341
|
+
: [];
|
|
342
|
+
const autoDerivePorts = formData.autoDerivePorts !== false;
|
|
343
|
+
const tags = formData.tags
|
|
344
|
+
? formData.tags.split(',').map((t) => t.trim()).filter(Boolean)
|
|
345
|
+
: [];
|
|
346
|
+
await appstate.remoteIngressStatePart.dispatchAction(appstate.updateRemoteIngressAction, {
|
|
347
|
+
id: edge.id,
|
|
348
|
+
name: formData.name || edge.name,
|
|
349
|
+
listenPorts,
|
|
350
|
+
autoDerivePorts,
|
|
351
|
+
tags,
|
|
352
|
+
});
|
|
353
|
+
await modalArg.destroy();
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
],
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
},
|
|
294
360
|
{
|
|
295
361
|
name: 'Regenerate Secret',
|
|
296
362
|
iconName: 'lucide:key',
|
|
@@ -332,13 +398,12 @@ let OpsViewRemoteIngress = (() => {
|
|
|
332
398
|
return status?.publicIp || '-';
|
|
333
399
|
}
|
|
334
400
|
getPortsHtml(edge) {
|
|
335
|
-
const
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
if (ports.length === 0) {
|
|
401
|
+
const manualPorts = edge.manualPorts || [];
|
|
402
|
+
const derivedPorts = edge.derivedPorts || [];
|
|
403
|
+
if (manualPorts.length === 0 && derivedPorts.length === 0) {
|
|
339
404
|
return html `<span style="color: var(--text-muted, #6b7280); font-size: 12px;">none</span>`;
|
|
340
405
|
}
|
|
341
|
-
return html `<div class="portsDisplay">${
|
|
406
|
+
return html `<div class="portsDisplay">${manualPorts.map(p => html `<span class="portBadge manual">${p}</span>`)}${derivedPorts.map(p => html `<span class="portBadge derived">${p}</span>`)}${derivedPorts.length > 0 ? html `<span style="font-size: 11px; color: var(--text-muted, #6b7280); align-self: center;">(auto)</span>` : ''}</div>`;
|
|
342
407
|
}
|
|
343
408
|
getEdgeTunnelCount(edgeId) {
|
|
344
409
|
const status = this.getEdgeStatus(edgeId);
|
|
@@ -362,4 +427,4 @@ let OpsViewRemoteIngress = (() => {
|
|
|
362
427
|
return OpsViewRemoteIngress = _classThis;
|
|
363
428
|
})();
|
|
364
429
|
export { OpsViewRemoteIngress };
|
|
365
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctcmVtb3RlaW5ncmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9lbGVtZW50cy9vcHMtdmlldy1yZW1vdGVpbmdyZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLElBQUksRUFDSixhQUFhLEVBRWIsR0FBRyxFQUNILEtBQUssRUFDTCxVQUFVLEdBQ1gsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEtBQUssUUFBUSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sS0FBSyxVQUFVLE1BQU0sbUNBQW1DLENBQUM7QUFDaEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sRUFBbUIsTUFBTSw2QkFBNkIsQ0FBQztJQVNqRCxvQkFBb0I7NEJBRGhDLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQzs7OztzQkFDRSxXQUFXOzs7O29DQUFuQixTQUFRLFdBQVc7Ozs7bUNBQ2xELEtBQUssRUFBRTtZQUNSLDBLQUFTLE9BQU8sNkJBQVAsT0FBTyx5RkFBNEU7WUFGOUYsNktBZ1VDOzs7O1FBOVRDLDJFQUFpRCxRQUFRLENBQUMsc0JBQXNCLENBQUMsUUFBUSxFQUFFLEVBQUM7UUFBNUYsSUFBUyxPQUFPLDZDQUE0RTtRQUE1RixJQUFTLE9BQU8sbURBQTRFO1FBRTVGO1lBQ0UsS0FBSyxFQUFFLENBQUM7O1lBQ1IsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDdkUsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7WUFDMUIsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNoQztRQUVELEtB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
|
|
430
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctcmVtb3RlaW5ncmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9lbGVtZW50cy9vcHMtdmlldy1yZW1vdGVpbmdyZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLElBQUksRUFDSixhQUFhLEVBRWIsR0FBRyxFQUNILEtBQUssRUFDTCxVQUFVLEdBQ1gsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEtBQUssUUFBUSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sS0FBSyxVQUFVLE1BQU0sbUNBQW1DLENBQUM7QUFDaEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sRUFBbUIsTUFBTSw2QkFBNkIsQ0FBQztJQVNqRCxvQkFBb0I7NEJBRGhDLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQzs7OztzQkFDRSxXQUFXOzs7O29DQUFuQixTQUFRLFdBQVc7Ozs7bUNBQ2xELEtBQUssRUFBRTtZQUNSLDBLQUFTLE9BQU8sNkJBQVAsT0FBTyx5RkFBNEU7WUFGOUYsNktBbVlDOzs7O1FBallDLDJFQUFpRCxRQUFRLENBQUMsc0JBQXNCLENBQUMsUUFBUSxFQUFFLEVBQUM7UUFBNUYsSUFBUyxPQUFPLDZDQUE0RTtRQUE1RixJQUFTLE9BQU8sbURBQTRFO1FBRTVGO1lBQ0UsS0FBSyxFQUFFLENBQUM7O1lBQ1IsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDdkUsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7WUFDMUIsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNoQztRQUVELEtB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
|
package/package.json
CHANGED
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -42,6 +42,36 @@ export class CertificateHandler {
|
|
|
42
42
|
}
|
|
43
43
|
)
|
|
44
44
|
);
|
|
45
|
+
|
|
46
|
+
// Delete certificate
|
|
47
|
+
this.typedrouter.addTypedHandler(
|
|
48
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteCertificate>(
|
|
49
|
+
'deleteCertificate',
|
|
50
|
+
async (dataArg) => {
|
|
51
|
+
return this.deleteCertificate(dataArg.domain);
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Export certificate
|
|
57
|
+
this.typedrouter.addTypedHandler(
|
|
58
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ExportCertificate>(
|
|
59
|
+
'exportCertificate',
|
|
60
|
+
async (dataArg) => {
|
|
61
|
+
return this.exportCertificate(dataArg.domain);
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Import certificate
|
|
67
|
+
this.typedrouter.addTypedHandler(
|
|
68
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ImportCertificate>(
|
|
69
|
+
'importCertificate',
|
|
70
|
+
async (dataArg) => {
|
|
71
|
+
return this.importCertificate(dataArg.cert);
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
);
|
|
45
75
|
}
|
|
46
76
|
|
|
47
77
|
/**
|
|
@@ -324,4 +354,154 @@ export class CertificateHandler {
|
|
|
324
354
|
|
|
325
355
|
return { success: false, message: `No routes found for domain '${domain}'` };
|
|
326
356
|
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Delete certificate data for a domain from storage
|
|
360
|
+
*/
|
|
361
|
+
private async deleteCertificate(domain: string): Promise<{ success: boolean; message?: string }> {
|
|
362
|
+
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
363
|
+
const cleanDomain = domain.replace(/^\*\.?/, '');
|
|
364
|
+
|
|
365
|
+
// Delete from all known storage paths
|
|
366
|
+
const paths = [
|
|
367
|
+
`/proxy-certs/${domain}`,
|
|
368
|
+
`/proxy-certs/${cleanDomain}`,
|
|
369
|
+
`/certs/${cleanDomain}`,
|
|
370
|
+
];
|
|
371
|
+
|
|
372
|
+
for (const path of paths) {
|
|
373
|
+
try {
|
|
374
|
+
await dcRouter.storageManager.delete(path);
|
|
375
|
+
} catch {
|
|
376
|
+
// Path may not exist — ignore
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Clear from in-memory status map
|
|
381
|
+
dcRouter.certificateStatusMap.delete(domain);
|
|
382
|
+
|
|
383
|
+
// Clear backoff info
|
|
384
|
+
if (dcRouter.certProvisionScheduler) {
|
|
385
|
+
await dcRouter.certProvisionScheduler.clearBackoff(domain);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return { success: true, message: `Certificate data deleted for '${domain}'` };
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Export certificate data for a domain as ICert-shaped JSON
|
|
393
|
+
*/
|
|
394
|
+
private async exportCertificate(domain: string): Promise<{
|
|
395
|
+
success: boolean;
|
|
396
|
+
cert?: {
|
|
397
|
+
id: string;
|
|
398
|
+
domainName: string;
|
|
399
|
+
created: number;
|
|
400
|
+
validUntil: number;
|
|
401
|
+
privateKey: string;
|
|
402
|
+
publicKey: string;
|
|
403
|
+
csr: string;
|
|
404
|
+
};
|
|
405
|
+
message?: string;
|
|
406
|
+
}> {
|
|
407
|
+
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
408
|
+
const cleanDomain = domain.replace(/^\*\.?/, '');
|
|
409
|
+
|
|
410
|
+
// Try SmartAcme /certs/ path first (has full ICert fields)
|
|
411
|
+
let certData = await dcRouter.storageManager.getJSON(`/certs/${cleanDomain}`);
|
|
412
|
+
if (certData && certData.publicKey && certData.privateKey) {
|
|
413
|
+
return {
|
|
414
|
+
success: true,
|
|
415
|
+
cert: {
|
|
416
|
+
id: certData.id || plugins.crypto.randomUUID(),
|
|
417
|
+
domainName: certData.domainName || domain,
|
|
418
|
+
created: certData.created || Date.now(),
|
|
419
|
+
validUntil: certData.validUntil || 0,
|
|
420
|
+
privateKey: certData.privateKey,
|
|
421
|
+
publicKey: certData.publicKey,
|
|
422
|
+
csr: certData.csr || '',
|
|
423
|
+
},
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Fallback: try /proxy-certs/ with original domain
|
|
428
|
+
certData = await dcRouter.storageManager.getJSON(`/proxy-certs/${domain}`);
|
|
429
|
+
if (!certData || !certData.publicKey) {
|
|
430
|
+
// Try with clean domain
|
|
431
|
+
certData = await dcRouter.storageManager.getJSON(`/proxy-certs/${cleanDomain}`);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (certData && certData.publicKey && certData.privateKey) {
|
|
435
|
+
return {
|
|
436
|
+
success: true,
|
|
437
|
+
cert: {
|
|
438
|
+
id: plugins.crypto.randomUUID(),
|
|
439
|
+
domainName: domain,
|
|
440
|
+
created: certData.validFrom || Date.now(),
|
|
441
|
+
validUntil: certData.validUntil || 0,
|
|
442
|
+
privateKey: certData.privateKey,
|
|
443
|
+
publicKey: certData.publicKey,
|
|
444
|
+
csr: '',
|
|
445
|
+
},
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return { success: false, message: `No certificate data found for '${domain}'` };
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Import a certificate from ICert-shaped JSON
|
|
454
|
+
*/
|
|
455
|
+
private async importCertificate(cert: {
|
|
456
|
+
id: string;
|
|
457
|
+
domainName: string;
|
|
458
|
+
created: number;
|
|
459
|
+
validUntil: number;
|
|
460
|
+
privateKey: string;
|
|
461
|
+
publicKey: string;
|
|
462
|
+
csr: string;
|
|
463
|
+
}): Promise<{ success: boolean; message?: string }> {
|
|
464
|
+
// Validate PEM content
|
|
465
|
+
if (!cert.publicKey || !cert.publicKey.includes('-----BEGIN CERTIFICATE-----')) {
|
|
466
|
+
return { success: false, message: 'Invalid publicKey: must contain a PEM-encoded certificate' };
|
|
467
|
+
}
|
|
468
|
+
if (!cert.privateKey || !cert.privateKey.includes('-----BEGIN')) {
|
|
469
|
+
return { success: false, message: 'Invalid privateKey: must contain a PEM-encoded key' };
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
473
|
+
const cleanDomain = cert.domainName.replace(/^\*\.?/, '');
|
|
474
|
+
|
|
475
|
+
// Save to /certs/ (SmartAcme-compatible path)
|
|
476
|
+
await dcRouter.storageManager.setJSON(`/certs/${cleanDomain}`, {
|
|
477
|
+
id: cert.id,
|
|
478
|
+
domainName: cert.domainName,
|
|
479
|
+
created: cert.created,
|
|
480
|
+
validUntil: cert.validUntil,
|
|
481
|
+
privateKey: cert.privateKey,
|
|
482
|
+
publicKey: cert.publicKey,
|
|
483
|
+
csr: cert.csr || '',
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// Also save to /proxy-certs/ (proxy-cert format)
|
|
487
|
+
await dcRouter.storageManager.setJSON(`/proxy-certs/${cert.domainName}`, {
|
|
488
|
+
domain: cert.domainName,
|
|
489
|
+
publicKey: cert.publicKey,
|
|
490
|
+
privateKey: cert.privateKey,
|
|
491
|
+
ca: undefined,
|
|
492
|
+
validUntil: cert.validUntil,
|
|
493
|
+
validFrom: cert.created,
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
// Update in-memory status map
|
|
497
|
+
dcRouter.certificateStatusMap.set(cert.domainName, {
|
|
498
|
+
status: 'valid',
|
|
499
|
+
source: 'static',
|
|
500
|
+
expiryDate: cert.validUntil ? new Date(cert.validUntil).toISOString() : undefined,
|
|
501
|
+
issuedAt: cert.created ? new Date(cert.created).toISOString() : undefined,
|
|
502
|
+
routeNames: [],
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
return { success: true, message: `Certificate imported for '${cert.domainName}'` };
|
|
506
|
+
}
|
|
327
507
|
}
|
|
@@ -20,12 +20,17 @@ export class RemoteIngressHandler {
|
|
|
20
20
|
if (!manager) {
|
|
21
21
|
return { edges: [] };
|
|
22
22
|
}
|
|
23
|
-
// Return edges without secrets, enriched with effective listen ports
|
|
24
|
-
const edges = manager.getAllEdges().map((e) =>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
// Return edges without secrets, enriched with effective listen ports and breakdown
|
|
24
|
+
const edges = manager.getAllEdges().map((e) => {
|
|
25
|
+
const breakdown = manager.getPortBreakdown(e);
|
|
26
|
+
return {
|
|
27
|
+
...e,
|
|
28
|
+
secret: '********', // Never expose secrets via API
|
|
29
|
+
effectiveListenPorts: manager.getEffectiveListenPorts(e),
|
|
30
|
+
manualPorts: breakdown.manual,
|
|
31
|
+
derivedPorts: breakdown.derived,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
29
34
|
return { edges };
|
|
30
35
|
},
|
|
31
36
|
),
|
|
@@ -50,6 +55,7 @@ export class RemoteIngressHandler {
|
|
|
50
55
|
dataArg.name,
|
|
51
56
|
dataArg.listenPorts || [],
|
|
52
57
|
dataArg.tags,
|
|
58
|
+
dataArg.autoDerivePorts ?? true,
|
|
53
59
|
);
|
|
54
60
|
|
|
55
61
|
// Sync allowed edges with the hub
|
|
@@ -102,6 +108,7 @@ export class RemoteIngressHandler {
|
|
|
102
108
|
const edge = await manager.updateEdge(dataArg.id, {
|
|
103
109
|
name: dataArg.name,
|
|
104
110
|
listenPorts: dataArg.listenPorts,
|
|
111
|
+
autoDerivePorts: dataArg.autoDerivePorts,
|
|
105
112
|
enabled: dataArg.enabled,
|
|
106
113
|
tags: dataArg.tags,
|
|
107
114
|
});
|
|
@@ -115,7 +122,17 @@ export class RemoteIngressHandler {
|
|
|
115
122
|
await tunnelManager.syncAllowedEdges();
|
|
116
123
|
}
|
|
117
124
|
|
|
118
|
-
|
|
125
|
+
const breakdown = manager.getPortBreakdown(edge);
|
|
126
|
+
return {
|
|
127
|
+
success: true,
|
|
128
|
+
edge: {
|
|
129
|
+
...edge,
|
|
130
|
+
secret: '********',
|
|
131
|
+
effectiveListenPorts: manager.getEffectiveListenPorts(edge),
|
|
132
|
+
manualPorts: breakdown.manual,
|
|
133
|
+
derivedPorts: breakdown.derived,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
119
136
|
},
|
|
120
137
|
),
|
|
121
138
|
);
|
|
@@ -47,6 +47,11 @@ export class RemoteIngressManager {
|
|
|
47
47
|
for (const key of keys) {
|
|
48
48
|
const edge = await this.storageManager.getJSON<IRemoteIngress>(key);
|
|
49
49
|
if (edge) {
|
|
50
|
+
// Migration: old edges without autoDerivePorts default to true
|
|
51
|
+
if ((edge as any).autoDerivePorts === undefined) {
|
|
52
|
+
edge.autoDerivePorts = true;
|
|
53
|
+
await this.storageManager.setJSON(key, edge);
|
|
54
|
+
}
|
|
50
55
|
this.edges.set(edge.id, edge);
|
|
51
56
|
}
|
|
52
57
|
}
|
|
@@ -91,13 +96,28 @@ export class RemoteIngressManager {
|
|
|
91
96
|
|
|
92
97
|
/**
|
|
93
98
|
* Get the effective listen ports for an edge.
|
|
94
|
-
*
|
|
99
|
+
* Manual ports are always included. Auto-derived ports are added (union) when autoDerivePorts is true.
|
|
95
100
|
*/
|
|
96
101
|
public getEffectiveListenPorts(edge: IRemoteIngress): number[] {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
const manualPorts = edge.listenPorts || [];
|
|
103
|
+
const shouldDerive = edge.autoDerivePorts !== false;
|
|
104
|
+
if (!shouldDerive) return [...manualPorts].sort((a, b) => a - b);
|
|
105
|
+
const derivedPorts = this.derivePortsForEdge(edge.id, edge.tags);
|
|
106
|
+
return [...new Set([...manualPorts, ...derivedPorts])].sort((a, b) => a - b);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get manual and derived port breakdown for an edge (used in API responses).
|
|
111
|
+
* Derived ports exclude any ports already present in the manual list.
|
|
112
|
+
*/
|
|
113
|
+
public getPortBreakdown(edge: IRemoteIngress): { manual: number[]; derived: number[] } {
|
|
114
|
+
const manual = edge.listenPorts || [];
|
|
115
|
+
const shouldDerive = edge.autoDerivePorts !== false;
|
|
116
|
+
if (!shouldDerive) return { manual, derived: [] };
|
|
117
|
+
const manualSet = new Set(manual);
|
|
118
|
+
const allDerived = this.derivePortsForEdge(edge.id, edge.tags);
|
|
119
|
+
const derived = allDerived.filter((p) => !manualSet.has(p));
|
|
120
|
+
return { manual, derived };
|
|
101
121
|
}
|
|
102
122
|
|
|
103
123
|
/**
|
|
@@ -107,6 +127,7 @@ export class RemoteIngressManager {
|
|
|
107
127
|
name: string,
|
|
108
128
|
listenPorts: number[] = [],
|
|
109
129
|
tags?: string[],
|
|
130
|
+
autoDerivePorts: boolean = true,
|
|
110
131
|
): Promise<IRemoteIngress> {
|
|
111
132
|
const id = plugins.uuid.v4();
|
|
112
133
|
const secret = plugins.crypto.randomBytes(32).toString('hex');
|
|
@@ -118,6 +139,7 @@ export class RemoteIngressManager {
|
|
|
118
139
|
secret,
|
|
119
140
|
listenPorts,
|
|
120
141
|
enabled: true,
|
|
142
|
+
autoDerivePorts,
|
|
121
143
|
tags: tags || [],
|
|
122
144
|
createdAt: now,
|
|
123
145
|
updatedAt: now,
|
|
@@ -150,6 +172,7 @@ export class RemoteIngressManager {
|
|
|
150
172
|
updates: {
|
|
151
173
|
name?: string;
|
|
152
174
|
listenPorts?: number[];
|
|
175
|
+
autoDerivePorts?: boolean;
|
|
153
176
|
enabled?: boolean;
|
|
154
177
|
tags?: string[];
|
|
155
178
|
},
|
|
@@ -161,6 +184,7 @@ export class RemoteIngressManager {
|
|
|
161
184
|
|
|
162
185
|
if (updates.name !== undefined) edge.name = updates.name;
|
|
163
186
|
if (updates.listenPorts !== undefined) edge.listenPorts = updates.listenPorts;
|
|
187
|
+
if (updates.autoDerivePorts !== undefined) edge.autoDerivePorts = updates.autoDerivePorts;
|
|
164
188
|
if (updates.enabled !== undefined) edge.enabled = updates.enabled;
|
|
165
189
|
if (updates.tags !== undefined) edge.tags = updates.tags;
|
|
166
190
|
edge.updatedAt = Date.now();
|
package/ts_web/appstate.ts
CHANGED
|
@@ -780,6 +780,80 @@ export const reprovisionCertificateAction = certificateStatePart.createAction<st
|
|
|
780
780
|
}
|
|
781
781
|
);
|
|
782
782
|
|
|
783
|
+
export const deleteCertificateAction = certificateStatePart.createAction<string>(
|
|
784
|
+
async (statePartArg, domain) => {
|
|
785
|
+
const context = getActionContext();
|
|
786
|
+
const currentState = statePartArg.getState();
|
|
787
|
+
|
|
788
|
+
try {
|
|
789
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
790
|
+
interfaces.requests.IReq_DeleteCertificate
|
|
791
|
+
>('/typedrequest', 'deleteCertificate');
|
|
792
|
+
|
|
793
|
+
await request.fire({
|
|
794
|
+
identity: context.identity,
|
|
795
|
+
domain,
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
// Re-fetch overview after deletion
|
|
799
|
+
await certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null);
|
|
800
|
+
return statePartArg.getState();
|
|
801
|
+
} catch (error) {
|
|
802
|
+
return {
|
|
803
|
+
...currentState,
|
|
804
|
+
error: error instanceof Error ? error.message : 'Failed to delete certificate',
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
);
|
|
809
|
+
|
|
810
|
+
export const importCertificateAction = certificateStatePart.createAction<{
|
|
811
|
+
id: string;
|
|
812
|
+
domainName: string;
|
|
813
|
+
created: number;
|
|
814
|
+
validUntil: number;
|
|
815
|
+
privateKey: string;
|
|
816
|
+
publicKey: string;
|
|
817
|
+
csr: string;
|
|
818
|
+
}>(
|
|
819
|
+
async (statePartArg, cert) => {
|
|
820
|
+
const context = getActionContext();
|
|
821
|
+
const currentState = statePartArg.getState();
|
|
822
|
+
|
|
823
|
+
try {
|
|
824
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
825
|
+
interfaces.requests.IReq_ImportCertificate
|
|
826
|
+
>('/typedrequest', 'importCertificate');
|
|
827
|
+
|
|
828
|
+
await request.fire({
|
|
829
|
+
identity: context.identity,
|
|
830
|
+
cert,
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
// Re-fetch overview after import
|
|
834
|
+
await certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null);
|
|
835
|
+
return statePartArg.getState();
|
|
836
|
+
} catch (error) {
|
|
837
|
+
return {
|
|
838
|
+
...currentState,
|
|
839
|
+
error: error instanceof Error ? error.message : 'Failed to import certificate',
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
);
|
|
844
|
+
|
|
845
|
+
export async function fetchCertificateExport(domain: string) {
|
|
846
|
+
const context = getActionContext();
|
|
847
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
848
|
+
interfaces.requests.IReq_ExportCertificate
|
|
849
|
+
>('/typedrequest', 'exportCertificate');
|
|
850
|
+
|
|
851
|
+
return request.fire({
|
|
852
|
+
identity: context.identity,
|
|
853
|
+
domain,
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
|
|
783
857
|
// ============================================================================
|
|
784
858
|
// Remote Ingress Actions
|
|
785
859
|
// ============================================================================
|
|
@@ -822,6 +896,7 @@ export const fetchRemoteIngressAction = remoteIngressStatePart.createAction(asyn
|
|
|
822
896
|
export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
823
897
|
name: string;
|
|
824
898
|
listenPorts?: number[];
|
|
899
|
+
autoDerivePorts?: boolean;
|
|
825
900
|
tags?: string[];
|
|
826
901
|
}>(async (statePartArg, dataArg) => {
|
|
827
902
|
const context = getActionContext();
|
|
@@ -836,6 +911,7 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
836
911
|
identity: context.identity,
|
|
837
912
|
name: dataArg.name,
|
|
838
913
|
listenPorts: dataArg.listenPorts,
|
|
914
|
+
autoDerivePorts: dataArg.autoDerivePorts,
|
|
839
915
|
tags: dataArg.tags,
|
|
840
916
|
});
|
|
841
917
|
|
|
@@ -883,6 +959,40 @@ export const deleteRemoteIngressAction = remoteIngressStatePart.createAction<str
|
|
|
883
959
|
}
|
|
884
960
|
);
|
|
885
961
|
|
|
962
|
+
export const updateRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
963
|
+
id: string;
|
|
964
|
+
name?: string;
|
|
965
|
+
listenPorts?: number[];
|
|
966
|
+
autoDerivePorts?: boolean;
|
|
967
|
+
tags?: string[];
|
|
968
|
+
}>(async (statePartArg, dataArg) => {
|
|
969
|
+
const context = getActionContext();
|
|
970
|
+
const currentState = statePartArg.getState();
|
|
971
|
+
|
|
972
|
+
try {
|
|
973
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
974
|
+
interfaces.requests.IReq_UpdateRemoteIngress
|
|
975
|
+
>('/typedrequest', 'updateRemoteIngress');
|
|
976
|
+
|
|
977
|
+
await request.fire({
|
|
978
|
+
identity: context.identity,
|
|
979
|
+
id: dataArg.id,
|
|
980
|
+
name: dataArg.name,
|
|
981
|
+
listenPorts: dataArg.listenPorts,
|
|
982
|
+
autoDerivePorts: dataArg.autoDerivePorts,
|
|
983
|
+
tags: dataArg.tags,
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
await remoteIngressStatePart.dispatchAction(fetchRemoteIngressAction, null);
|
|
987
|
+
return statePartArg.getState();
|
|
988
|
+
} catch (error) {
|
|
989
|
+
return {
|
|
990
|
+
...currentState,
|
|
991
|
+
error: error instanceof Error ? error.message : 'Failed to update edge',
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
});
|
|
995
|
+
|
|
886
996
|
export const regenerateRemoteIngressSecretAction = remoteIngressStatePart.createAction<string>(
|
|
887
997
|
async (statePartArg, edgeId) => {
|
|
888
998
|
const context = getActionContext();
|