@serve.zone/dcrouter 7.4.2 → 8.0.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 +10755 -3472
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +3 -0
- package/dist_ts/classes.dcrouter.js +43 -3
- package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +22 -2
- package/dist_ts/opsserver/handlers/email-ops.handler.js +166 -159
- package/dist_ts_interfaces/requests/email-ops.d.ts +51 -108
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +2 -16
- package/dist_ts_web/appstate.js +7 -176
- package/dist_ts_web/elements/ops-view-emails.d.ts +8 -31
- package/dist_ts_web/elements/ops-view-emails.js +54 -769
- package/dist_ts_web/elements/ops-view-logs.d.ts +2 -8
- package/dist_ts_web/elements/ops-view-logs.js +4 -101
- package/dist_ts_web/plugins.d.ts +2 -1
- package/dist_ts_web/plugins.js +4 -2
- package/dist_ts_web/router.d.ts +0 -6
- package/dist_ts_web/router.js +7 -81
- package/package.json +3 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +46 -2
- package/ts/opsserver/handlers/email-ops.handler.ts +177 -225
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +8 -221
- package/ts_web/elements/ops-view-emails.ts +40 -749
- package/ts_web/elements/ops-view-logs.ts +2 -87
- package/ts_web/plugins.ts +4 -0
- package/ts_web/router.ts +6 -81
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
1
|
import * as appstate from '../appstate.js';
|
|
3
2
|
import { DeesElement } from '@design.estate/dees-element';
|
|
4
3
|
export declare class OpsViewLogs extends DeesElement {
|
|
5
4
|
accessor logState: appstate.ILogState;
|
|
6
|
-
accessor filterLevel: string | undefined;
|
|
7
|
-
accessor filterCategory: string | undefined;
|
|
8
|
-
accessor filterLimit: number;
|
|
9
5
|
private lastPushedCount;
|
|
10
6
|
constructor();
|
|
11
|
-
static styles:
|
|
12
|
-
render():
|
|
7
|
+
static styles: import("@design.estate/dees-element").CSSResult[];
|
|
8
|
+
render(): import("@design.estate/dees-element").TemplateResult<1>;
|
|
13
9
|
connectedCallback(): Promise<void>;
|
|
14
10
|
updated(changedProperties: Map<string, any>): Promise<void>;
|
|
15
11
|
private pushLogsToChart;
|
|
16
12
|
private getMappedLogEntries;
|
|
17
|
-
private fetchLogs;
|
|
18
|
-
private updateFilter;
|
|
19
13
|
}
|
|
@@ -32,7 +32,6 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
32
32
|
}
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
|
-
import * as plugins from '../plugins.js';
|
|
36
35
|
import * as shared from './shared/index.js';
|
|
37
36
|
import * as appstate from '../appstate.js';
|
|
38
37
|
import { DeesElement, customElement, html, state, css, cssManager, } from '@design.estate/dees-element';
|
|
@@ -45,27 +44,12 @@ let OpsViewLogs = (() => {
|
|
|
45
44
|
let _logState_decorators;
|
|
46
45
|
let _logState_initializers = [];
|
|
47
46
|
let _logState_extraInitializers = [];
|
|
48
|
-
let _filterLevel_decorators;
|
|
49
|
-
let _filterLevel_initializers = [];
|
|
50
|
-
let _filterLevel_extraInitializers = [];
|
|
51
|
-
let _filterCategory_decorators;
|
|
52
|
-
let _filterCategory_initializers = [];
|
|
53
|
-
let _filterCategory_extraInitializers = [];
|
|
54
|
-
let _filterLimit_decorators;
|
|
55
|
-
let _filterLimit_initializers = [];
|
|
56
|
-
let _filterLimit_extraInitializers = [];
|
|
57
47
|
var OpsViewLogs = class extends _classSuper {
|
|
58
48
|
static { _classThis = this; }
|
|
59
49
|
static {
|
|
60
50
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
61
51
|
_logState_decorators = [state()];
|
|
62
|
-
_filterLevel_decorators = [state()];
|
|
63
|
-
_filterCategory_decorators = [state()];
|
|
64
|
-
_filterLimit_decorators = [state()];
|
|
65
52
|
__esDecorate(this, null, _logState_decorators, { kind: "accessor", name: "logState", static: false, private: false, access: { has: obj => "logState" in obj, get: obj => obj.logState, set: (obj, value) => { obj.logState = value; } }, metadata: _metadata }, _logState_initializers, _logState_extraInitializers);
|
|
66
|
-
__esDecorate(this, null, _filterLevel_decorators, { kind: "accessor", name: "filterLevel", static: false, private: false, access: { has: obj => "filterLevel" in obj, get: obj => obj.filterLevel, set: (obj, value) => { obj.filterLevel = value; } }, metadata: _metadata }, _filterLevel_initializers, _filterLevel_extraInitializers);
|
|
67
|
-
__esDecorate(this, null, _filterCategory_decorators, { kind: "accessor", name: "filterCategory", static: false, private: false, access: { has: obj => "filterCategory" in obj, get: obj => obj.filterCategory, set: (obj, value) => { obj.filterCategory = value; } }, metadata: _metadata }, _filterCategory_initializers, _filterCategory_extraInitializers);
|
|
68
|
-
__esDecorate(this, null, _filterLimit_decorators, { kind: "accessor", name: "filterLimit", static: false, private: false, access: { has: obj => "filterLimit" in obj, get: obj => obj.filterLimit, set: (obj, value) => { obj.filterLimit = value; } }, metadata: _metadata }, _filterLimit_initializers, _filterLimit_extraInitializers);
|
|
69
53
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
70
54
|
OpsViewLogs = _classThis = _classDescriptor.value;
|
|
71
55
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -77,16 +61,7 @@ let OpsViewLogs = (() => {
|
|
|
77
61
|
});
|
|
78
62
|
get logState() { return this.#logState_accessor_storage; }
|
|
79
63
|
set logState(value) { this.#logState_accessor_storage = value; }
|
|
80
|
-
|
|
81
|
-
get filterLevel() { return this.#filterLevel_accessor_storage; }
|
|
82
|
-
set filterLevel(value) { this.#filterLevel_accessor_storage = value; }
|
|
83
|
-
#filterCategory_accessor_storage = (__runInitializers(this, _filterLevel_extraInitializers), __runInitializers(this, _filterCategory_initializers, void 0));
|
|
84
|
-
get filterCategory() { return this.#filterCategory_accessor_storage; }
|
|
85
|
-
set filterCategory(value) { this.#filterCategory_accessor_storage = value; }
|
|
86
|
-
#filterLimit_accessor_storage = (__runInitializers(this, _filterCategory_extraInitializers), __runInitializers(this, _filterLimit_initializers, 100));
|
|
87
|
-
get filterLimit() { return this.#filterLimit_accessor_storage; }
|
|
88
|
-
set filterLimit(value) { this.#filterLimit_accessor_storage = value; }
|
|
89
|
-
lastPushedCount = (__runInitializers(this, _filterLimit_extraInitializers), 0);
|
|
64
|
+
lastPushedCount = (__runInitializers(this, _logState_extraInitializers), 0);
|
|
90
65
|
constructor() {
|
|
91
66
|
super();
|
|
92
67
|
const subscription = appstate.logStatePart
|
|
@@ -99,62 +74,12 @@ let OpsViewLogs = (() => {
|
|
|
99
74
|
static styles = [
|
|
100
75
|
cssManager.defaultStyles,
|
|
101
76
|
shared.viewHostCss,
|
|
102
|
-
css
|
|
103
|
-
.controls {
|
|
104
|
-
display: flex;
|
|
105
|
-
gap: 16px;
|
|
106
|
-
margin-bottom: 24px;
|
|
107
|
-
flex-wrap: wrap;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.filterGroup {
|
|
111
|
-
display: flex;
|
|
112
|
-
align-items: center;
|
|
113
|
-
gap: 8px;
|
|
114
|
-
}
|
|
115
|
-
`,
|
|
77
|
+
css ``,
|
|
116
78
|
];
|
|
117
79
|
render() {
|
|
118
80
|
return html `
|
|
119
81
|
<ops-sectionheading>Logs</ops-sectionheading>
|
|
120
82
|
|
|
121
|
-
<div class="controls">
|
|
122
|
-
<div class="filterGroup">
|
|
123
|
-
<dees-button
|
|
124
|
-
@click=${() => this.fetchLogs()}
|
|
125
|
-
>
|
|
126
|
-
Refresh Logs
|
|
127
|
-
</dees-button>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
<div class="filterGroup">
|
|
131
|
-
<label>Level:</label>
|
|
132
|
-
<dees-input-dropdown
|
|
133
|
-
.options=${['all', 'debug', 'info', 'warn', 'error']}
|
|
134
|
-
.selectedOption=${'all'}
|
|
135
|
-
@selectedOption=${(e) => this.updateFilter('level', e.detail)}
|
|
136
|
-
></dees-input-dropdown>
|
|
137
|
-
</div>
|
|
138
|
-
|
|
139
|
-
<div class="filterGroup">
|
|
140
|
-
<label>Category:</label>
|
|
141
|
-
<dees-input-dropdown
|
|
142
|
-
.options=${['all', 'smtp', 'dns', 'security', 'system', 'email']}
|
|
143
|
-
.selectedOption=${'all'}
|
|
144
|
-
@selectedOption=${(e) => this.updateFilter('category', e.detail)}
|
|
145
|
-
></dees-input-dropdown>
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
|
-
<div class="filterGroup">
|
|
149
|
-
<label>Limit:</label>
|
|
150
|
-
<dees-input-dropdown
|
|
151
|
-
.options=${['50', '100', '200', '500']}
|
|
152
|
-
.selectedOption=${'100'}
|
|
153
|
-
@selectedOption=${(e) => this.updateFilter('limit', e.detail)}
|
|
154
|
-
></dees-input-dropdown>
|
|
155
|
-
</div>
|
|
156
|
-
</div>
|
|
157
|
-
|
|
158
83
|
<dees-chart-log
|
|
159
84
|
.label=${'Application Logs'}
|
|
160
85
|
.autoScroll=${true}
|
|
@@ -168,7 +93,7 @@ let OpsViewLogs = (() => {
|
|
|
168
93
|
this.lastPushedCount = 0;
|
|
169
94
|
// Only fetch if state is empty (streaming will handle new entries)
|
|
170
95
|
if (this.logState.recentLogs.length === 0) {
|
|
171
|
-
|
|
96
|
+
await appstate.logStatePart.dispatchAction(appstate.fetchRecentLogsAction, { limit: 100 });
|
|
172
97
|
}
|
|
173
98
|
}
|
|
174
99
|
async updated(changedProperties) {
|
|
@@ -217,28 +142,6 @@ let OpsViewLogs = (() => {
|
|
|
217
142
|
source: log.category,
|
|
218
143
|
}));
|
|
219
144
|
}
|
|
220
|
-
async fetchLogs() {
|
|
221
|
-
await appstate.logStatePart.dispatchAction(appstate.fetchRecentLogsAction, {
|
|
222
|
-
limit: this.filterLimit,
|
|
223
|
-
level: this.filterLevel,
|
|
224
|
-
category: this.filterCategory,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
updateFilter(type, value) {
|
|
228
|
-
const resolved = value === 'all' ? undefined : value;
|
|
229
|
-
switch (type) {
|
|
230
|
-
case 'level':
|
|
231
|
-
this.filterLevel = resolved;
|
|
232
|
-
break;
|
|
233
|
-
case 'category':
|
|
234
|
-
this.filterCategory = resolved;
|
|
235
|
-
break;
|
|
236
|
-
case 'limit':
|
|
237
|
-
this.filterLimit = resolved ? parseInt(resolved, 10) : 100;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
this.fetchLogs();
|
|
241
|
-
}
|
|
242
145
|
static {
|
|
243
146
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
244
147
|
}
|
|
@@ -246,4 +149,4 @@ let OpsViewLogs = (() => {
|
|
|
246
149
|
return OpsViewLogs = _classThis;
|
|
247
150
|
})();
|
|
248
151
|
export { OpsViewLogs };
|
|
249
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
152
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctbG9ncy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9lbGVtZW50cy9vcHMtdmlldy1sb2dzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEtBQUssTUFBTSxNQUFNLG1CQUFtQixDQUFDO0FBQzVDLE9BQU8sS0FBSyxRQUFRLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsT0FBTyxFQUNMLFdBQVcsRUFDWCxhQUFhLEVBQ2IsSUFBSSxFQUNKLEtBQUssRUFDTCxHQUFHLEVBQ0gsVUFBVSxHQUNYLE1BQU0sNkJBQTZCLENBQUM7SUFHeEIsV0FBVzs0QkFEdkIsYUFBYSxDQUFDLGVBQWUsQ0FBQzs7OztzQkFDRSxXQUFXOzs7OzJCQUFuQixTQUFRLFdBQVc7Ozs7b0NBQ3pDLEtBQUssRUFBRTtZQUNSLDZLQUFTLFFBQVEsNkJBQVIsUUFBUSwyRkFJZjtZQU5KLDZLQStGQzs7OztRQTdGQyw2RUFBd0M7WUFDdEMsVUFBVSxFQUFFLEVBQUU7WUFDZCxXQUFXLEVBQUUsS0FBSztZQUNsQixPQUFPLEVBQUUsRUFBRTtTQUNaLEVBQUM7UUFKRixJQUFTLFFBQVEsOENBSWY7UUFKRixJQUFTLFFBQVEsb0RBSWY7UUFFTSxlQUFlLDBEQUFHLENBQUMsRUFBQztRQUU1QjtZQUNFLEtBQUssRUFBRSxDQUFDO1lBQ1IsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLFlBQVk7aUJBQ3ZDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDO2lCQUM5QixTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDdEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7WUFDTCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMxQyxDQUFDO1FBRU0s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
|
package/dist_ts_web/plugins.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as deesElement from '@design.estate/dees-element';
|
|
2
2
|
import * as deesCatalog from '@design.estate/dees-catalog';
|
|
3
|
+
import * as szCatalog from '@serve.zone/catalog';
|
|
3
4
|
import * as typedsocket from '@api.global/typedsocket';
|
|
4
|
-
export { deesElement, deesCatalog, typedsocket, };
|
|
5
|
+
export { deesElement, deesCatalog, szCatalog, typedsocket, };
|
|
5
6
|
export declare const domtools: typeof deesElement.domtools;
|
package/dist_ts_web/plugins.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// @design.estate scope
|
|
2
2
|
import * as deesElement from '@design.estate/dees-element';
|
|
3
3
|
import * as deesCatalog from '@design.estate/dees-catalog';
|
|
4
|
+
// @serve.zone scope
|
|
5
|
+
import * as szCatalog from '@serve.zone/catalog';
|
|
4
6
|
// TypedSocket for real-time push communication
|
|
5
7
|
import * as typedsocket from '@api.global/typedsocket';
|
|
6
|
-
export { deesElement, deesCatalog, typedsocket, };
|
|
8
|
+
export { deesElement, deesCatalog, szCatalog, typedsocket, };
|
|
7
9
|
// domtools gives us TypedRequest and other utilities
|
|
8
10
|
export const domtools = deesElement.domtools;
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3dlYi9wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVCQUF1QjtBQUN2QixPQUFPLEtBQUssV0FBVyxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sS0FBSyxXQUFXLE1BQU0sNkJBQTZCLENBQUM7QUFFM0Qsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxTQUFTLE1BQU0scUJBQXFCLENBQUM7QUFFakQsK0NBQStDO0FBQy9DLE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFFdkQsT0FBTyxFQUNMLFdBQVcsRUFDWCxXQUFXLEVBQ1gsU0FBUyxFQUNULFdBQVcsR0FDWixDQUFBO0FBRUQscURBQXFEO0FBQ3JELE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDIn0=
|
package/dist_ts_web/router.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export declare const validViews: readonly ["overview", "network", "emails", "logs", "configuration", "security", "certificates", "remoteingress"];
|
|
2
|
-
export declare const validEmailFolders: readonly ["queued", "sent", "failed", "security"];
|
|
3
2
|
export type TValidView = typeof validViews[number];
|
|
4
|
-
export type TValidEmailFolder = typeof validEmailFolders[number];
|
|
5
3
|
declare class AppRouter {
|
|
6
4
|
private router;
|
|
7
5
|
private initialized;
|
|
@@ -10,15 +8,11 @@ declare class AppRouter {
|
|
|
10
8
|
init(): void;
|
|
11
9
|
private setupRoutes;
|
|
12
10
|
private setupStateSync;
|
|
13
|
-
private getExpectedPath;
|
|
14
11
|
private handleInitialRoute;
|
|
15
12
|
private updateViewState;
|
|
16
|
-
private updateEmailFolder;
|
|
17
13
|
navigateTo(path: string): void;
|
|
18
14
|
navigateToView(view: string): void;
|
|
19
|
-
navigateToEmailFolder(folder: string): void;
|
|
20
15
|
getCurrentView(): string;
|
|
21
|
-
getCurrentEmailFolder(): string;
|
|
22
16
|
destroy(): void;
|
|
23
17
|
}
|
|
24
18
|
export declare const appRouter: AppRouter;
|
package/dist_ts_web/router.js
CHANGED
|
@@ -2,7 +2,6 @@ import * as plugins from './plugins.js';
|
|
|
2
2
|
import * as appstate from './appstate.js';
|
|
3
3
|
const SmartRouter = plugins.domtools.plugins.smartrouter.SmartRouter;
|
|
4
4
|
export const validViews = ['overview', 'network', 'emails', 'logs', 'configuration', 'security', 'certificates', 'remoteingress'];
|
|
5
|
-
export const validEmailFolders = ['queued', 'sent', 'failed', 'security'];
|
|
6
5
|
class AppRouter {
|
|
7
6
|
router;
|
|
8
7
|
initialized = false;
|
|
@@ -19,32 +18,10 @@ class AppRouter {
|
|
|
19
18
|
this.initialized = true;
|
|
20
19
|
}
|
|
21
20
|
setupRoutes() {
|
|
22
|
-
// Main views
|
|
23
21
|
for (const view of validViews) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.updateViewState('emails');
|
|
28
|
-
this.updateEmailFolder('queued');
|
|
29
|
-
});
|
|
30
|
-
// Email with folder parameter
|
|
31
|
-
this.router.on('/emails/:folder', async (routeInfo) => {
|
|
32
|
-
const folder = routeInfo.params.folder;
|
|
33
|
-
if (validEmailFolders.includes(folder)) {
|
|
34
|
-
this.updateViewState('emails');
|
|
35
|
-
this.updateEmailFolder(folder);
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
// Invalid folder, redirect to queued
|
|
39
|
-
this.navigateTo('/emails/queued');
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
this.router.on(`/${view}`, async () => {
|
|
45
|
-
this.updateViewState(view);
|
|
46
|
-
});
|
|
47
|
-
}
|
|
22
|
+
this.router.on(`/${view}`, async () => {
|
|
23
|
+
this.updateViewState(view);
|
|
24
|
+
});
|
|
48
25
|
}
|
|
49
26
|
// Root redirect
|
|
50
27
|
this.router.on('/', async () => {
|
|
@@ -52,59 +29,30 @@ class AppRouter {
|
|
|
52
29
|
});
|
|
53
30
|
}
|
|
54
31
|
setupStateSync() {
|
|
55
|
-
// Sync URL when state changes programmatically (not from router)
|
|
56
32
|
appstate.uiStatePart.state.subscribe((uiState) => {
|
|
57
33
|
if (this.suppressStateUpdate)
|
|
58
34
|
return;
|
|
59
35
|
const currentPath = window.location.pathname;
|
|
60
|
-
const expectedPath =
|
|
61
|
-
|
|
62
|
-
if (!currentPath.startsWith(expectedPath)) {
|
|
36
|
+
const expectedPath = `/${uiState.activeView}`;
|
|
37
|
+
if (currentPath !== expectedPath) {
|
|
63
38
|
this.suppressStateUpdate = true;
|
|
64
|
-
|
|
65
|
-
const emailState = appstate.emailOpsStatePart.getState();
|
|
66
|
-
this.router.pushUrl(`/emails/${emailState.currentView}`);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
this.router.pushUrl(`/${uiState.activeView}`);
|
|
70
|
-
}
|
|
39
|
+
this.router.pushUrl(expectedPath);
|
|
71
40
|
this.suppressStateUpdate = false;
|
|
72
41
|
}
|
|
73
42
|
});
|
|
74
43
|
}
|
|
75
|
-
getExpectedPath(view) {
|
|
76
|
-
if (view === 'emails') {
|
|
77
|
-
return '/emails';
|
|
78
|
-
}
|
|
79
|
-
return `/${view}`;
|
|
80
|
-
}
|
|
81
44
|
handleInitialRoute() {
|
|
82
45
|
const path = window.location.pathname;
|
|
83
46
|
if (!path || path === '/') {
|
|
84
|
-
// Redirect root to overview
|
|
85
47
|
this.router.pushUrl('/overview');
|
|
86
48
|
}
|
|
87
49
|
else {
|
|
88
|
-
// Parse current path and update state
|
|
89
50
|
const segments = path.split('/').filter(Boolean);
|
|
90
51
|
const view = segments[0];
|
|
91
52
|
if (validViews.includes(view)) {
|
|
92
53
|
this.updateViewState(view);
|
|
93
|
-
if (view === 'emails' && segments[1]) {
|
|
94
|
-
const folder = segments[1];
|
|
95
|
-
if (validEmailFolders.includes(folder)) {
|
|
96
|
-
this.updateEmailFolder(folder);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
this.updateEmailFolder('queued');
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
else if (view === 'emails') {
|
|
103
|
-
this.updateEmailFolder('queued');
|
|
104
|
-
}
|
|
105
54
|
}
|
|
106
55
|
else {
|
|
107
|
-
// Invalid view, redirect to overview
|
|
108
56
|
this.router.pushUrl('/overview');
|
|
109
57
|
}
|
|
110
58
|
}
|
|
@@ -120,17 +68,6 @@ class AppRouter {
|
|
|
120
68
|
}
|
|
121
69
|
this.suppressStateUpdate = false;
|
|
122
70
|
}
|
|
123
|
-
updateEmailFolder(folder) {
|
|
124
|
-
this.suppressStateUpdate = true;
|
|
125
|
-
const currentState = appstate.emailOpsStatePart.getState();
|
|
126
|
-
if (currentState.currentView !== folder) {
|
|
127
|
-
appstate.emailOpsStatePart.setState({
|
|
128
|
-
...currentState,
|
|
129
|
-
currentView: folder,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
this.suppressStateUpdate = false;
|
|
133
|
-
}
|
|
134
71
|
navigateTo(path) {
|
|
135
72
|
this.router.pushUrl(path);
|
|
136
73
|
}
|
|
@@ -142,24 +79,13 @@ class AppRouter {
|
|
|
142
79
|
this.navigateTo('/overview');
|
|
143
80
|
}
|
|
144
81
|
}
|
|
145
|
-
navigateToEmailFolder(folder) {
|
|
146
|
-
if (validEmailFolders.includes(folder)) {
|
|
147
|
-
this.navigateTo(`/emails/${folder}`);
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
this.navigateTo('/emails/queued');
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
82
|
getCurrentView() {
|
|
154
83
|
return appstate.uiStatePart.getState().activeView;
|
|
155
84
|
}
|
|
156
|
-
getCurrentEmailFolder() {
|
|
157
|
-
return appstate.emailOpsStatePart.getState().currentView;
|
|
158
|
-
}
|
|
159
85
|
destroy() {
|
|
160
86
|
this.router.destroy();
|
|
161
87
|
this.initialized = false;
|
|
162
88
|
}
|
|
163
89
|
}
|
|
164
90
|
export const appRouter = new AppRouter();
|
|
165
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
91
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssUUFBUSxNQUFNLGVBQWUsQ0FBQztBQUUxQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0FBRXJFLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxlQUFlLENBQVUsQ0FBQztBQUkzSSxNQUFNLFNBQVM7SUFDTCxNQUFNLENBQW1DO0lBQ3pDLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsbUJBQW1CLEdBQUcsS0FBSyxDQUFDO0lBRXBDO1FBQ0UsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLFdBQVcsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFTSxJQUFJO1FBQ1QsSUFBSSxJQUFJLENBQUMsV0FBVztZQUFFLE9BQU87UUFDN0IsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztJQUMxQixDQUFDO0lBRU8sV0FBVztRQUNqQixLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxFQUFFLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ3BDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFD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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": "
|
|
4
|
+
"version": "8.0.0",
|
|
5
5
|
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@api.global/typedserver": "^8.3.0",
|
|
33
33
|
"@api.global/typedsocket": "^4.1.0",
|
|
34
34
|
"@apiclient.xyz/cloudflare": "^7.1.0",
|
|
35
|
-
"@design.estate/dees-catalog": "^3.43.
|
|
35
|
+
"@design.estate/dees-catalog": "^3.43.2",
|
|
36
36
|
"@design.estate/dees-element": "^2.1.6",
|
|
37
37
|
"@push.rocks/projectinfo": "^5.0.2",
|
|
38
38
|
"@push.rocks/qenv": "^6.1.3",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"@push.rocks/smartrx": "^3.0.10",
|
|
56
56
|
"@push.rocks/smartstate": "^2.0.30",
|
|
57
57
|
"@push.rocks/smartunique": "^3.0.9",
|
|
58
|
+
"@serve.zone/catalog": "^2.2.0",
|
|
58
59
|
"@serve.zone/interfaces": "^5.3.0",
|
|
59
60
|
"@serve.zone/remoteingress": "^4.0.0",
|
|
60
61
|
"@tsclass/tsclass": "^9.3.0",
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/classes.dcrouter.ts
CHANGED
|
@@ -212,6 +212,11 @@ export class DcRouter {
|
|
|
212
212
|
public remoteIngressManager?: RemoteIngressManager;
|
|
213
213
|
public tunnelManager?: TunnelManager;
|
|
214
214
|
|
|
215
|
+
// DNS query logging rate limiter state
|
|
216
|
+
private dnsLogWindow: number[] = [];
|
|
217
|
+
private dnsBatchCount: number = 0;
|
|
218
|
+
private dnsBatchTimer: ReturnType<typeof setTimeout> | null = null;
|
|
219
|
+
|
|
215
220
|
// Certificate status tracking from SmartProxy events (keyed by domain)
|
|
216
221
|
public certificateStatusMap = new Map<string, {
|
|
217
222
|
status: 'valid' | 'failed';
|
|
@@ -855,6 +860,17 @@ export class DcRouter {
|
|
|
855
860
|
public async stop() {
|
|
856
861
|
logger.log('info', 'Stopping DcRouter services...');
|
|
857
862
|
|
|
863
|
+
// Flush pending DNS batch log
|
|
864
|
+
if (this.dnsBatchTimer) {
|
|
865
|
+
clearTimeout(this.dnsBatchTimer);
|
|
866
|
+
if (this.dnsBatchCount > 0) {
|
|
867
|
+
logger.log('info', `DNS: ${this.dnsBatchCount} queries processed (rate limited, final flush)`, { zone: 'dns' });
|
|
868
|
+
}
|
|
869
|
+
this.dnsBatchTimer = null;
|
|
870
|
+
this.dnsBatchCount = 0;
|
|
871
|
+
this.dnsLogWindow = [];
|
|
872
|
+
}
|
|
873
|
+
|
|
858
874
|
await this.opsServer.stop();
|
|
859
875
|
|
|
860
876
|
try {
|
|
@@ -1002,21 +1018,25 @@ export class DcRouter {
|
|
|
1002
1018
|
// Start the server
|
|
1003
1019
|
await this.emailServer.start();
|
|
1004
1020
|
|
|
1005
|
-
// Wire delivery events to MetricsManager
|
|
1021
|
+
// Wire delivery events to MetricsManager and logger
|
|
1006
1022
|
if (this.metricsManager && this.emailServer.deliverySystem) {
|
|
1007
1023
|
this.emailServer.deliverySystem.on('deliveryStart', (item: any) => {
|
|
1008
1024
|
this.metricsManager.trackEmailReceived(item?.from);
|
|
1025
|
+
logger.log('info', `Email delivery started: ${item?.from} → ${item?.to}`, { zone: 'email' });
|
|
1009
1026
|
});
|
|
1010
1027
|
this.emailServer.deliverySystem.on('deliverySuccess', (item: any) => {
|
|
1011
1028
|
this.metricsManager.trackEmailSent(item?.to);
|
|
1029
|
+
logger.log('info', `Email delivered to ${item?.to}`, { zone: 'email' });
|
|
1012
1030
|
});
|
|
1013
1031
|
this.emailServer.deliverySystem.on('deliveryFailed', (item: any, error: any) => {
|
|
1014
1032
|
this.metricsManager.trackEmailFailed(item?.to, error?.message);
|
|
1033
|
+
logger.log('warn', `Email delivery failed to ${item?.to}: ${error?.message}`, { zone: 'email' });
|
|
1015
1034
|
});
|
|
1016
1035
|
}
|
|
1017
1036
|
if (this.metricsManager && this.emailServer) {
|
|
1018
1037
|
this.emailServer.on('bounceProcessed', () => {
|
|
1019
1038
|
this.metricsManager.trackEmailBounced();
|
|
1039
|
+
logger.log('warn', 'Email bounce processed', { zone: 'email' });
|
|
1020
1040
|
});
|
|
1021
1041
|
}
|
|
1022
1042
|
|
|
@@ -1203,9 +1223,18 @@ export class DcRouter {
|
|
|
1203
1223
|
await this.dnsServer.start();
|
|
1204
1224
|
logger.log('info', `DNS server started on UDP ${vmIpAddress}:53`);
|
|
1205
1225
|
|
|
1206
|
-
// Wire DNS query events to MetricsManager
|
|
1226
|
+
// Wire DNS query events to MetricsManager and logger with adaptive rate limiting
|
|
1207
1227
|
if (this.metricsManager && this.dnsServer) {
|
|
1228
|
+
const flushDnsBatch = () => {
|
|
1229
|
+
if (this.dnsBatchCount > 0) {
|
|
1230
|
+
logger.log('info', `DNS: ${this.dnsBatchCount} queries processed (rate limited)`, { zone: 'dns' });
|
|
1231
|
+
this.dnsBatchCount = 0;
|
|
1232
|
+
}
|
|
1233
|
+
this.dnsBatchTimer = null;
|
|
1234
|
+
};
|
|
1235
|
+
|
|
1208
1236
|
this.dnsServer.on('query', (event: plugins.smartdns.dnsServerMod.IDnsQueryCompletedEvent) => {
|
|
1237
|
+
// Metrics tracking
|
|
1209
1238
|
for (const question of event.questions) {
|
|
1210
1239
|
this.metricsManager.trackDnsQuery(
|
|
1211
1240
|
question.type,
|
|
@@ -1215,6 +1244,21 @@ export class DcRouter {
|
|
|
1215
1244
|
event.answered,
|
|
1216
1245
|
);
|
|
1217
1246
|
}
|
|
1247
|
+
|
|
1248
|
+
// Adaptive logging: individual logs up to 2/sec, then batch
|
|
1249
|
+
const now = Date.now();
|
|
1250
|
+
this.dnsLogWindow = this.dnsLogWindow.filter(t => now - t < 1000);
|
|
1251
|
+
|
|
1252
|
+
if (this.dnsLogWindow.length < 2) {
|
|
1253
|
+
this.dnsLogWindow.push(now);
|
|
1254
|
+
const summary = event.questions.map(q => `${q.type} ${q.name}`).join(', ');
|
|
1255
|
+
logger.log('info', `DNS query: ${summary} (${event.responseTimeMs}ms, ${event.answered ? 'answered' : 'unanswered'})`, { zone: 'dns' });
|
|
1256
|
+
} else {
|
|
1257
|
+
this.dnsBatchCount++;
|
|
1258
|
+
if (!this.dnsBatchTimer) {
|
|
1259
|
+
this.dnsBatchTimer = setTimeout(flushDnsBatch, 5000);
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1218
1262
|
});
|
|
1219
1263
|
}
|
|
1220
1264
|
|