@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.
Files changed (69) hide show
  1. package/dist_serve/bundle.js +1202 -1133
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts_web/00_commitinfo_data.js +1 -1
  4. package/dist_ts_web/appstate.d.ts +1 -0
  5. package/dist_ts_web/appstate.js +9 -22
  6. package/dist_ts_web/elements/index.d.ts +2 -6
  7. package/dist_ts_web/elements/index.js +3 -7
  8. package/dist_ts_web/elements/network/index.d.ts +6 -0
  9. package/dist_ts_web/elements/network/index.js +7 -0
  10. package/dist_ts_web/elements/{ops-view-network.d.ts → network/ops-view-network-activity.d.ts} +3 -3
  11. package/dist_ts_web/elements/{ops-view-network.js → network/ops-view-network-activity.js} +20 -30
  12. package/dist_ts_web/elements/network/ops-view-network.d.ts +24 -0
  13. package/dist_ts_web/elements/network/ops-view-network.js +151 -0
  14. package/dist_ts_web/elements/{ops-view-networktargets.d.ts → network/ops-view-networktargets.d.ts} +1 -1
  15. package/dist_ts_web/elements/{ops-view-networktargets.js → network/ops-view-networktargets.js} +6 -6
  16. package/dist_ts_web/elements/{ops-view-routes.d.ts → network/ops-view-routes.d.ts} +1 -1
  17. package/dist_ts_web/elements/{ops-view-routes.js → network/ops-view-routes.js} +5 -6
  18. package/dist_ts_web/elements/{ops-view-sourceprofiles.d.ts → network/ops-view-sourceprofiles.d.ts} +1 -1
  19. package/dist_ts_web/elements/{ops-view-sourceprofiles.js → network/ops-view-sourceprofiles.js} +6 -6
  20. package/dist_ts_web/elements/{ops-view-targetprofiles.d.ts → network/ops-view-targetprofiles.d.ts} +2 -2
  21. package/dist_ts_web/elements/{ops-view-targetprofiles.js → network/ops-view-targetprofiles.js} +7 -7
  22. package/dist_ts_web/elements/ops-dashboard.js +4 -27
  23. package/dist_ts_web/elements/ops-view-apitokens.js +2 -1
  24. package/dist_ts_web/elements/ops-view-certificates.js +2 -1
  25. package/dist_ts_web/elements/ops-view-config.js +3 -3
  26. package/dist_ts_web/elements/ops-view-remoteingress.js +2 -1
  27. package/dist_ts_web/elements/ops-view-vpn.js +2 -1
  28. package/dist_ts_web/elements/security/index.d.ts +5 -0
  29. package/dist_ts_web/elements/security/index.js +6 -0
  30. package/dist_ts_web/elements/security/ops-view-security-authentication.d.ts +13 -0
  31. package/dist_ts_web/elements/security/ops-view-security-authentication.js +156 -0
  32. package/dist_ts_web/elements/security/ops-view-security-blocked.d.ts +15 -0
  33. package/dist_ts_web/elements/security/ops-view-security-blocked.js +152 -0
  34. package/dist_ts_web/elements/security/ops-view-security-emailsecurity.d.ts +14 -0
  35. package/dist_ts_web/elements/security/ops-view-security-emailsecurity.js +196 -0
  36. package/dist_ts_web/elements/security/ops-view-security-overview.d.ts +16 -0
  37. package/dist_ts_web/elements/security/ops-view-security-overview.js +204 -0
  38. package/dist_ts_web/elements/security/ops-view-security.d.ts +23 -0
  39. package/dist_ts_web/elements/security/ops-view-security.js +146 -0
  40. package/dist_ts_web/router.d.ts +5 -3
  41. package/dist_ts_web/router.js +69 -17
  42. package/package.json +1 -1
  43. package/ts/00_commitinfo_data.ts +1 -1
  44. package/ts_web/00_commitinfo_data.ts +1 -1
  45. package/ts_web/appstate.ts +10 -24
  46. package/ts_web/elements/index.ts +2 -6
  47. package/ts_web/elements/network/index.ts +6 -0
  48. package/ts_web/elements/{ops-view-network.ts → network/ops-view-network-activity.ts} +43 -53
  49. package/ts_web/elements/network/ops-view-network.ts +119 -0
  50. package/ts_web/elements/{ops-view-networktargets.ts → network/ops-view-networktargets.ts} +5 -5
  51. package/ts_web/elements/{ops-view-routes.ts → network/ops-view-routes.ts} +4 -5
  52. package/ts_web/elements/{ops-view-sourceprofiles.ts → network/ops-view-sourceprofiles.ts} +5 -5
  53. package/ts_web/elements/{ops-view-targetprofiles.ts → network/ops-view-targetprofiles.ts} +6 -6
  54. package/ts_web/elements/ops-dashboard.ts +3 -26
  55. package/ts_web/elements/ops-view-apitokens.ts +1 -0
  56. package/ts_web/elements/ops-view-certificates.ts +1 -0
  57. package/ts_web/elements/ops-view-config.ts +2 -2
  58. package/ts_web/elements/ops-view-remoteingress.ts +1 -0
  59. package/ts_web/elements/ops-view-vpn.ts +1 -0
  60. package/ts_web/elements/security/index.ts +5 -0
  61. package/ts_web/elements/security/ops-view-security-authentication.ts +120 -0
  62. package/ts_web/elements/security/ops-view-security-blocked.ts +117 -0
  63. package/ts_web/elements/security/ops-view-security-emailsecurity.ts +159 -0
  64. package/ts_web/elements/security/ops-view-security-overview.ts +171 -0
  65. package/ts_web/elements/security/ops-view-security.ts +114 -0
  66. package/ts_web/router.ts +75 -17
  67. package/dist_ts_web/elements/ops-view-security.d.ts +0 -24
  68. package/dist_ts_web/elements/ops-view-security.js +0 -481
  69. package/ts_web/elements/ops-view-security.ts +0 -453
