@serve.zone/dcrouter 12.9.4 → 12.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_serve/bundle.js +553 -537
- package/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/config/classes.route-config-manager.js +13 -2
- package/dist_ts_web/00_commitinfo_data.js +2 -2
- package/dist_ts_web/elements/ops-view-routes.js +113 -3
- package/package.json +3 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/config/classes.route-config-manager.ts +12 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/ops-view-routes.ts +111 -2
|
@@ -13,6 +13,40 @@ import {
|
|
|
13
13
|
type TemplateResult,
|
|
14
14
|
} from '@design.estate/dees-element';
|
|
15
15
|
|
|
16
|
+
// TLS dropdown options shared by create and edit dialogs
|
|
17
|
+
const tlsModeOptions = [
|
|
18
|
+
{ key: 'none', option: '(none — no TLS)' },
|
|
19
|
+
{ key: 'passthrough', option: 'Passthrough' },
|
|
20
|
+
{ key: 'terminate', option: 'Terminate' },
|
|
21
|
+
{ key: 'terminate-and-reencrypt', option: 'Terminate & Re-encrypt' },
|
|
22
|
+
];
|
|
23
|
+
const tlsCertOptions = [
|
|
24
|
+
{ key: 'auto', option: 'Auto (ACME/Let\'s Encrypt)' },
|
|
25
|
+
{ key: 'custom', option: 'Custom certificate' },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Toggle TLS form field visibility based on selected TLS mode and certificate type.
|
|
30
|
+
*/
|
|
31
|
+
function setupTlsVisibility(formEl: any) {
|
|
32
|
+
const updateVisibility = async () => {
|
|
33
|
+
const data = await formEl.collectFormData();
|
|
34
|
+
const contentEl = formEl.closest('.content') || formEl.parentElement;
|
|
35
|
+
if (!contentEl) return;
|
|
36
|
+
const tlsModeValue = data.tlsMode;
|
|
37
|
+
const modeKey = typeof tlsModeValue === 'string' ? tlsModeValue : tlsModeValue?.key;
|
|
38
|
+
const needsCert = modeKey === 'terminate' || modeKey === 'terminate-and-reencrypt';
|
|
39
|
+
const certGroup = contentEl.querySelector('.tlsCertificateGroup') as HTMLElement;
|
|
40
|
+
if (certGroup) certGroup.style.display = needsCert ? 'flex' : 'none';
|
|
41
|
+
const tlsCertValue = data.tlsCertificate;
|
|
42
|
+
const certKey = typeof tlsCertValue === 'string' ? tlsCertValue : tlsCertValue?.key;
|
|
43
|
+
const customGroup = contentEl.querySelector('.tlsCustomCertGroup') as HTMLElement;
|
|
44
|
+
if (customGroup) customGroup.style.display = (needsCert && certKey === 'custom') ? 'flex' : 'none';
|
|
45
|
+
};
|
|
46
|
+
formEl.changeSubject.subscribe(() => updateVisibility());
|
|
47
|
+
updateVisibility();
|
|
48
|
+
}
|
|
49
|
+
|
|
16
50
|
@customElement('ops-view-routes')
|
|
17
51
|
export class OpsViewRoutes extends DeesElement {
|
|
18
52
|
@state() accessor routeState: appstate.IRouteManagementState = {
|
|
@@ -423,7 +457,18 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
423
457
|
: '';
|
|
424
458
|
const currentTargetPort = firstTarget?.port != null ? String(firstTarget.port) : '';
|
|
425
459
|
|
|
426
|
-
|
|
460
|
+
// Compute current TLS state for pre-population
|
|
461
|
+
const currentTls = (route.action as any).tls;
|
|
462
|
+
const currentTlsMode = currentTls?.mode || 'none';
|
|
463
|
+
const currentTlsCert = currentTls
|
|
464
|
+
? (currentTls.certificate === 'auto' || !currentTls.certificate ? 'auto' : 'custom')
|
|
465
|
+
: 'auto';
|
|
466
|
+
const currentCustomKey = (typeof currentTls?.certificate === 'object') ? currentTls.certificate.key : '';
|
|
467
|
+
const currentCustomCert = (typeof currentTls?.certificate === 'object') ? currentTls.certificate.cert : '';
|
|
468
|
+
const needsCert = currentTlsMode === 'terminate' || currentTlsMode === 'terminate-and-reencrypt';
|
|
469
|
+
const isCustom = currentTlsCert === 'custom';
|
|
470
|
+
|
|
471
|
+
const editModal = await DeesModal.createAndShow({
|
|
427
472
|
heading: `Edit Route: ${route.name}`,
|
|
428
473
|
content: html`
|
|
429
474
|
<dees-form>
|
|
@@ -435,6 +480,14 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
435
480
|
<dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions} .selectedOption=${targetOptions.find((o) => o.key === (merged.metadata?.networkTargetRef || '')) || null}></dees-input-dropdown>
|
|
436
481
|
<dees-input-text .key=${'targetHost'} .label=${'Target Host (if no target selected)'} .value=${currentTargetHost}></dees-input-text>
|
|
437
482
|
<dees-input-text .key=${'targetPort'} .label=${'Target Port (if no target selected)'} .value=${currentTargetPort}></dees-input-text>
|
|
483
|
+
<dees-input-dropdown .key=${'tlsMode'} .label=${'TLS Mode'} .options=${tlsModeOptions} .selectedOption=${tlsModeOptions.find((o) => o.key === currentTlsMode) || tlsModeOptions[0]}></dees-input-dropdown>
|
|
484
|
+
<div class="tlsCertificateGroup" style="display: ${needsCert ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
|
|
485
|
+
<dees-input-dropdown .key=${'tlsCertificate'} .label=${'Certificate'} .options=${tlsCertOptions} .selectedOption=${tlsCertOptions.find((o) => o.key === currentTlsCert) || tlsCertOptions[0]}></dees-input-dropdown>
|
|
486
|
+
<div class="tlsCustomCertGroup" style="display: ${needsCert && isCustom ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
|
|
487
|
+
<dees-input-text .key=${'tlsCertKey'} .label=${'Private Key (PEM)'} .value=${currentCustomKey}></dees-input-text>
|
|
488
|
+
<dees-input-text .key=${'tlsCertCert'} .label=${'Certificate (PEM)'} .value=${currentCustomCert}></dees-input-text>
|
|
489
|
+
</div>
|
|
490
|
+
</div>
|
|
438
491
|
</dees-form>
|
|
439
492
|
`,
|
|
440
493
|
menuOptions: [
|
|
@@ -476,6 +529,25 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
476
529
|
...(priority != null && !isNaN(priority) ? { priority } : {}),
|
|
477
530
|
};
|
|
478
531
|
|
|
532
|
+
// Build TLS config from form
|
|
533
|
+
const tlsModeValue = formData.tlsMode as any;
|
|
534
|
+
const tlsModeKey = typeof tlsModeValue === 'string' ? tlsModeValue : tlsModeValue?.key;
|
|
535
|
+
if (tlsModeKey && tlsModeKey !== 'none') {
|
|
536
|
+
const tls: any = { mode: tlsModeKey };
|
|
537
|
+
if (tlsModeKey !== 'passthrough') {
|
|
538
|
+
const tlsCertValue = formData.tlsCertificate as any;
|
|
539
|
+
const tlsCertKey = typeof tlsCertValue === 'string' ? tlsCertValue : tlsCertValue?.key;
|
|
540
|
+
if (tlsCertKey === 'custom' && formData.tlsCertKey && formData.tlsCertCert) {
|
|
541
|
+
tls.certificate = { key: formData.tlsCertKey, cert: formData.tlsCertCert };
|
|
542
|
+
} else {
|
|
543
|
+
tls.certificate = 'auto';
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
updatedRoute.action.tls = tls;
|
|
547
|
+
} else {
|
|
548
|
+
updatedRoute.action.tls = null; // explicit removal
|
|
549
|
+
}
|
|
550
|
+
|
|
479
551
|
const metadata: any = {};
|
|
480
552
|
const profileRefValue = formData.securityProfileRef as any;
|
|
481
553
|
const profileKey = typeof profileRefValue === 'string' ? profileRefValue : profileRefValue?.key;
|
|
@@ -501,6 +573,12 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
501
573
|
},
|
|
502
574
|
],
|
|
503
575
|
});
|
|
576
|
+
// Setup conditional TLS field visibility after modal renders
|
|
577
|
+
const editForm = editModal?.shadowRoot?.querySelector('.content')?.querySelector('dees-form') as any;
|
|
578
|
+
if (editForm) {
|
|
579
|
+
await editForm.updateComplete;
|
|
580
|
+
setupTlsVisibility(editForm);
|
|
581
|
+
}
|
|
504
582
|
}
|
|
505
583
|
|
|
506
584
|
private async showCreateRouteDialog() {
|
|
@@ -524,7 +602,7 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
524
602
|
})),
|
|
525
603
|
];
|
|
526
604
|
|
|
527
|
-
await DeesModal.createAndShow({
|
|
605
|
+
const createModal = await DeesModal.createAndShow({
|
|
528
606
|
heading: 'Add Programmatic Route',
|
|
529
607
|
content: html`
|
|
530
608
|
<dees-form>
|
|
@@ -536,6 +614,14 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
536
614
|
<dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions}></dees-input-dropdown>
|
|
537
615
|
<dees-input-text .key=${'targetHost'} .label=${'Target Host (if no target selected)'} .value=${'localhost'}></dees-input-text>
|
|
538
616
|
<dees-input-text .key=${'targetPort'} .label=${'Target Port (if no target selected)'}></dees-input-text>
|
|
617
|
+
<dees-input-dropdown .key=${'tlsMode'} .label=${'TLS Mode'} .options=${tlsModeOptions} .selectedOption=${tlsModeOptions[0]}></dees-input-dropdown>
|
|
618
|
+
<div class="tlsCertificateGroup" style="display: none; flex-direction: column; gap: 16px;">
|
|
619
|
+
<dees-input-dropdown .key=${'tlsCertificate'} .label=${'Certificate'} .options=${tlsCertOptions} .selectedOption=${tlsCertOptions[0]}></dees-input-dropdown>
|
|
620
|
+
<div class="tlsCustomCertGroup" style="display: none; flex-direction: column; gap: 16px;">
|
|
621
|
+
<dees-input-text .key=${'tlsCertKey'} .label=${'Private Key (PEM)'}></dees-input-text>
|
|
622
|
+
<dees-input-text .key=${'tlsCertCert'} .label=${'Certificate (PEM)'}></dees-input-text>
|
|
623
|
+
</div>
|
|
624
|
+
</div>
|
|
539
625
|
</dees-form>
|
|
540
626
|
`,
|
|
541
627
|
menuOptions: [
|
|
@@ -577,6 +663,23 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
577
663
|
...(priority != null && !isNaN(priority) ? { priority } : {}),
|
|
578
664
|
};
|
|
579
665
|
|
|
666
|
+
// Build TLS config from form
|
|
667
|
+
const tlsModeValue = formData.tlsMode as any;
|
|
668
|
+
const tlsModeKey = typeof tlsModeValue === 'string' ? tlsModeValue : tlsModeValue?.key;
|
|
669
|
+
if (tlsModeKey && tlsModeKey !== 'none') {
|
|
670
|
+
const tls: any = { mode: tlsModeKey };
|
|
671
|
+
if (tlsModeKey !== 'passthrough') {
|
|
672
|
+
const tlsCertValue = formData.tlsCertificate as any;
|
|
673
|
+
const tlsCertKey = typeof tlsCertValue === 'string' ? tlsCertValue : tlsCertValue?.key;
|
|
674
|
+
if (tlsCertKey === 'custom' && formData.tlsCertKey && formData.tlsCertCert) {
|
|
675
|
+
tls.certificate = { key: formData.tlsCertKey, cert: formData.tlsCertCert };
|
|
676
|
+
} else {
|
|
677
|
+
tls.certificate = 'auto';
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
route.action.tls = tls;
|
|
681
|
+
}
|
|
682
|
+
|
|
580
683
|
// Build metadata if profile/target selected
|
|
581
684
|
const metadata: any = {};
|
|
582
685
|
const profileRefValue = formData.securityProfileRef as any;
|
|
@@ -602,6 +705,12 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
602
705
|
},
|
|
603
706
|
],
|
|
604
707
|
});
|
|
708
|
+
// Setup conditional TLS field visibility after modal renders
|
|
709
|
+
const createForm = createModal?.shadowRoot?.querySelector('.content')?.querySelector('dees-form') as any;
|
|
710
|
+
if (createForm) {
|
|
711
|
+
await createForm.updateComplete;
|
|
712
|
+
setupTlsVisibility(createForm);
|
|
713
|
+
}
|
|
605
714
|
}
|
|
606
715
|
|
|
607
716
|
private refreshData() {
|