@serve.zone/dcrouter 13.1.3 → 13.3.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 +1202 -1133
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +1 -0
- package/dist_ts_web/appstate.js +9 -22
- package/dist_ts_web/elements/index.d.ts +2 -6
- package/dist_ts_web/elements/index.js +3 -7
- package/dist_ts_web/elements/network/index.d.ts +6 -0
- package/dist_ts_web/elements/network/index.js +7 -0
- package/dist_ts_web/elements/{ops-view-network.d.ts → network/ops-view-network-activity.d.ts} +3 -3
- package/dist_ts_web/elements/{ops-view-network.js → network/ops-view-network-activity.js} +20 -30
- package/dist_ts_web/elements/network/ops-view-network.d.ts +24 -0
- package/dist_ts_web/elements/network/ops-view-network.js +151 -0
- package/dist_ts_web/elements/{ops-view-networktargets.d.ts → network/ops-view-networktargets.d.ts} +1 -1
- package/dist_ts_web/elements/{ops-view-networktargets.js → network/ops-view-networktargets.js} +6 -6
- package/dist_ts_web/elements/{ops-view-routes.d.ts → network/ops-view-routes.d.ts} +1 -1
- package/dist_ts_web/elements/{ops-view-routes.js → network/ops-view-routes.js} +5 -6
- package/dist_ts_web/elements/{ops-view-sourceprofiles.d.ts → network/ops-view-sourceprofiles.d.ts} +1 -1
- package/dist_ts_web/elements/{ops-view-sourceprofiles.js → network/ops-view-sourceprofiles.js} +6 -6
- package/dist_ts_web/elements/{ops-view-targetprofiles.d.ts → network/ops-view-targetprofiles.d.ts} +2 -2
- package/dist_ts_web/elements/{ops-view-targetprofiles.js → network/ops-view-targetprofiles.js} +7 -7
- package/dist_ts_web/elements/ops-dashboard.js +4 -27
- package/dist_ts_web/elements/ops-view-apitokens.js +2 -1
- package/dist_ts_web/elements/ops-view-certificates.js +2 -1
- package/dist_ts_web/elements/ops-view-config.js +3 -3
- package/dist_ts_web/elements/ops-view-remoteingress.js +2 -1
- package/dist_ts_web/elements/ops-view-vpn.js +2 -1
- package/dist_ts_web/elements/security/index.d.ts +5 -0
- package/dist_ts_web/elements/security/index.js +6 -0
- package/dist_ts_web/elements/security/ops-view-security-authentication.d.ts +13 -0
- package/dist_ts_web/elements/security/ops-view-security-authentication.js +156 -0
- package/dist_ts_web/elements/security/ops-view-security-blocked.d.ts +15 -0
- package/dist_ts_web/elements/security/ops-view-security-blocked.js +152 -0
- package/dist_ts_web/elements/security/ops-view-security-emailsecurity.d.ts +14 -0
- package/dist_ts_web/elements/security/ops-view-security-emailsecurity.js +196 -0
- package/dist_ts_web/elements/security/ops-view-security-overview.d.ts +16 -0
- package/dist_ts_web/elements/security/ops-view-security-overview.js +204 -0
- package/dist_ts_web/elements/security/ops-view-security.d.ts +23 -0
- package/dist_ts_web/elements/security/ops-view-security.js +146 -0
- package/dist_ts_web/router.d.ts +5 -3
- package/dist_ts_web/router.js +69 -17
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +10 -24
- package/ts_web/elements/index.ts +2 -6
- package/ts_web/elements/network/index.ts +6 -0
- package/ts_web/elements/{ops-view-network.ts → network/ops-view-network-activity.ts} +43 -53
- package/ts_web/elements/network/ops-view-network.ts +119 -0
- package/ts_web/elements/{ops-view-networktargets.ts → network/ops-view-networktargets.ts} +5 -5
- package/ts_web/elements/{ops-view-routes.ts → network/ops-view-routes.ts} +4 -5
- package/ts_web/elements/{ops-view-sourceprofiles.ts → network/ops-view-sourceprofiles.ts} +5 -5
- package/ts_web/elements/{ops-view-targetprofiles.ts → network/ops-view-targetprofiles.ts} +6 -6
- package/ts_web/elements/ops-dashboard.ts +3 -26
- package/ts_web/elements/ops-view-apitokens.ts +1 -0
- package/ts_web/elements/ops-view-certificates.ts +1 -0
- package/ts_web/elements/ops-view-config.ts +2 -2
- package/ts_web/elements/ops-view-remoteingress.ts +1 -0
- package/ts_web/elements/ops-view-vpn.ts +1 -0
- package/ts_web/elements/security/index.ts +5 -0
- package/ts_web/elements/security/ops-view-security-authentication.ts +120 -0
- package/ts_web/elements/security/ops-view-security-blocked.ts +117 -0
- package/ts_web/elements/security/ops-view-security-emailsecurity.ts +159 -0
- package/ts_web/elements/security/ops-view-security-overview.ts +171 -0
- package/ts_web/elements/security/ops-view-security.ts +114 -0
- package/ts_web/router.ts +75 -17
- package/dist_ts_web/elements/ops-view-security.d.ts +0 -24
- package/dist_ts_web/elements/ops-view-security.js +0 -481
- package/ts_web/elements/ops-view-security.ts +0 -453
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import * as appstate from '../../appstate.js';
|
|
2
|
+
import { appRouter } from '../../router.js';
|
|
3
|
+
import { viewHostCss } from '../shared/css.js';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
DeesElement,
|
|
7
|
+
customElement,
|
|
8
|
+
html,
|
|
9
|
+
state,
|
|
10
|
+
css,
|
|
11
|
+
cssManager,
|
|
12
|
+
type TemplateResult,
|
|
13
|
+
} from '@design.estate/dees-element';
|
|
14
|
+
|
|
15
|
+
// Side-effect imports register the subview custom elements
|
|
16
|
+
import './ops-view-security-overview.js';
|
|
17
|
+
import './ops-view-security-blocked.js';
|
|
18
|
+
import './ops-view-security-authentication.js';
|
|
19
|
+
import './ops-view-security-emailsecurity.js';
|
|
20
|
+
|
|
21
|
+
declare global {
|
|
22
|
+
interface HTMLElementTagNameMap {
|
|
23
|
+
'ops-view-security': OpsViewSecurity;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type TSecurityTab = 'overview' | 'blocked' | 'authentication' | 'emailsecurity';
|
|
28
|
+
|
|
29
|
+
@customElement('ops-view-security')
|
|
30
|
+
export class OpsViewSecurity extends DeesElement {
|
|
31
|
+
@state()
|
|
32
|
+
accessor selectedTab: TSecurityTab = 'overview';
|
|
33
|
+
|
|
34
|
+
private tabLabelMap: Record<TSecurityTab, string> = {
|
|
35
|
+
'overview': 'Overview',
|
|
36
|
+
'blocked': 'Blocked IPs',
|
|
37
|
+
'authentication': 'Authentication',
|
|
38
|
+
'emailsecurity': 'Email Security',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
private labelToTab: Record<string, TSecurityTab> = {
|
|
42
|
+
'Overview': 'overview',
|
|
43
|
+
'Blocked IPs': 'blocked',
|
|
44
|
+
'Authentication': 'authentication',
|
|
45
|
+
'Email Security': 'emailsecurity',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
private static isSecurityTab(s: string | null): s is TSecurityTab {
|
|
49
|
+
return s === 'overview' || s === 'blocked' || s === 'authentication' || s === 'emailsecurity';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
constructor() {
|
|
53
|
+
super();
|
|
54
|
+
// Read initial subview from state (URL-driven)
|
|
55
|
+
const initialState = appstate.uiStatePart.getState()!;
|
|
56
|
+
if (OpsViewSecurity.isSecurityTab(initialState.activeSubview)) {
|
|
57
|
+
this.selectedTab = initialState.activeSubview;
|
|
58
|
+
}
|
|
59
|
+
// Subscribe to future changes (back/forward navigation, direct URL entry)
|
|
60
|
+
const sub = appstate.uiStatePart.select((s) => s.activeSubview).subscribe((sub) => {
|
|
61
|
+
if (OpsViewSecurity.isSecurityTab(sub) && sub !== this.selectedTab) {
|
|
62
|
+
this.selectedTab = sub;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
this.rxSubscriptions.push(sub);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async firstUpdated() {
|
|
69
|
+
const toggle = this.shadowRoot!.querySelector('dees-input-multitoggle') as any;
|
|
70
|
+
if (toggle) {
|
|
71
|
+
const sub = toggle.changeSubject.subscribe(() => {
|
|
72
|
+
const tab = this.labelToTab[toggle.selectedOption];
|
|
73
|
+
if (tab && tab !== this.selectedTab) {
|
|
74
|
+
// Push URL → router updates state → subscription updates selectedTab
|
|
75
|
+
appRouter.navigateToView('security', tab);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
this.rxSubscriptions.push(sub);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public static styles = [
|
|
83
|
+
cssManager.defaultStyles,
|
|
84
|
+
viewHostCss,
|
|
85
|
+
css`
|
|
86
|
+
dees-input-multitoggle {
|
|
87
|
+
margin-bottom: 24px;
|
|
88
|
+
}
|
|
89
|
+
`,
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
public render(): TemplateResult {
|
|
93
|
+
return html`
|
|
94
|
+
<dees-heading level="2">Security</dees-heading>
|
|
95
|
+
|
|
96
|
+
<dees-input-multitoggle
|
|
97
|
+
.type=${'single'}
|
|
98
|
+
.options=${['Overview', 'Blocked IPs', 'Authentication', 'Email Security']}
|
|
99
|
+
.selectedOption=${this.tabLabelMap[this.selectedTab]}
|
|
100
|
+
></dees-input-multitoggle>
|
|
101
|
+
|
|
102
|
+
${this.renderTabContent()}
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private renderTabContent(): TemplateResult {
|
|
107
|
+
switch (this.selectedTab) {
|
|
108
|
+
case 'overview': return html`<ops-view-security-overview></ops-view-security-overview>`;
|
|
109
|
+
case 'blocked': return html`<ops-view-security-blocked></ops-view-security-blocked>`;
|
|
110
|
+
case 'authentication': return html`<ops-view-security-authentication></ops-view-security-authentication>`;
|
|
111
|
+
case 'emailsecurity': return html`<ops-view-security-emailsecurity></ops-view-security-emailsecurity>`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
package/ts_web/router.ts
CHANGED
|
@@ -3,9 +3,31 @@ import * as appstate from './appstate.js';
|
|
|
3
3
|
|
|
4
4
|
const SmartRouter = plugins.domtools.plugins.smartrouter.SmartRouter;
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// Flat top-level views (no subviews)
|
|
7
|
+
const flatViews = ['overview', 'configuration', 'emails', 'logs', 'apitokens', 'certificates', 'remoteingress', 'vpn'] as const;
|
|
8
|
+
|
|
9
|
+
// Tabbed views and their valid subviews
|
|
10
|
+
const subviewMap: Record<string, readonly string[]> = {
|
|
11
|
+
network: ['activity', 'routes', 'sourceprofiles', 'networktargets', 'targetprofiles'] as const,
|
|
12
|
+
security: ['overview', 'blocked', 'authentication', 'emailsecurity'] as const,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Default subview when user visits the bare parent URL
|
|
16
|
+
const defaultSubview: Record<string, string> = {
|
|
17
|
+
network: 'activity',
|
|
18
|
+
security: 'overview',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const validTopLevelViews = [...flatViews, ...Object.keys(subviewMap)] as const;
|
|
22
|
+
export type TValidView = typeof validTopLevelViews[number];
|
|
23
|
+
|
|
24
|
+
export function isValidView(view: string): boolean {
|
|
25
|
+
return (validTopLevelViews as readonly string[]).includes(view);
|
|
26
|
+
}
|
|
7
27
|
|
|
8
|
-
export
|
|
28
|
+
export function isValidSubview(view: string, subview: string): boolean {
|
|
29
|
+
return subviewMap[view]?.includes(subview) ?? false;
|
|
30
|
+
}
|
|
9
31
|
|
|
10
32
|
class AppRouter {
|
|
11
33
|
private router: InstanceType<typeof SmartRouter>;
|
|
@@ -25,10 +47,25 @@ class AppRouter {
|
|
|
25
47
|
}
|
|
26
48
|
|
|
27
49
|
private setupRoutes(): void {
|
|
28
|
-
|
|
50
|
+
// Flat views
|
|
51
|
+
for (const view of flatViews) {
|
|
52
|
+
this.router.on(`/${view}`, async () => {
|
|
53
|
+
this.updateViewState(view, null);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Tabbed views
|
|
58
|
+
for (const view of Object.keys(subviewMap)) {
|
|
59
|
+
// Bare parent → redirect to default subview
|
|
29
60
|
this.router.on(`/${view}`, async () => {
|
|
30
|
-
this.
|
|
61
|
+
this.navigateTo(`/${view}/${defaultSubview[view]}`);
|
|
31
62
|
});
|
|
63
|
+
// Each valid subview
|
|
64
|
+
for (const sub of subviewMap[view]) {
|
|
65
|
+
this.router.on(`/${view}/${sub}`, async () => {
|
|
66
|
+
this.updateViewState(view, sub);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
32
69
|
}
|
|
33
70
|
|
|
34
71
|
// Root redirect
|
|
@@ -42,7 +79,9 @@ class AppRouter {
|
|
|
42
79
|
if (this.suppressStateUpdate) return;
|
|
43
80
|
|
|
44
81
|
const currentPath = window.location.pathname;
|
|
45
|
-
const expectedPath =
|
|
82
|
+
const expectedPath = uiState.activeSubview
|
|
83
|
+
? `/${uiState.activeView}/${uiState.activeSubview}`
|
|
84
|
+
: `/${uiState.activeView}`;
|
|
46
85
|
|
|
47
86
|
if (currentPath !== expectedPath) {
|
|
48
87
|
this.suppressStateUpdate = true;
|
|
@@ -57,25 +96,38 @@ class AppRouter {
|
|
|
57
96
|
|
|
58
97
|
if (!path || path === '/') {
|
|
59
98
|
this.router.pushUrl('/overview');
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const segments = path.split('/').filter(Boolean);
|
|
103
|
+
const view = segments[0];
|
|
104
|
+
const sub = segments[1];
|
|
63
105
|
|
|
64
|
-
|
|
65
|
-
|
|
106
|
+
if (!isValidView(view)) {
|
|
107
|
+
this.router.pushUrl('/overview');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (subviewMap[view]) {
|
|
112
|
+
if (sub && isValidSubview(view, sub)) {
|
|
113
|
+
this.updateViewState(view, sub);
|
|
66
114
|
} else {
|
|
67
|
-
|
|
115
|
+
// Bare parent or invalid sub → default subview
|
|
116
|
+
this.router.pushUrl(`/${view}/${defaultSubview[view]}`);
|
|
68
117
|
}
|
|
118
|
+
} else {
|
|
119
|
+
this.updateViewState(view, null);
|
|
69
120
|
}
|
|
70
121
|
}
|
|
71
122
|
|
|
72
|
-
private updateViewState(view: string): void {
|
|
123
|
+
private updateViewState(view: string, subview: string | null): void {
|
|
73
124
|
this.suppressStateUpdate = true;
|
|
74
125
|
const currentState = appstate.uiStatePart.getState()!;
|
|
75
|
-
if (currentState.activeView !== view) {
|
|
126
|
+
if (currentState.activeView !== view || currentState.activeSubview !== subview) {
|
|
76
127
|
appstate.uiStatePart.setState({
|
|
77
128
|
...currentState,
|
|
78
129
|
activeView: view,
|
|
130
|
+
activeSubview: subview,
|
|
79
131
|
} as appstate.IUiState);
|
|
80
132
|
}
|
|
81
133
|
this.suppressStateUpdate = false;
|
|
@@ -85,11 +137,17 @@ class AppRouter {
|
|
|
85
137
|
this.router.pushUrl(path);
|
|
86
138
|
}
|
|
87
139
|
|
|
88
|
-
public navigateToView(view: string): void {
|
|
89
|
-
if (
|
|
90
|
-
this.navigateTo(`/${view}`);
|
|
91
|
-
} else {
|
|
140
|
+
public navigateToView(view: string, subview?: string): void {
|
|
141
|
+
if (!isValidView(view)) {
|
|
92
142
|
this.navigateTo('/overview');
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (subview && isValidSubview(view, subview)) {
|
|
146
|
+
this.navigateTo(`/${view}/${subview}`);
|
|
147
|
+
} else if (subviewMap[view]) {
|
|
148
|
+
this.navigateTo(`/${view}/${defaultSubview[view]}`);
|
|
149
|
+
} else {
|
|
150
|
+
this.navigateTo(`/${view}`);
|
|
93
151
|
}
|
|
94
152
|
}
|
|
95
153
|
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import * as appstate from '../appstate.js';
|
|
3
|
-
import { DeesElement } from '@design.estate/dees-element';
|
|
4
|
-
export declare class OpsViewSecurity extends DeesElement {
|
|
5
|
-
accessor statsState: appstate.IStatsState;
|
|
6
|
-
accessor selectedTab: 'overview' | 'blocked' | 'authentication' | 'email-security';
|
|
7
|
-
private tabLabelMap;
|
|
8
|
-
private labelToTab;
|
|
9
|
-
constructor();
|
|
10
|
-
firstUpdated(): Promise<void>;
|
|
11
|
-
static styles: plugins.deesElement.CSSResult[];
|
|
12
|
-
render(): plugins.deesElement.TemplateResult<1>;
|
|
13
|
-
private renderTabContent;
|
|
14
|
-
private renderOverview;
|
|
15
|
-
private renderBlockedIPs;
|
|
16
|
-
private renderAuthentication;
|
|
17
|
-
private renderEmailSecurity;
|
|
18
|
-
private calculateThreatLevel;
|
|
19
|
-
private getThreatScore;
|
|
20
|
-
private getSecurityEvents;
|
|
21
|
-
private clearBlockedIPs;
|
|
22
|
-
private unblockIP;
|
|
23
|
-
private saveEmailSecuritySettings;
|
|
24
|
-
}
|