import { html } from '@design.estate/dees-element';
import * as appstate from '../../appstate.js';
import * as interfaces from '../../../dist_ts_interfaces/index.js';
export const letsEncryptHttp01ManagedRouteKind = 'letsencrypt-http01-forward' as const;
export function getSpecialForwardDomains(
route: interfaces.data.IMergedRoute,
): string[] {
const domains = route.route.match.domains;
if (!domains) return [];
return Array.isArray(domains) ? domains : [domains];
}
export function getSpecialForwardTarget(
route: interfaces.data.IMergedRoute,
): { host: string; port: number } | undefined {
const target = route.route.action.targets?.[0];
if (!target || typeof target.port !== 'number') return undefined;
const host = typeof target.host === 'string'
? target.host
: Array.isArray(target.host)
? target.host[0]
: undefined;
return host ? { host, port: target.port } : undefined;
}
function getDropdownKey(value: unknown): string {
return typeof value === 'string'
? value
: value && typeof value === 'object' && 'key' in value
? String((value as { key: unknown }).key)
: '';
}
export async function showLetsEncryptHttp01ForwardDialog(options: {
existing?: interfaces.data.IMergedRoute;
targets: interfaces.data.INetworkTarget[];
}): Promise {
const { DeesModal } = await import('@design.estate/dees-catalog');
const { existing, targets } = options;
const target = existing ? getSpecialForwardTarget(existing) : undefined;
const targetOptions = [
{ key: '', option: '(none — inline target)' },
...targets.map((networkTarget) => ({
key: networkTarget.id,
option: `${networkTarget.name} (${
Array.isArray(networkTarget.host) ? networkTarget.host.join(', ') : networkTarget.host
}:${networkTarget.port})`,
})),
];
const selectedTarget = targetOptions.find((option) => {
return option.key === (existing?.metadata?.networkTargetRef || '');
}) || targetOptions[0];
await DeesModal.createAndShow({
heading: existing
? `Edit User HTTP-01 Forward: ${existing.route.name || existing.id}`
: 'Add User Let\'s Encrypt HTTP-01 Forward',
content: html`
`,
menuOptions: [
{
name: 'Cancel',
iconName: 'lucide:x',
action: async (modalArg: any) => modalArg.destroy(),
},
{
name: existing ? 'Save' : 'Create',
iconName: existing ? 'lucide:check' : 'lucide:plus',
action: async (modalArg: any) => {
const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
if (!form) return;
const data = await form.collectFormData();
const name = String(data.name || '').trim();
const domains = Array.isArray(data.domains)
? data.domains.map((domain: unknown) => String(domain).trim()).filter(Boolean)
: [];
const networkTargetRef = getDropdownKey(data.networkTargetRef).trim();
const targetHost = String(data.targetHost || '').trim();
const targetPort = Number.parseInt(String(data.targetPort || ''), 10);
if (!name || domains.length === 0) {
alert('Name and at least one domain are required.');
return;
}
if (
!networkTargetRef
&& (!targetHost || !Number.isInteger(targetPort) || targetPort < 1 || targetPort > 65535)
) {
alert('A valid inline target host and port are required.');
return;
}
const edgeFilter = Array.isArray(data.remoteIngressEdgeFilter)
? data.remoteIngressEdgeFilter.map((entry: unknown) => String(entry).trim()).filter(Boolean)
: [];
const config: interfaces.data.ILetsEncryptHttp01ForwardConfig = {
name,
domains,
...(networkTargetRef
? { networkTargetRef }
: { target: { host: targetHost, port: targetPort } }),
...(data.remoteIngressEnabled
? {
remoteIngress: {
enabled: true,
...(edgeFilter.length ? { edgeFilter } : {}),
},
}
: {}),
};
if (existing) {
await appstate.routeManagementStatePart.dispatchAction(
appstate.updateLetsEncryptHttp01ForwardAction,
{ id: existing.id, config, enabled: existing.enabled },
);
} else {
await appstate.routeManagementStatePart.dispatchAction(
appstate.createLetsEncryptHttp01ForwardAction,
{ config },
);
}
await modalArg.destroy();
},
},
],
});
}