@@ -0,0 +1,204 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import * as appstate from '../../appstate.js';
36
+ import { DeesElement, customElement, html, state, css, cssManager, } from '@design.estate/dees-element';
37
+ import {} from '@design.estate/dees-catalog';
38
+ let OpsViewSecurityOverview = (() => {
39
+ let _classDecorators = [customElement('ops-view-security-overview')];
40
+ let _classDescriptor;
41
+ let _classExtraInitializers = [];
42
+ let _classThis;
43
+ let _classSuper = DeesElement;
44
+ let _statsState_decorators;
45
+ let _statsState_initializers = [];
46
+ let _statsState_extraInitializers = [];
47
+ var OpsViewSecurityOverview = class extends _classSuper {
48
+ static { _classThis = this; }
49
+ static {
50
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
51
+ _statsState_decorators = [state()];
52
+ __esDecorate(this, null, _statsState_decorators, { kind: "accessor", name: "statsState", static: false, private: false, access: { has: obj => "statsState" in obj, get: obj => obj.statsState, set: (obj, value) => { obj.statsState = value; } }, metadata: _metadata }, _statsState_initializers, _statsState_extraInitializers);
53
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
54
+ OpsViewSecurityOverview = _classThis = _classDescriptor.value;
55
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
56
+ }
57
+ #statsState_accessor_storage = __runInitializers(this, _statsState_initializers, appstate.statsStatePart.getState());
58
+ get statsState() { return this.#statsState_accessor_storage; }
59
+ set statsState(value) { this.#statsState_accessor_storage = value; }
60
+ constructor() {
61
+ super();
62
+ __runInitializers(this, _statsState_extraInitializers);
63
+ const sub = appstate.statsStatePart
64
+ .select((s) => s)
65
+ .subscribe((s) => {
66
+ this.statsState = s;
67
+ });
68
+ this.rxSubscriptions.push(sub);
69
+ }
70
+ static styles = [
71
+ cssManager.defaultStyles,
72
+ css `
73
+ :host { display: block; }
74
+ h2 {
75
+ margin: 32px 0 16px 0;
76
+ font-size: 24px;
77
+ font-weight: 600;
78
+ color: ${cssManager.bdTheme('#333', '#ccc')};
79
+ }
80
+ dees-statsgrid {
81
+ margin-bottom: 32px;
82
+ }
83
+ `,
84
+ ];
85
+ render() {
86
+ const metrics = this.statsState.securityMetrics;
87
+ if (!metrics) {
88
+ return html `
89
+ <div class="loadingMessage">
90
+ <p>Loading security metrics...</p>
91
+ </div>
92
+ `;
93
+ }
94
+ const threatLevel = this.calculateThreatLevel(metrics);
95
+ const threatScore = this.getThreatScore(metrics);
96
+ // Derive active sessions from recent successful auth events (last hour)
97
+ const allEvents = metrics.recentEvents || [];
98
+ const oneHourAgo = Date.now() - 3600000;
99
+ const recentAuthSuccesses = allEvents.filter((evt) => evt.type === 'authentication' && evt.success === true && evt.timestamp >= oneHourAgo).length;
100
+ const tiles = [
101
+ {
102
+ id: 'threatLevel',
103
+ title: 'Threat Level',
104
+ value: threatScore,
105
+ type: 'gauge',
106
+ icon: 'lucide:Shield',
107
+ gaugeOptions: {
108
+ min: 0,
109
+ max: 100,
110
+ thresholds: [
111
+ { value: 0, color: '#ef4444' },
112
+ { value: 30, color: '#f59e0b' },
113
+ { value: 70, color: '#22c55e' },
114
+ ],
115
+ },
116
+ description: `Status: ${threatLevel.toUpperCase()}`,
117
+ },
118
+ {
119
+ id: 'blockedThreats',
120
+ title: 'Blocked Threats',
121
+ value: (metrics.blockedIPs?.length || 0) + metrics.spamDetected,
122
+ type: 'number',
123
+ icon: 'lucide:ShieldCheck',
124
+ color: '#ef4444',
125
+ description: 'Total threats blocked today',
126
+ },
127
+ {
128
+ id: 'activeSessions',
129
+ title: 'Active Sessions',
130
+ value: recentAuthSuccesses,
131
+ type: 'number',
132
+ icon: 'lucide:Users',
133
+ color: '#22c55e',
134
+ description: 'Authenticated in last hour',
135
+ },
136
+ {
137
+ id: 'authFailures',
138
+ title: 'Auth Failures',
139
+ value: metrics.authenticationFailures,
140
+ type: 'number',
141
+ icon: 'lucide:LockOpen',
142
+ color: metrics.authenticationFailures > 10 ? '#ef4444' : '#f59e0b',
143
+ description: 'Failed login attempts today',
144
+ },
145
+ ];
146
+ return html `
147
+ <dees-heading level="hr">Overview</dees-heading>
148
+
149
+ <dees-statsgrid
150
+ .tiles=${tiles}
151
+ .minTileWidth=${200}
152
+ ></dees-statsgrid>
153
+
154
+ <h2>Recent Security Events</h2>
155
+ <dees-table
156
+ .heading1=${'Security Events'}
157
+ .heading2=${'Last 24 hours'}
158
+ .data=${this.getSecurityEvents(metrics)}
159
+ .displayFunction=${(item) => ({
160
+ 'Time': new Date(item.timestamp).toLocaleTimeString(),
161
+ 'Event': item.event,
162
+ 'Severity': item.severity,
163
+ 'Details': item.details,
164
+ })}
165
+ ></dees-table>
166
+ `;
167
+ }
168
+ calculateThreatLevel(metrics) {
169
+ const score = this.getThreatScore(metrics);
170
+ if (score < 30)
171
+ return 'alert';
172
+ if (score < 70)
173
+ return 'warning';
174
+ return 'success';
175
+ }
176
+ getThreatScore(metrics) {
177
+ // Simple scoring algorithm
178
+ let score = 100;
179
+ const blockedCount = Array.isArray(metrics.blockedIPs) ? metrics.blockedIPs.length : (metrics.blockedIPs || 0);
180
+ score -= blockedCount * 2;
181
+ score -= (metrics.authenticationFailures || 0) * 1;
182
+ score -= (metrics.spamDetected || 0) * 0.5;
183
+ score -= (metrics.malwareDetected || 0) * 3;
184
+ score -= (metrics.phishingDetected || 0) * 3;
185
+ score -= (metrics.suspiciousActivities || 0) * 2;
186
+ return Math.max(0, Math.min(100, Math.round(score)));
187
+ }
188
+ getSecurityEvents(metrics) {
189
+ const events = metrics.recentEvents || [];
190
+ return events.map((evt) => ({
191
+ timestamp: evt.timestamp,
192
+ event: evt.message,
193
+ severity: evt.level === 'critical' ? 'critical' : evt.level === 'error' ? 'high' : evt.level === 'warn' ? 'warning' : 'info',
194
+ details: evt.ipAddress ? `IP: ${evt.ipAddress}` : evt.domain ? `Domain: ${evt.domain}` : evt.type,
195
+ }));
196
+ }
197
+ static {
198
+ __runInitializers(_classThis, _classExtraInitializers);
199
+ }
200
+ };
201
+ return OpsViewSecurityOverview = _classThis;
202
+ })();
203
+ export { OpsViewSecurityOverview };
204
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctc2VjdXJpdHktb3ZlcnZpZXcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90c193ZWIvZWxlbWVudHMvc2VjdXJpdHkvb3BzLXZpZXctc2VjdXJpdHktb3ZlcnZpZXcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFFOUMsT0FBTyxFQUNMLFdBQVcsRUFDWCxhQUFhLEVBQ2IsSUFBSSxFQUNKLEtBQUssRUFDTCxHQUFHLEVBQ0gsVUFBVSxHQUVYLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUFtQixNQUFNLDZCQUE2QixDQUFDO0lBU2pELHVCQUF1Qjs0QkFEbkMsYUFBYSxDQUFDLDRCQUE0QixDQUFDOzs7O3NCQUNDLFdBQVc7Ozs7dUNBQW5CLFNBQVEsV0FBVzs7OztzQ0FDckQsS0FBSyxFQUFFO1lBQ1IsbUxBQVMsVUFBVSw2QkFBVixVQUFVLCtGQUE2RDtZQUZsRiw2S0FzSkM7Ozs7UUFwSkMsaUZBQTRDLFFBQVEsQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFHLEVBQUM7UUFBaEYsSUFBUyxVQUFVLGdEQUE2RDtRQUFoRixJQUFTLFVBQVUsc0RBQTZEO1FBRWhGO1lBQ0UsS0FBSyxFQUFFLENBQUM7O1lBQ1IsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLGNBQWM7aUJBQ2hDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2lCQUNoQixTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDZixJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztZQUN0QixDQUFDLENBQUMsQ0FBQztZQUNMLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ2hDO1FBRU0sTUFBTSxDQUFDLE1BQU0sR0FBRztZ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
@@ -0,0 +1,23 @@
1
+ import { DeesElement, type TemplateResult } from '@design.estate/dees-element';
2
+ import './ops-view-security-overview.js';
3
+ import './ops-view-security-blocked.js';
4
+ import './ops-view-security-authentication.js';
5
+ import './ops-view-security-emailsecurity.js';
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ 'ops-view-security': OpsViewSecurity;
9
+ }
10
+ }
11
+ type TSecurityTab = 'overview' | 'blocked' | 'authentication' | 'emailsecurity';
12
+ export declare class OpsViewSecurity extends DeesElement {
13
+ accessor selectedTab: TSecurityTab;
14
+ private tabLabelMap;
15
+ private labelToTab;
16
+ private static isSecurityTab;
17
+ constructor();
18
+ firstUpdated(): Promise<void>;
19
+ static styles: import("@design.estate/dees-element").CSSResult[];
20
+ render(): TemplateResult;
21
+ private renderTabContent;
22
+ }
23
+ export {};
@@ -0,0 +1,146 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import * as appstate from '../../appstate.js';
36
+ import { appRouter } from '../../router.js';
37
+ import { viewHostCss } from '../shared/css.js';
38
+ import { DeesElement, customElement, html, state, css, cssManager, } from '@design.estate/dees-element';
39
+ // Side-effect imports register the subview custom elements
40
+ import './ops-view-security-overview.js';
41
+ import './ops-view-security-blocked.js';
42
+ import './ops-view-security-authentication.js';
43
+ import './ops-view-security-emailsecurity.js';
44
+ let OpsViewSecurity = (() => {
45
+ let _classDecorators = [customElement('ops-view-security')];
46
+ let _classDescriptor;
47
+ let _classExtraInitializers = [];
48
+ let _classThis;
49
+ let _classSuper = DeesElement;
50
+ let _selectedTab_decorators;
51
+ let _selectedTab_initializers = [];
52
+ let _selectedTab_extraInitializers = [];
53
+ var OpsViewSecurity = class extends _classSuper {
54
+ static { _classThis = this; }
55
+ static {
56
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
57
+ _selectedTab_decorators = [state()];
58
+ __esDecorate(this, null, _selectedTab_decorators, { kind: "accessor", name: "selectedTab", static: false, private: false, access: { has: obj => "selectedTab" in obj, get: obj => obj.selectedTab, set: (obj, value) => { obj.selectedTab = value; } }, metadata: _metadata }, _selectedTab_initializers, _selectedTab_extraInitializers);
59
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
60
+ OpsViewSecurity = _classThis = _classDescriptor.value;
61
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
62
+ }
63
+ #selectedTab_accessor_storage = __runInitializers(this, _selectedTab_initializers, 'overview');
64
+ get selectedTab() { return this.#selectedTab_accessor_storage; }
65
+ set selectedTab(value) { this.#selectedTab_accessor_storage = value; }
66
+ tabLabelMap = (__runInitializers(this, _selectedTab_extraInitializers), {
67
+ 'overview': 'Overview',
68
+ 'blocked': 'Blocked IPs',
69
+ 'authentication': 'Authentication',
70
+ 'emailsecurity': 'Email Security',
71
+ });
72
+ labelToTab = {
73
+ 'Overview': 'overview',
74
+ 'Blocked IPs': 'blocked',
75
+ 'Authentication': 'authentication',
76
+ 'Email Security': 'emailsecurity',
77
+ };
78
+ static isSecurityTab(s) {
79
+ return s === 'overview' || s === 'blocked' || s === 'authentication' || s === 'emailsecurity';
80
+ }
81
+ constructor() {
82
+ super();
83
+ // Read initial subview from state (URL-driven)
84
+ const initialState = appstate.uiStatePart.getState();
85
+ if (OpsViewSecurity.isSecurityTab(initialState.activeSubview)) {
86
+ this.selectedTab = initialState.activeSubview;
87
+ }
88
+ // Subscribe to future changes (back/forward navigation, direct URL entry)
89
+ const sub = appstate.uiStatePart.select((s) => s.activeSubview).subscribe((sub) => {
90
+ if (OpsViewSecurity.isSecurityTab(sub) && sub !== this.selectedTab) {
91
+ this.selectedTab = sub;
92
+ }
93
+ });
94
+ this.rxSubscriptions.push(sub);
95
+ }
96
+ async firstUpdated() {
97
+ const toggle = this.shadowRoot.querySelector('dees-input-multitoggle');
98
+ if (toggle) {
99
+ const sub = toggle.changeSubject.subscribe(() => {
100
+ const tab = this.labelToTab[toggle.selectedOption];
101
+ if (tab && tab !== this.selectedTab) {
102
+ // Push URL → router updates state → subscription updates selectedTab
103
+ appRouter.navigateToView('security', tab);
104
+ }
105
+ });
106
+ this.rxSubscriptions.push(sub);
107
+ }
108
+ }
109
+ static styles = [
110
+ cssManager.defaultStyles,
111
+ viewHostCss,
112
+ css `
113
+ dees-input-multitoggle {
114
+ margin-bottom: 24px;
115
+ }
116
+ `,
117
+ ];
118
+ render() {
119
+ return html `
120
+ <dees-heading level="2">Security</dees-heading>
121
+
122
+ <dees-input-multitoggle
123
+ .type=${'single'}
124
+ .options=${['Overview', 'Blocked IPs', 'Authentication', 'Email Security']}
125
+ .selectedOption=${this.tabLabelMap[this.selectedTab]}
126
+ ></dees-input-multitoggle>
127
+
128
+ ${this.renderTabContent()}
129
+ `;
130
+ }
131
+ renderTabContent() {
132
+ switch (this.selectedTab) {
133
+ case 'overview': return html `<ops-view-security-overview></ops-view-security-overview>`;
134
+ case 'blocked': return html `<ops-view-security-blocked></ops-view-security-blocked>`;
135
+ case 'authentication': return html `<ops-view-security-authentication></ops-view-security-authentication>`;
136
+ case 'emailsecurity': return html `<ops-view-security-emailsecurity></ops-view-security-emailsecurity>`;
137
+ }
138
+ }
139
+ static {
140
+ __runInitializers(_classThis, _classExtraInitializers);
141
+ }
142
+ };
143
+ return OpsViewSecurity = _classThis;
144
+ })();
145
+ export { OpsViewSecurity };
146
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctc2VjdXJpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90c193ZWIvZWxlbWVudHMvc2VjdXJpdHkvb3BzLXZpZXctc2VjdXJpdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUUvQyxPQUFPLEVBQ0wsV0FBVyxFQUNYLGFBQWEsRUFDYixJQUFJLEVBQ0osS0FBSyxFQUNMLEdBQUcsRUFDSCxVQUFVLEdBRVgsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQywyREFBMkQ7QUFDM0QsT0FBTyxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLGdDQUFnQyxDQUFDO0FBQ3hDLE9BQU8sdUNBQXVDLENBQUM7QUFDL0MsT0FBTyxzQ0FBc0MsQ0FBQztJQVdqQyxlQUFlOzRCQUQzQixhQUFhLENBQUMsbUJBQW1CLENBQUM7Ozs7c0JBQ0UsV0FBVzs7OzsrQkFBbkIsU0FBUSxXQUFXOzs7O3VDQUM3QyxLQUFLLEVBQUU7WUFDUixzTEFBUyxXQUFXLDZCQUFYLFdBQVcsaUdBQTRCO1lBRmxELDZLQW9GQzs7OztRQWxGQyxtRkFBcUMsVUFBVSxFQUFDO1FBQWhELElBQVMsV0FBVyxpREFBNEI7UUFBaEQsSUFBUyxXQUFXLHVEQUE0QjtRQUV4QyxXQUFXLDZEQUFpQztZQUNsRCxVQUFVLEVBQVEsVUFBVTtZQUM1QixTQUFTLEVBQVMsYUFBYTtZQUMvQixnQkFBZ0IsRUFBRSxnQkFBZ0I7WUFDbEMsZUFBZSxFQUFHLGdCQUFnQjtTQUNuQyxFQUFDO1FBRU0sVUFBVSxHQUFpQztZQUNqRCxVQUFVLEVBQVEsVUFBVTtZQUM1QixhQUFhLEVBQUssU0FBUztZQUMzQixnQkFBZ0IsRUFBRSxnQkFBZ0I7WUFDbEMsZ0JBQWdCLEVBQUUsZUFBZTtTQUNsQyxDQUFDO1FBRU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFnQjtZQUMzQyxPQUFPLENBQUMsS0FBSyxVQUFVLElBQUksQ0FBQyxLQUFLLFNBQVMsSUFBSSxDQUFDLEtBQUssZ0JBQWdCLElBQUksQ0FBQyxLQUFLLGVBQWUsQ0FBQztRQUNoRyxDQUFDO1FBRUQ7WUFDRSxLQUFLLEVBQUUsQ0FBQztZQUNSLCtDQUErQztZQUMvQyxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRyxDQUFDO1lBQ3RELElBQUksZUFBZSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztnQkFDOUQsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDO1lBQ2hELENBQUM7WUFDRCwwRUFBMEU7WUFDMUUsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDaEYsSUFBSSxlQUFlLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsS0FBSyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7b0JBQ25FLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDO2dCQUN6QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNqQyxDQUFDO1FBRUQsS0FBSyxDQUFDLFlBQVk7WUFDaEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVcsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQVEsQ0FBQztZQUMvRSxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUNYLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtvQkFDOUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7b0JBQ25ELElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7d0JBQ3BDLHFFQUFxRTt3QkFDckUsU0FBUyxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBQzVDLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakMsQ0FBQztRQUNILENBQUM7UUFFTSxNQUFNLENBQUMsTUFBTSxHQUFHO1lBQ3JCLFVBQVUsQ0FBQyxhQUFhO1lBQ3hCLFdBQVc7WUFDWCxHQUFHLENBQUE7Ozs7S0FJRjtTQUNGLENBQUM7UUFFSyxNQUFNO1lBQ1gsT0FBTyxJQUFJLENBQUE7Ozs7Z0JBSUMsUUFBUTttQkFDTCxDQUFDLFVBQVUsRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUM7MEJBQ3hELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQzs7O1FBR3BELElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtLQUMxQixDQUFDO1FBQ0osQ0FBQztRQUVPLGdCQUFnQjtZQUN0QixRQUFRLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDekIsS0FBSyxVQUFVLENBQUMsQ0FBTyxPQUFPLElBQUksQ0FBQSwyREFBMkQsQ0FBQztnQkFDOUYsS0FBSyxTQUFTLENBQUMsQ0FBUSxPQUFPLElBQUksQ0FBQSx5REFBeUQsQ0FBQztnQkFDNUYsS0FBSyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFBLHVFQUF1RSxDQUFDO2dCQUMxRyxLQUFLLGVBQWUsQ0FBQyxDQUFFLE9BQU8sSUFBSSxDQUFBLHFFQUFxRSxDQUFDO1lBQzFHLENBQUM7UUFDSCxDQUFDOztZQW5GVSx1REFBZTs7Ozs7U0FBZixlQUFlIn0=
@@ -1,5 +1,7 @@
1
- export declare const validViews: readonly ["overview", "network", "emails", "logs", "routes", "apitokens", "configuration", "security", "certificates", "remoteingress", "vpn", "sourceprofiles", "networktargets", "targetprofiles"];
2
- export type TValidView = typeof validViews[number];
1
+ export declare const validTopLevelViews: readonly ["overview", "configuration", "emails", "logs", "apitokens", "certificates", "remoteingress", "vpn", ...string[]];
2
+ export type TValidView = typeof validTopLevelViews[number];
3
+ export declare function isValidView(view: string): boolean;
4
+ export declare function isValidSubview(view: string, subview: string): boolean;
3
5
  declare class AppRouter {
4
6
  private router;
5
7
  private initialized;
@@ -11,7 +13,7 @@ declare class AppRouter {
11
13
  private handleInitialRoute;
12
14
  private updateViewState;
13
15
  navigateTo(path: string): void;
14
- navigateToView(view: string): void;
16
+ navigateToView(view: string, subview?: string): void;
15
17
  getCurrentView(): string;
16
18
  destroy(): void;
17
19
  }
@@ -1,7 +1,25 @@
1
1
  import * as plugins from './plugins.js';
2
2
  import * as appstate from './appstate.js';
3
3
  const SmartRouter = plugins.domtools.plugins.smartrouter.SmartRouter;
4
- export const validViews = ['overview', 'network', 'emails', 'logs', 'routes', 'apitokens', 'configuration', 'security', 'certificates', 'remoteingress', 'vpn', 'sourceprofiles', 'networktargets', 'targetprofiles'];
4
+ // Flat top-level views (no subviews)
5
+ const flatViews = ['overview', 'configuration', 'emails', 'logs', 'apitokens', 'certificates', 'remoteingress', 'vpn'];
6
+ // Tabbed views and their valid subviews
7
+ const subviewMap = {
8
+ network: ['activity', 'routes', 'sourceprofiles', 'networktargets', 'targetprofiles'],
9
+ security: ['overview', 'blocked', 'authentication', 'emailsecurity'],
10
+ };
11
+ // Default subview when user visits the bare parent URL
12
+ const defaultSubview = {
13
+ network: 'activity',
14
+ security: 'overview',
15
+ };
16
+ export const validTopLevelViews = [...flatViews, ...Object.keys(subviewMap)];
17
+ export function isValidView(view) {
18
+ return validTopLevelViews.includes(view);
19
+ }
20
+ export function isValidSubview(view, subview) {
21
+ return subviewMap[view]?.includes(subview) ?? false;
22
+ }
5
23
  class AppRouter {
6
24
  router;
7
25
  initialized = false;
@@ -18,10 +36,24 @@ class AppRouter {
18
36
  this.initialized = true;
19
37
  }
20
38
  setupRoutes() {
21
- for (const view of validViews) {
39
+ // Flat views
40
+ for (const view of flatViews) {
41
+ this.router.on(`/${view}`, async () => {
42
+ this.updateViewState(view, null);
43
+ });
44
+ }
45
+ // Tabbed views
46
+ for (const view of Object.keys(subviewMap)) {
47
+ // Bare parent → redirect to default subview
22
48
  this.router.on(`/${view}`, async () => {
23
- this.updateViewState(view);
49
+ this.navigateTo(`/${view}/${defaultSubview[view]}`);
24
50
  });
51
+ // Each valid subview
52
+ for (const sub of subviewMap[view]) {
53
+ this.router.on(`/${view}/${sub}`, async () => {
54
+ this.updateViewState(view, sub);
55
+ });
56
+ }
25
57
  }
26
58
  // Root redirect
27
59
  this.router.on('/', async () => {
@@ -33,7 +65,9 @@ class AppRouter {
33
65
  if (this.suppressStateUpdate)
34
66
  return;
35
67
  const currentPath = window.location.pathname;
36
- const expectedPath = `/${uiState.activeView}`;
68
+ const expectedPath = uiState.activeSubview
69
+ ? `/${uiState.activeView}/${uiState.activeSubview}`
70
+ : `/${uiState.activeView}`;
37
71
  if (currentPath !== expectedPath) {
38
72
  this.suppressStateUpdate = true;
39
73
  this.router.pushUrl(expectedPath);
@@ -45,25 +79,36 @@ class AppRouter {
45
79
  const path = window.location.pathname;
46
80
  if (!path || path === '/') {
47
81
  this.router.pushUrl('/overview');
82
+ return;
48
83
  }
49
- else {
50
- const segments = path.split('/').filter(Boolean);
51
- const view = segments[0];
52
- if (validViews.includes(view)) {
53
- this.updateViewState(view);
84
+ const segments = path.split('/').filter(Boolean);
85
+ const view = segments[0];
86
+ const sub = segments[1];
87
+ if (!isValidView(view)) {
88
+ this.router.pushUrl('/overview');
89
+ return;
90
+ }
91
+ if (subviewMap[view]) {
92
+ if (sub && isValidSubview(view, sub)) {
93
+ this.updateViewState(view, sub);
54
94
  }
55
95
  else {
56
- this.router.pushUrl('/overview');
96
+ // Bare parent or invalid sub → default subview
97
+ this.router.pushUrl(`/${view}/${defaultSubview[view]}`);
57
98
  }
58
99
  }
100
+ else {
101
+ this.updateViewState(view, null);
102
+ }
59
103
  }
60
- updateViewState(view) {
104
+ updateViewState(view, subview) {
61
105
  this.suppressStateUpdate = true;
62
106
  const currentState = appstate.uiStatePart.getState();
63
- if (currentState.activeView !== view) {
107
+ if (currentState.activeView !== view || currentState.activeSubview !== subview) {
64
108
  appstate.uiStatePart.setState({
65
109
  ...currentState,
66
110
  activeView: view,
111
+ activeSubview: subview,
67
112
  });
68
113
  }
69
114
  this.suppressStateUpdate = false;
@@ -71,12 +116,19 @@ class AppRouter {
71
116
  navigateTo(path) {
72
117
  this.router.pushUrl(path);
73
118
  }
74
- navigateToView(view) {
75
- if (validViews.includes(view)) {
76
- this.navigateTo(`/${view}`);
119
+ navigateToView(view, subview) {
120
+ if (!isValidView(view)) {
121
+ this.navigateTo('/overview');
122
+ return;
123
+ }
124
+ if (subview && isValidSubview(view, subview)) {
125
+ this.navigateTo(`/${view}/${subview}`);
126
+ }
127
+ else if (subviewMap[view]) {
128
+ this.navigateTo(`/${view}/${defaultSubview[view]}`);
77
129
  }
78
130
  else {
79
- this.navigateTo('/overview');
131
+ this.navigateTo(`/${view}`);
80
132
  }
81
133
  }
82
134
  getCurrentView() {
@@ -88,4 +140,4 @@ class AppRouter {
88
140
  }
89
141
  }
90
142
  export const appRouter = new AppRouter();
91
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssUUFBUSxNQUFNLGVBQWUsQ0FBQztBQUUxQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0FBRXJFLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQVUsQ0FBQztBQUkvTixNQUFNLFNBQVM7SUFDTCxNQUFNLENBQW1DO0lBQ3pDLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO0lBRXBDO1FBQ0UsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLFdBQVcsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFTSxJQUFJO1FBQ1QsSUFBSSxJQUFJLENBQUMsV0FBVztZQUFFLE9BQU87UUFDN0IsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztJQUMxQixDQUFDO0lBRU8sV0FBVztRQUNqQixLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxF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
143
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssUUFBUSxNQUFNLGVBQWUsQ0FBQztBQUUxQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0FBRXJFLHFDQUFxQztBQUNyQyxNQUFNLFNBQVMsR0FBRyxDQUFDLFVBQVUsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBRSxLQUFLLENBQVUsQ0FBQztBQUVoSSx3Q0FBd0M7QUFDeEMsTUFBTSxVQUFVLEdBQXNDO0lBQ3BELE9BQU8sRUFBRSxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQVU7SUFDOUYsUUFBUSxFQUFFLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxlQUFlLENBQVU7Q0FDOUUsQ0FBQztBQUVGLHVEQUF1RDtBQUN2RCxNQUFNLGNBQWMsR0FBMkI7SUFDN0MsT0FBTyxFQUFFLFVBQVU7SUFDbkIsUUFBUSxFQUFFLFVBQVU7Q0FDckIsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBRyxTQUFTLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUM7QUFHdEYsTUFBTSxVQUFVLFdBQVcsQ0FBQyxJQUFZO0lBQ3RDLE9BQVEsa0JBQXdDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xFLENBQUM7QUFFRCxNQUFNLFVBQVUsY0FBYyxDQUFDLElBQVksRUFBRSxPQUFlO0lBQzFELE9BQU8sVUFBVSxDQUFDLElBQUks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
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@serve.zone/dcrouter",
3
3
  "private": false,
4
- "version": "13.1.3",
4
+ "version": "13.3.0",
5
5
  "description": "A multifaceted routing service handling mail and SMS delivery functions.",
6
6
  "type": "module",
7
7
  "exports": {
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '13.1.3',
6
+ version: '13.3.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  }
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '13.1.3',
6
+ version: '13.3.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  }