fix(routes): support profile and target metadata in route creation and refresh remote ingress routes after config initialization
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-04-02 - 12.2.4 - fix(routes)
|
||||
support profile and target metadata in route creation and refresh remote ingress routes after config initialization
|
||||
|
||||
- Re-applies routes to the remote ingress manager after config managers finish to avoid missing DB-backed routes during initialization
|
||||
- Fetches profiles and targets when opening or authenticating into the routes view so route creation dropdowns are populated
|
||||
- Includes selected security profile and network target metadata when creating programmatic routes and displays that metadata in route details
|
||||
- Improves security profile forms by switching IP allow/block lists to list inputs instead of comma-separated text fields
|
||||
- Updates UI dependencies including smartdb, dees-catalog, and serve.zone catalog
|
||||
|
||||
## 2026-04-02 - 12.2.3 - fix(repo)
|
||||
no changes to commit
|
||||
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
"@api.global/typedserver": "^8.4.6",
|
||||
"@api.global/typedsocket": "^4.1.2",
|
||||
"@apiclient.xyz/cloudflare": "^7.1.0",
|
||||
"@design.estate/dees-catalog": "^3.49.1",
|
||||
"@design.estate/dees-catalog": "^3.49.2",
|
||||
"@design.estate/dees-element": "^2.2.4",
|
||||
"@push.rocks/lik": "^6.4.0",
|
||||
"@push.rocks/projectinfo": "^5.1.0",
|
||||
"@push.rocks/qenv": "^6.1.3",
|
||||
"@push.rocks/smartacme": "^9.3.1",
|
||||
"@push.rocks/smartdata": "^7.1.3",
|
||||
"@push.rocks/smartdb": "^2.0.0",
|
||||
"@push.rocks/smartdb": "^2.1.1",
|
||||
"@push.rocks/smartdns": "^7.9.0",
|
||||
"@push.rocks/smartfs": "^1.5.0",
|
||||
"@push.rocks/smartguard": "^3.1.0",
|
||||
@@ -61,7 +61,7 @@
|
||||
"@push.rocks/smartunique": "^3.0.9",
|
||||
"@push.rocks/smartvpn": "1.19.1",
|
||||
"@push.rocks/taskbuffer": "^8.0.2",
|
||||
"@serve.zone/catalog": "^2.9.0",
|
||||
"@serve.zone/catalog": "^2.9.1",
|
||||
"@serve.zone/interfaces": "^5.3.0",
|
||||
"@serve.zone/remoteingress": "^4.15.3",
|
||||
"@tsclass/tsclass": "^9.5.0",
|
||||
|
||||
48
pnpm-lock.yaml
generated
48
pnpm-lock.yaml
generated
@@ -24,8 +24,8 @@ importers:
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0
|
||||
'@design.estate/dees-catalog':
|
||||
specifier: ^3.49.1
|
||||
version: 3.49.1(@tiptap/pm@2.27.2)
|
||||
specifier: ^3.49.2
|
||||
version: 3.49.2(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-element':
|
||||
specifier: ^2.2.4
|
||||
version: 2.2.4
|
||||
@@ -45,8 +45,8 @@ importers:
|
||||
specifier: ^7.1.3
|
||||
version: 7.1.3(socks@2.8.7)
|
||||
'@push.rocks/smartdb':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1(@tiptap/pm@2.27.2)
|
||||
'@push.rocks/smartdns':
|
||||
specifier: ^7.9.0
|
||||
version: 7.9.0
|
||||
@@ -102,8 +102,8 @@ importers:
|
||||
specifier: ^8.0.2
|
||||
version: 8.0.2
|
||||
'@serve.zone/catalog':
|
||||
specifier: ^2.9.0
|
||||
version: 2.9.0(@tiptap/pm@2.27.2)
|
||||
specifier: ^2.9.1
|
||||
version: 2.9.1(@tiptap/pm@2.27.2)
|
||||
'@serve.zone/interfaces':
|
||||
specifier: ^5.3.0
|
||||
version: 5.3.0
|
||||
@@ -350,8 +350,8 @@ packages:
|
||||
'@configvault.io/interfaces@1.0.17':
|
||||
resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==}
|
||||
|
||||
'@design.estate/dees-catalog@3.49.1':
|
||||
resolution: {integrity: sha512-YyaRu6uep5wiqx2wnQeeWXstNRkkEfTAH7uA9XiWwM+TwbWH83esu5PR8L+J4akz3VsSW26JlfRI+7GoWTs2mw==}
|
||||
'@design.estate/dees-catalog@3.49.2':
|
||||
resolution: {integrity: sha512-ChVf5IW/w1WSsfuI3BA1SX2QJFjZljnAvnyPDXnbzTXuOdTgs054p66JwlDca9KM8yBlndwibgAYJfD6/4sONw==}
|
||||
|
||||
'@design.estate/dees-comms@1.0.30':
|
||||
resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==}
|
||||
@@ -1141,8 +1141,8 @@ packages:
|
||||
'@push.rocks/smartdata@7.1.3':
|
||||
resolution: {integrity: sha512-7vQJ9pdRk450yn2m9tmGPdSRlQVmxFPZjHD4sGYsfqCQPg+GLFusu+H16zpf+jKzAq4F2ZBMPaYymJHXvXiVcw==}
|
||||
|
||||
'@push.rocks/smartdb@2.0.0':
|
||||
resolution: {integrity: sha512-RGaXGOS+5c7Hru2XwoyavQuoZqrfIzUfF/AnnVA0GYOrj4P2S89fngp8QDczVyZq/IbkByYXz59foQmN/WDlWA==}
|
||||
'@push.rocks/smartdb@2.1.1':
|
||||
resolution: {integrity: sha512-bm+xYpuzSgS+EacNP3NppwNvpw9OZN3gmtVUgBdqyLLKYX0329bDN5X63V6vdrglFBV/+MKox43l8BQBwVdfjw==}
|
||||
|
||||
'@push.rocks/smartdelay@3.0.5':
|
||||
resolution: {integrity: sha512-mUuI7kj2f7ztjpic96FvRIlf2RsKBa5arw81AHNsndbxO6asRcxuWL8dTVxouEIK8YsBUlj0AsrCkHhMbLQdHw==}
|
||||
@@ -1583,8 +1583,8 @@ packages:
|
||||
'@selderee/plugin-htmlparser2@0.11.0':
|
||||
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
|
||||
|
||||
'@serve.zone/catalog@2.9.0':
|
||||
resolution: {integrity: sha512-7FgwS44pD/DFVj29jS0Kwwyn1i5h8cf4/yWMBEY8+8GO70ab3QctbcKMu+BVa1G3gIrpLqhpmxLFDoeL/zDnQA==}
|
||||
'@serve.zone/catalog@2.9.1':
|
||||
resolution: {integrity: sha512-W+4x5O834DiEtcqfVNFrP6qYlj/6c9UTR9oEl2Wthf0R2SN0zC6Hbs16US2kP+mmQBKAIDMQYvTUI9oaXqvcog==}
|
||||
|
||||
'@serve.zone/interfaces@5.3.0':
|
||||
resolution: {integrity: sha512-venO7wtDR9ixzD9NhdERBGjNKbFA5LL0yHw4eqGh0UpmvtXVc3SFG0uuHDilOKMZqZ8bttV88qVsFy1aSTJrtA==}
|
||||
@@ -4260,11 +4260,13 @@ packages:
|
||||
|
||||
xterm-addon-fit@0.8.0:
|
||||
resolution: {integrity: sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==}
|
||||
deprecated: This package is now deprecated. Move to @xterm/addon-fit instead.
|
||||
peerDependencies:
|
||||
xterm: ^5.0.0
|
||||
|
||||
xterm@5.3.0:
|
||||
resolution: {integrity: sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg==}
|
||||
deprecated: This package is now deprecated. Move to @xterm/xterm instead.
|
||||
|
||||
y18n@4.0.3:
|
||||
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||
@@ -4339,7 +4341,7 @@ snapshots:
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
'@api.global/typedsocket': 4.1.2(@push.rocks/smartserve@2.0.3)
|
||||
'@cloudflare/workers-types': 4.20260317.1
|
||||
'@design.estate/dees-catalog': 3.49.1(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-catalog': 3.49.2(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-comms': 1.0.30
|
||||
'@push.rocks/lik': 6.4.0
|
||||
'@push.rocks/smartdelay': 3.0.5
|
||||
@@ -4868,7 +4870,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@api.global/typedrequest-interfaces': 3.0.19
|
||||
|
||||
'@design.estate/dees-catalog@3.49.1(@tiptap/pm@2.27.2)':
|
||||
'@design.estate/dees-catalog@3.49.2(@tiptap/pm@2.27.2)':
|
||||
dependencies:
|
||||
'@design.estate/dees-domtools': 2.5.4
|
||||
'@design.estate/dees-element': 2.2.4
|
||||
@@ -6127,9 +6129,19 @@ snapshots:
|
||||
- supports-color
|
||||
- vue
|
||||
|
||||
'@push.rocks/smartdb@2.0.0':
|
||||
'@push.rocks/smartdb@2.1.1(@tiptap/pm@2.27.2)':
|
||||
dependencies:
|
||||
'@api.global/typedserver': 8.4.6(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-element': 2.2.4
|
||||
'@push.rocks/smartrust': 1.3.2
|
||||
transitivePeerDependencies:
|
||||
- '@nuxt/kit'
|
||||
- '@tiptap/pm'
|
||||
- bufferutil
|
||||
- react
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
- vue
|
||||
|
||||
'@push.rocks/smartdelay@3.0.5':
|
||||
dependencies:
|
||||
@@ -6894,10 +6906,10 @@ snapshots:
|
||||
domhandler: 5.0.3
|
||||
selderee: 0.11.0
|
||||
|
||||
'@serve.zone/catalog@2.9.0(@tiptap/pm@2.27.2)':
|
||||
'@serve.zone/catalog@2.9.1(@tiptap/pm@2.27.2)':
|
||||
dependencies:
|
||||
'@design.estate/dees-catalog': 3.49.1(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-domtools': 2.5.3
|
||||
'@design.estate/dees-catalog': 3.49.2(@tiptap/pm@2.27.2)
|
||||
'@design.estate/dees-domtools': 2.5.4
|
||||
'@design.estate/dees-element': 2.2.4
|
||||
'@design.estate/dees-wcctools': 3.8.0
|
||||
transitivePeerDependencies:
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/dcrouter',
|
||||
version: '12.2.3',
|
||||
version: '12.2.4',
|
||||
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
||||
}
|
||||
|
||||
@@ -2060,6 +2060,13 @@ export class DcRouter {
|
||||
const currentRoutes = this.constructorRoutes;
|
||||
this.remoteIngressManager.setRoutes(currentRoutes as any[]);
|
||||
|
||||
// Race-condition fix: if ConfigManagers finished before us, re-apply routes
|
||||
// so the callback delivers the full merged set (including DB-stored routes)
|
||||
// to our newly-created remoteIngressManager.
|
||||
if (this.routeConfigManager) {
|
||||
await this.routeConfigManager.applyRoutes();
|
||||
}
|
||||
|
||||
// Resolve TLS certs for tunnel: explicit paths > ACME for hubDomain > self-signed (Rust default)
|
||||
const riCfg = this.options.remoteIngressConfig;
|
||||
let tlsConfig: { certPem: string; keyPem: string } | undefined;
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/dcrouter',
|
||||
version: '12.2.3',
|
||||
version: '12.2.4',
|
||||
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
||||
}
|
||||
|
||||
@@ -427,6 +427,8 @@ export const setActiveViewAction = uiStatePart.createAction<string>(async (state
|
||||
if (viewName === 'routes' && currentState.activeView !== 'routes') {
|
||||
setTimeout(() => {
|
||||
routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null);
|
||||
// Also fetch profiles/targets for the Create Route dropdowns
|
||||
profilesTargetsStatePart.dispatchAction(fetchProfilesAndTargetsAction, null);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
@@ -1413,6 +1415,7 @@ export const fetchMergedRoutesAction = routeManagementStatePart.createAction(asy
|
||||
export const createRouteAction = routeManagementStatePart.createAction<{
|
||||
route: any;
|
||||
enabled?: boolean;
|
||||
metadata?: any;
|
||||
}>(async (statePartArg, dataArg, actionContext): Promise<IRouteManagementState> => {
|
||||
const context = getActionContext();
|
||||
const currentState = statePartArg.getState()!;
|
||||
@@ -1426,6 +1429,7 @@ export const createRouteAction = routeManagementStatePart.createAction<{
|
||||
identity: context.identity!,
|
||||
route: dataArg.route,
|
||||
enabled: dataArg.enabled,
|
||||
metadata: dataArg.metadata,
|
||||
});
|
||||
|
||||
return await actionContext!.dispatch(fetchMergedRoutesAction, null);
|
||||
|
||||
@@ -24,6 +24,14 @@ export class OpsViewRoutes extends DeesElement {
|
||||
lastUpdated: 0,
|
||||
};
|
||||
|
||||
@state() accessor profilesTargetsState: appstate.IProfilesTargetsState = {
|
||||
profiles: [],
|
||||
targets: [],
|
||||
isLoading: false,
|
||||
error: null,
|
||||
lastUpdated: 0,
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const sub = appstate.routeManagementStatePart
|
||||
@@ -33,6 +41,13 @@ export class OpsViewRoutes extends DeesElement {
|
||||
});
|
||||
this.rxSubscriptions.push(sub);
|
||||
|
||||
const ptSub = appstate.profilesTargetsStatePart
|
||||
.select((s) => s)
|
||||
.subscribe((ptState) => {
|
||||
this.profilesTargetsState = ptState;
|
||||
});
|
||||
this.rxSubscriptions.push(ptSub);
|
||||
|
||||
// Re-fetch routes when user logs in (fixes race condition where
|
||||
// the view is created before authentication completes)
|
||||
const loginSub = appstate.loginStatePart
|
||||
@@ -40,6 +55,7 @@ export class OpsViewRoutes extends DeesElement {
|
||||
.subscribe((isLoggedIn) => {
|
||||
if (isLoggedIn) {
|
||||
appstate.routeManagementStatePart.dispatchAction(appstate.fetchMergedRoutesAction, null);
|
||||
appstate.profilesTargetsStatePart.dispatchAction(appstate.fetchProfilesAndTargetsAction, null);
|
||||
}
|
||||
});
|
||||
this.rxSubscriptions.push(loginSub);
|
||||
@@ -145,6 +161,7 @@ export class OpsViewRoutes extends DeesElement {
|
||||
enabled: mr.enabled,
|
||||
tags,
|
||||
id: mr.storedRouteId || mr.route.name || undefined,
|
||||
metadata: mr.metadata,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -275,6 +292,7 @@ export class OpsViewRoutes extends DeesElement {
|
||||
});
|
||||
} else {
|
||||
// Programmatic route
|
||||
const meta = merged.metadata;
|
||||
await DeesModal.createAndShow({
|
||||
heading: `Route: ${merged.route.name}`,
|
||||
content: html`
|
||||
@@ -282,6 +300,8 @@ export class OpsViewRoutes extends DeesElement {
|
||||
<p>Source: <strong style="color: #0af;">programmatic</strong></p>
|
||||
<p>Status: <strong>${merged.enabled ? 'Enabled' : 'Disabled'}</strong></p>
|
||||
<p>ID: <code style="color: #888;">${merged.storedRouteId}</code></p>
|
||||
${meta?.securityProfileName ? html`<p>Security Profile: <strong style="color: #a78bfa;">${meta.securityProfileName}</strong></p>` : ''}
|
||||
${meta?.networkTargetName ? html`<p>Network Target: <strong style="color: #a78bfa;">${meta.networkTargetName}</strong></p>` : ''}
|
||||
</div>
|
||||
`,
|
||||
menuOptions: [
|
||||
@@ -319,6 +339,24 @@ export class OpsViewRoutes extends DeesElement {
|
||||
|
||||
private async showCreateRouteDialog() {
|
||||
const { DeesModal } = await import('@design.estate/dees-catalog');
|
||||
const profiles = this.profilesTargetsState.profiles;
|
||||
const targets = this.profilesTargetsState.targets;
|
||||
|
||||
// Build dropdown options for profiles and targets
|
||||
const profileOptions = [
|
||||
{ key: '', option: '(none — inline security)' },
|
||||
...profiles.map((p) => ({
|
||||
key: p.id,
|
||||
option: `${p.name}${p.description ? ' — ' + p.description : ''}`,
|
||||
})),
|
||||
];
|
||||
const targetOptions = [
|
||||
{ key: '', option: '(none — inline target)' },
|
||||
...targets.map((t) => ({
|
||||
key: t.id,
|
||||
option: `${t.name} (${Array.isArray(t.host) ? t.host.join(',') : t.host}:${t.port})`,
|
||||
})),
|
||||
];
|
||||
|
||||
await DeesModal.createAndShow({
|
||||
heading: 'Add Programmatic Route',
|
||||
@@ -327,8 +365,10 @@ export class OpsViewRoutes extends DeesElement {
|
||||
<dees-input-text .key=${'name'} .label=${'Route Name'} .required=${true}></dees-input-text>
|
||||
<dees-input-text .key=${'ports'} .label=${'Ports (comma-separated)'} .required=${true}></dees-input-text>
|
||||
<dees-input-text .key=${'domains'} .label=${'Domains (comma-separated, optional)'}></dees-input-text>
|
||||
<dees-input-text .key=${'targetHost'} .label=${'Target Host'} .value=${'localhost'} .required=${true}></dees-input-text>
|
||||
<dees-input-text .key=${'targetPort'} .label=${'Target Port'} .required=${true}></dees-input-text>
|
||||
<dees-input-dropdown .key=${'securityProfileRef'} .label=${'Security Profile'} .options=${profileOptions} .selectedKey=${''}></dees-input-dropdown>
|
||||
<dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions} .selectedKey=${''}></dees-input-dropdown>
|
||||
<dees-input-text .key=${'targetHost'} .label=${'Target Host (if no target selected)'} .value=${'localhost'}></dees-input-text>
|
||||
<dees-input-text .key=${'targetPort'} .label=${'Target Port (if no target selected)'}></dees-input-text>
|
||||
</dees-form>
|
||||
`,
|
||||
menuOptions: [
|
||||
@@ -362,15 +402,27 @@ export class OpsViewRoutes extends DeesElement {
|
||||
targets: [
|
||||
{
|
||||
host: formData.targetHost || 'localhost',
|
||||
port: parseInt(formData.targetPort, 10),
|
||||
port: parseInt(formData.targetPort, 10) || 443,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
// Build metadata if profile/target selected
|
||||
const metadata: any = {};
|
||||
if (formData.securityProfileRef) {
|
||||
metadata.securityProfileRef = formData.securityProfileRef;
|
||||
}
|
||||
if (formData.networkTargetRef) {
|
||||
metadata.networkTargetRef = formData.networkTargetRef;
|
||||
}
|
||||
|
||||
await appstate.routeManagementStatePart.dispatchAction(
|
||||
appstate.createRouteAction,
|
||||
{ route },
|
||||
{
|
||||
route,
|
||||
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
||||
},
|
||||
);
|
||||
await modalArg.destroy();
|
||||
},
|
||||
|
||||
@@ -131,8 +131,8 @@ export class OpsViewSecurityProfiles extends DeesElement {
|
||||
<dees-form>
|
||||
<dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
|
||||
<dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
|
||||
<dees-input-text .key=${'ipAllowList'} .label=${'IP Allow List (comma-separated)'}></dees-input-text>
|
||||
<dees-input-text .key=${'ipBlockList'} .label=${'IP Block List (comma-separated)'}></dees-input-text>
|
||||
<dees-input-list .key=${'ipAllowList'} .label=${'IP Allow List'} .placeholder=${'Add IP or CIDR...'}></dees-input-list>
|
||||
<dees-input-list .key=${'ipBlockList'} .label=${'IP Block List'} .placeholder=${'Add IP or CIDR...'}></dees-input-list>
|
||||
<dees-input-text .key=${'maxConnections'} .label=${'Max Connections'}></dees-input-text>
|
||||
</dees-form>
|
||||
`,
|
||||
@@ -142,20 +142,16 @@ export class OpsViewSecurityProfiles extends DeesElement {
|
||||
action: async (modalArg: any) => {
|
||||
const form = modalArg.shadowRoot!.querySelector('dees-form');
|
||||
const data = await form.collectFormData();
|
||||
const ipAllowList = data.ipAllowList
|
||||
? String(data.ipAllowList).split(',').map((s: string) => s.trim()).filter(Boolean)
|
||||
: undefined;
|
||||
const ipBlockList = data.ipBlockList
|
||||
? String(data.ipBlockList).split(',').map((s: string) => s.trim()).filter(Boolean)
|
||||
: undefined;
|
||||
const ipAllowList: string[] = Array.isArray(data.ipAllowList) ? data.ipAllowList : [];
|
||||
const ipBlockList: string[] = Array.isArray(data.ipBlockList) ? data.ipBlockList : [];
|
||||
const maxConnections = data.maxConnections ? parseInt(String(data.maxConnections)) : undefined;
|
||||
|
||||
await appstate.profilesTargetsStatePart.dispatchAction(appstate.createProfileAction, {
|
||||
name: String(data.name),
|
||||
description: data.description ? String(data.description) : undefined,
|
||||
security: {
|
||||
...(ipAllowList ? { ipAllowList } : {}),
|
||||
...(ipBlockList ? { ipBlockList } : {}),
|
||||
...(ipAllowList.length > 0 ? { ipAllowList } : {}),
|
||||
...(ipBlockList.length > 0 ? { ipBlockList } : {}),
|
||||
...(maxConnections ? { maxConnections } : {}),
|
||||
},
|
||||
});
|
||||
@@ -175,8 +171,8 @@ export class OpsViewSecurityProfiles extends DeesElement {
|
||||
<dees-form>
|
||||
<dees-input-text .key=${'name'} .label=${'Name'} .value=${profile.name}></dees-input-text>
|
||||
<dees-input-text .key=${'description'} .label=${'Description'} .value=${profile.description || ''}></dees-input-text>
|
||||
<dees-input-text .key=${'ipAllowList'} .label=${'IP Allow List (comma-separated)'} .value=${(profile.security?.ipAllowList || []).join(', ')}></dees-input-text>
|
||||
<dees-input-text .key=${'ipBlockList'} .label=${'IP Block List (comma-separated)'} .value=${(profile.security?.ipBlockList || []).join(', ')}></dees-input-text>
|
||||
<dees-input-list .key=${'ipAllowList'} .label=${'IP Allow List'} .placeholder=${'Add IP or CIDR...'} .value=${profile.security?.ipAllowList || []}></dees-input-list>
|
||||
<dees-input-list .key=${'ipBlockList'} .label=${'IP Block List'} .placeholder=${'Add IP or CIDR...'} .value=${profile.security?.ipBlockList || []}></dees-input-list>
|
||||
<dees-input-text .key=${'maxConnections'} .label=${'Max Connections'} .value=${String(profile.security?.maxConnections || '')}></dees-input-text>
|
||||
</dees-form>
|
||||
`,
|
||||
@@ -186,12 +182,8 @@ export class OpsViewSecurityProfiles extends DeesElement {
|
||||
action: async (modalArg: any) => {
|
||||
const form = modalArg.shadowRoot!.querySelector('dees-form');
|
||||
const data = await form.collectFormData();
|
||||
const ipAllowList = data.ipAllowList
|
||||
? String(data.ipAllowList).split(',').map((s: string) => s.trim()).filter(Boolean)
|
||||
: [];
|
||||
const ipBlockList = data.ipBlockList
|
||||
? String(data.ipBlockList).split(',').map((s: string) => s.trim()).filter(Boolean)
|
||||
: [];
|
||||
const ipAllowList: string[] = Array.isArray(data.ipAllowList) ? data.ipAllowList : [];
|
||||
const ipBlockList: string[] = Array.isArray(data.ipBlockList) ? data.ipBlockList : [];
|
||||
const maxConnections = data.maxConnections ? parseInt(String(data.maxConnections)) : undefined;
|
||||
|
||||
await appstate.profilesTargetsStatePart.dispatchAction(appstate.updateProfileAction, {
|
||||
|
||||
Reference in New Issue
Block a user