@serve.zone/dcrouter 11.10.4 → 11.10.7
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 +5102 -5102
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/cache/classes.cache.cleaner.js +1 -1
- package/dist_ts/cache/classes.cached.document.js +1 -1
- package/dist_ts/cache/classes.cachedb.js +1 -1
- package/dist_ts/cache/documents/classes.cached.email.js +1 -1
- package/dist_ts/cache/documents/classes.cached.ip.reputation.js +1 -1
- package/dist_ts/classes.dcrouter.js +3 -3
- package/dist_ts/config/classes.route-config-manager.d.ts +1 -1
- package/dist_ts/config/validator.js +1 -1
- package/dist_ts/errors/base.errors.js +2 -2
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +6 -1
- package/dist_ts/monitoring/classes.metricsmanager.js +1 -1
- package/dist_ts/opsserver/classes.opsserver.js +2 -2
- package/dist_ts/opsserver/handlers/admin.handler.js +1 -1
- package/dist_ts/opsserver/handlers/certificate.handler.js +1 -1
- package/dist_ts/opsserver/handlers/radius.handler.js +1 -1
- package/dist_ts/opsserver/handlers/stats.handler.js +1 -1
- package/dist_ts/radius/classes.accounting.manager.js +1 -1
- package/dist_ts/radius/classes.radius.server.js +1 -1
- package/dist_ts/radius/classes.vlan.manager.js +1 -1
- package/dist_ts/security/classes.contentscanner.js +3 -3
- package/dist_ts/security/classes.ipreputationchecker.js +4 -4
- package/dist_ts/security/classes.securitylogger.js +5 -3
- package/dist_ts/sms/classes.smsservice.js +2 -2
- package/dist_ts/storage/classes.storagemanager.d.ts +1 -1
- package/dist_ts/storage/classes.storagemanager.js +2 -4
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.js +9 -6
- package/dist_ts_web/elements/ops-dashboard.js +3 -2
- package/dist_ts_web/elements/ops-view-certificates.js +1 -1
- package/dist_ts_web/elements/ops-view-config.js +1 -1
- package/dist_ts_web/elements/ops-view-emails.js +1 -1
- package/dist_ts_web/elements/ops-view-network.js +1 -1
- package/dist_ts_web/elements/ops-view-remoteingress.js +1 -1
- package/dist_ts_web/router.js +1 -1
- package/license +21 -0
- package/package.json +15 -15
- package/readme.hints.md +1 -1
- package/readme.md +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/cache/classes.cache.cleaner.ts +10 -10
- package/ts/cache/classes.cached.document.ts +1 -1
- package/ts/cache/classes.cachedb.ts +6 -6
- package/ts/cache/documents/classes.cached.email.ts +14 -14
- package/ts/cache/documents/classes.cached.ip.reputation.ts +10 -10
- package/ts/classes.dcrouter.ts +31 -31
- package/ts/config/validator.ts +5 -5
- package/ts/errors/base.errors.ts +1 -1
- package/ts/monitoring/classes.metricsmanager.ts +3 -3
- package/ts/opsserver/classes.opsserver.ts +13 -13
- package/ts/opsserver/handlers/admin.handler.ts +1 -1
- package/ts/opsserver/handlers/certificate.handler.ts +6 -6
- package/ts/opsserver/handlers/radius.handler.ts +4 -4
- package/ts/opsserver/handlers/stats.handler.ts +1 -1
- package/ts/radius/classes.accounting.manager.ts +10 -10
- package/ts/radius/classes.radius.server.ts +2 -2
- package/ts/radius/classes.vlan.manager.ts +5 -5
- package/ts/readme.md +1 -1
- package/ts/security/classes.contentscanner.ts +12 -12
- package/ts/security/classes.ipreputationchecker.ts +26 -26
- package/ts/security/classes.securitylogger.ts +6 -4
- package/ts/sms/classes.smsservice.ts +3 -3
- package/ts/storage/classes.storagemanager.ts +23 -25
- package/ts_apiclient/readme.md +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +136 -133
- package/ts_web/elements/ops-dashboard.ts +15 -14
- package/ts_web/elements/ops-view-certificates.ts +10 -10
- package/ts_web/elements/ops-view-config.ts +8 -8
- package/ts_web/elements/ops-view-emails.ts +2 -2
- package/ts_web/elements/ops-view-network.ts +2 -2
- package/ts_web/elements/ops-view-remoteingress.ts +6 -6
- package/ts_web/readme.md +1 -1
- package/ts_web/router.ts +3 -3
- /package/{npmextra.json → .smartconfig.json} +0 -0
package/ts_web/appstate.ts
CHANGED
|
@@ -240,7 +240,7 @@ interface IActionContext {
|
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
const getActionContext = (): IActionContext => {
|
|
243
|
-
const identity = loginStatePart.getState()
|
|
243
|
+
const identity = loginStatePart.getState()!.identity;
|
|
244
244
|
// Treat expired JWTs as no identity — prevents stale persisted sessions from firing requests
|
|
245
245
|
if (identity && identity.expiresAt && identity.expiresAt < Date.now()) {
|
|
246
246
|
return { identity: null };
|
|
@@ -252,7 +252,7 @@ const getActionContext = (): IActionContext => {
|
|
|
252
252
|
export const loginAction = loginStatePart.createAction<{
|
|
253
253
|
username: string;
|
|
254
254
|
password: string;
|
|
255
|
-
}>(async (statePartArg, dataArg) => {
|
|
255
|
+
}>(async (statePartArg, dataArg): Promise<ILoginState> => {
|
|
256
256
|
const typedRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
257
257
|
interfaces.requests.IReq_AdminLoginWithUsernameAndPassword
|
|
258
258
|
>('/typedrequest', 'adminLoginWithUsernameAndPassword');
|
|
@@ -269,10 +269,10 @@ export const loginAction = loginStatePart.createAction<{
|
|
|
269
269
|
isLoggedIn: true,
|
|
270
270
|
};
|
|
271
271
|
}
|
|
272
|
-
return statePartArg.getState()
|
|
273
|
-
} catch (error) {
|
|
272
|
+
return statePartArg.getState()!;
|
|
273
|
+
} catch (error: unknown) {
|
|
274
274
|
console.error('Login failed:', error);
|
|
275
|
-
return statePartArg.getState()
|
|
275
|
+
return statePartArg.getState()!;
|
|
276
276
|
}
|
|
277
277
|
});
|
|
278
278
|
|
|
@@ -300,9 +300,9 @@ export const logoutAction = loginStatePart.createAction(async (statePartArg) =>
|
|
|
300
300
|
});
|
|
301
301
|
|
|
302
302
|
// Fetch All Stats Action - Using combined endpoint for efficiency
|
|
303
|
-
export const fetchAllStatsAction = statsStatePart.createAction(async (statePartArg) => {
|
|
303
|
+
export const fetchAllStatsAction = statsStatePart.createAction(async (statePartArg): Promise<IStatsState> => {
|
|
304
304
|
const context = getActionContext();
|
|
305
|
-
const currentState = statePartArg.getState()
|
|
305
|
+
const currentState = statePartArg.getState()!;
|
|
306
306
|
if (!context.identity) return currentState;
|
|
307
307
|
|
|
308
308
|
try {
|
|
@@ -310,7 +310,7 @@ export const fetchAllStatsAction = statsStatePart.createAction(async (statePartA
|
|
|
310
310
|
const combinedRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
311
311
|
interfaces.requests.IReq_GetCombinedMetrics
|
|
312
312
|
>('/typedrequest', 'getCombinedMetrics');
|
|
313
|
-
|
|
313
|
+
|
|
314
314
|
const combinedResponse = await combinedRequest.fire({
|
|
315
315
|
identity: context.identity,
|
|
316
316
|
sections: {
|
|
@@ -332,19 +332,19 @@ export const fetchAllStatsAction = statsStatePart.createAction(async (statePartA
|
|
|
332
332
|
isLoading: false,
|
|
333
333
|
error: null,
|
|
334
334
|
};
|
|
335
|
-
} catch (error) {
|
|
335
|
+
} catch (error: unknown) {
|
|
336
336
|
return {
|
|
337
337
|
...currentState,
|
|
338
338
|
isLoading: false,
|
|
339
|
-
error: error.message || 'Failed to fetch statistics',
|
|
339
|
+
error: (error as Error).message || 'Failed to fetch statistics',
|
|
340
340
|
};
|
|
341
341
|
}
|
|
342
342
|
});
|
|
343
343
|
|
|
344
344
|
// Fetch Configuration Action (read-only)
|
|
345
|
-
export const fetchConfigurationAction = configStatePart.createAction(async (statePartArg) => {
|
|
345
|
+
export const fetchConfigurationAction = configStatePart.createAction(async (statePartArg): Promise<IConfigState> => {
|
|
346
346
|
const context = getActionContext();
|
|
347
|
-
const currentState = statePartArg.getState()
|
|
347
|
+
const currentState = statePartArg.getState()!;
|
|
348
348
|
if (!context.identity) return currentState;
|
|
349
349
|
|
|
350
350
|
try {
|
|
@@ -361,11 +361,11 @@ export const fetchConfigurationAction = configStatePart.createAction(async (stat
|
|
|
361
361
|
isLoading: false,
|
|
362
362
|
error: null,
|
|
363
363
|
};
|
|
364
|
-
} catch (error) {
|
|
364
|
+
} catch (error: unknown) {
|
|
365
365
|
return {
|
|
366
366
|
...currentState,
|
|
367
367
|
isLoading: false,
|
|
368
|
-
error: error.message || 'Failed to fetch configuration',
|
|
368
|
+
error: (error as Error).message || 'Failed to fetch configuration',
|
|
369
369
|
};
|
|
370
370
|
}
|
|
371
371
|
});
|
|
@@ -375,9 +375,9 @@ export const fetchRecentLogsAction = logStatePart.createAction<{
|
|
|
375
375
|
limit?: number;
|
|
376
376
|
level?: 'debug' | 'info' | 'warn' | 'error';
|
|
377
377
|
category?: 'smtp' | 'dns' | 'security' | 'system' | 'email';
|
|
378
|
-
}>(async (statePartArg, dataArg) => {
|
|
378
|
+
}>(async (statePartArg, dataArg): Promise<ILogState> => {
|
|
379
379
|
const context = getActionContext();
|
|
380
|
-
if (!context.identity) return statePartArg.getState()
|
|
380
|
+
if (!context.identity) return statePartArg.getState()!;
|
|
381
381
|
|
|
382
382
|
const logsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
383
383
|
interfaces.requests.IReq_GetRecentLogs
|
|
@@ -391,14 +391,14 @@ export const fetchRecentLogsAction = logStatePart.createAction<{
|
|
|
391
391
|
});
|
|
392
392
|
|
|
393
393
|
return {
|
|
394
|
-
...statePartArg.getState()
|
|
394
|
+
...statePartArg.getState()!,
|
|
395
395
|
recentLogs: response.logs,
|
|
396
396
|
};
|
|
397
397
|
});
|
|
398
398
|
|
|
399
399
|
// Toggle Auto Refresh Action
|
|
400
|
-
export const toggleAutoRefreshAction = uiStatePart.createAction(async (statePartArg) => {
|
|
401
|
-
const currentState = statePartArg.getState()
|
|
400
|
+
export const toggleAutoRefreshAction = uiStatePart.createAction(async (statePartArg): Promise<IUiState> => {
|
|
401
|
+
const currentState = statePartArg.getState()!;
|
|
402
402
|
return {
|
|
403
403
|
...currentState,
|
|
404
404
|
autoRefresh: !currentState.autoRefresh,
|
|
@@ -406,9 +406,9 @@ export const toggleAutoRefreshAction = uiStatePart.createAction(async (statePart
|
|
|
406
406
|
});
|
|
407
407
|
|
|
408
408
|
// Set Active View Action
|
|
409
|
-
export const setActiveViewAction = uiStatePart.createAction<string>(async (statePartArg, viewName) => {
|
|
410
|
-
const currentState = statePartArg.getState()
|
|
411
|
-
|
|
409
|
+
export const setActiveViewAction = uiStatePart.createAction<string>(async (statePartArg, viewName): Promise<IUiState> => {
|
|
410
|
+
const currentState = statePartArg.getState()!;
|
|
411
|
+
|
|
412
412
|
// If switching to network view, ensure we fetch network data
|
|
413
413
|
if (viewName === 'network' && currentState.activeView !== 'network') {
|
|
414
414
|
setTimeout(() => {
|
|
@@ -451,9 +451,9 @@ export const setActiveViewAction = uiStatePart.createAction<string>(async (state
|
|
|
451
451
|
});
|
|
452
452
|
|
|
453
453
|
// Fetch Network Stats Action
|
|
454
|
-
export const fetchNetworkStatsAction = networkStatePart.createAction(async (statePartArg) => {
|
|
454
|
+
export const fetchNetworkStatsAction = networkStatePart.createAction(async (statePartArg): Promise<INetworkState> => {
|
|
455
455
|
const context = getActionContext();
|
|
456
|
-
const currentState = statePartArg.getState()
|
|
456
|
+
const currentState = statePartArg.getState()!;
|
|
457
457
|
if (!context.identity) return currentState;
|
|
458
458
|
|
|
459
459
|
try {
|
|
@@ -525,9 +525,9 @@ export const fetchNetworkStatsAction = networkStatePart.createAction(async (stat
|
|
|
525
525
|
// ============================================================================
|
|
526
526
|
|
|
527
527
|
// Fetch All Emails Action
|
|
528
|
-
export const fetchAllEmailsAction = emailOpsStatePart.createAction(async (statePartArg) => {
|
|
528
|
+
export const fetchAllEmailsAction = emailOpsStatePart.createAction(async (statePartArg): Promise<IEmailOpsState> => {
|
|
529
529
|
const context = getActionContext();
|
|
530
|
-
const currentState = statePartArg.getState()
|
|
530
|
+
const currentState = statePartArg.getState()!;
|
|
531
531
|
if (!context.identity) return currentState;
|
|
532
532
|
|
|
533
533
|
try {
|
|
@@ -558,9 +558,9 @@ export const fetchAllEmailsAction = emailOpsStatePart.createAction(async (stateP
|
|
|
558
558
|
// Certificate Actions
|
|
559
559
|
// ============================================================================
|
|
560
560
|
|
|
561
|
-
export const fetchCertificateOverviewAction = certificateStatePart.createAction(async (statePartArg) => {
|
|
561
|
+
export const fetchCertificateOverviewAction = certificateStatePart.createAction(async (statePartArg): Promise<ICertificateState> => {
|
|
562
562
|
const context = getActionContext();
|
|
563
|
-
const currentState = statePartArg.getState()
|
|
563
|
+
const currentState = statePartArg.getState()!;
|
|
564
564
|
if (!context.identity) return currentState;
|
|
565
565
|
|
|
566
566
|
try {
|
|
@@ -589,9 +589,9 @@ export const fetchCertificateOverviewAction = certificateStatePart.createAction(
|
|
|
589
589
|
});
|
|
590
590
|
|
|
591
591
|
export const reprovisionCertificateAction = certificateStatePart.createAction<string>(
|
|
592
|
-
async (statePartArg, domain, actionContext) => {
|
|
592
|
+
async (statePartArg, domain, actionContext): Promise<ICertificateState> => {
|
|
593
593
|
const context = getActionContext();
|
|
594
|
-
const currentState = statePartArg.getState()
|
|
594
|
+
const currentState = statePartArg.getState()!;
|
|
595
595
|
|
|
596
596
|
try {
|
|
597
597
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -599,13 +599,13 @@ export const reprovisionCertificateAction = certificateStatePart.createAction<st
|
|
|
599
599
|
>('/typedrequest', 'reprovisionCertificateDomain');
|
|
600
600
|
|
|
601
601
|
await request.fire({
|
|
602
|
-
identity: context.identity
|
|
602
|
+
identity: context.identity!,
|
|
603
603
|
domain,
|
|
604
604
|
});
|
|
605
605
|
|
|
606
606
|
// Re-fetch overview after reprovisioning
|
|
607
|
-
return await actionContext
|
|
608
|
-
} catch (error) {
|
|
607
|
+
return await actionContext!.dispatch(fetchCertificateOverviewAction, null);
|
|
608
|
+
} catch (error: unknown) {
|
|
609
609
|
return {
|
|
610
610
|
...currentState,
|
|
611
611
|
error: error instanceof Error ? error.message : 'Failed to reprovision certificate',
|
|
@@ -615,9 +615,9 @@ export const reprovisionCertificateAction = certificateStatePart.createAction<st
|
|
|
615
615
|
);
|
|
616
616
|
|
|
617
617
|
export const deleteCertificateAction = certificateStatePart.createAction<string>(
|
|
618
|
-
async (statePartArg, domain, actionContext) => {
|
|
618
|
+
async (statePartArg, domain, actionContext): Promise<ICertificateState> => {
|
|
619
619
|
const context = getActionContext();
|
|
620
|
-
const currentState = statePartArg.getState()
|
|
620
|
+
const currentState = statePartArg.getState()!;
|
|
621
621
|
|
|
622
622
|
try {
|
|
623
623
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -625,13 +625,13 @@ export const deleteCertificateAction = certificateStatePart.createAction<string>
|
|
|
625
625
|
>('/typedrequest', 'deleteCertificate');
|
|
626
626
|
|
|
627
627
|
await request.fire({
|
|
628
|
-
identity: context.identity
|
|
628
|
+
identity: context.identity!,
|
|
629
629
|
domain,
|
|
630
630
|
});
|
|
631
631
|
|
|
632
632
|
// Re-fetch overview after deletion
|
|
633
|
-
return await actionContext
|
|
634
|
-
} catch (error) {
|
|
633
|
+
return await actionContext!.dispatch(fetchCertificateOverviewAction, null);
|
|
634
|
+
} catch (error: unknown) {
|
|
635
635
|
return {
|
|
636
636
|
...currentState,
|
|
637
637
|
error: error instanceof Error ? error.message : 'Failed to delete certificate',
|
|
@@ -649,9 +649,9 @@ export const importCertificateAction = certificateStatePart.createAction<{
|
|
|
649
649
|
publicKey: string;
|
|
650
650
|
csr: string;
|
|
651
651
|
}>(
|
|
652
|
-
async (statePartArg, cert, actionContext) => {
|
|
652
|
+
async (statePartArg, cert, actionContext): Promise<ICertificateState> => {
|
|
653
653
|
const context = getActionContext();
|
|
654
|
-
const currentState = statePartArg.getState()
|
|
654
|
+
const currentState = statePartArg.getState()!;
|
|
655
655
|
|
|
656
656
|
try {
|
|
657
657
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -659,13 +659,13 @@ export const importCertificateAction = certificateStatePart.createAction<{
|
|
|
659
659
|
>('/typedrequest', 'importCertificate');
|
|
660
660
|
|
|
661
661
|
await request.fire({
|
|
662
|
-
identity: context.identity
|
|
662
|
+
identity: context.identity!,
|
|
663
663
|
cert,
|
|
664
664
|
});
|
|
665
665
|
|
|
666
666
|
// Re-fetch overview after import
|
|
667
|
-
return await actionContext
|
|
668
|
-
} catch (error) {
|
|
667
|
+
return await actionContext!.dispatch(fetchCertificateOverviewAction, null);
|
|
668
|
+
} catch (error: unknown) {
|
|
669
669
|
return {
|
|
670
670
|
...currentState,
|
|
671
671
|
error: error instanceof Error ? error.message : 'Failed to import certificate',
|
|
@@ -681,7 +681,7 @@ export async function fetchCertificateExport(domain: string) {
|
|
|
681
681
|
>('/typedrequest', 'exportCertificate');
|
|
682
682
|
|
|
683
683
|
return request.fire({
|
|
684
|
-
identity: context.identity
|
|
684
|
+
identity: context.identity!,
|
|
685
685
|
domain,
|
|
686
686
|
});
|
|
687
687
|
}
|
|
@@ -695,16 +695,16 @@ export async function fetchConnectionToken(edgeId: string) {
|
|
|
695
695
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
696
696
|
interfaces.requests.IReq_GetRemoteIngressConnectionToken
|
|
697
697
|
>('/typedrequest', 'getRemoteIngressConnectionToken');
|
|
698
|
-
return request.fire({ identity: context.identity
|
|
698
|
+
return request.fire({ identity: context.identity!, edgeId });
|
|
699
699
|
}
|
|
700
700
|
|
|
701
701
|
// ============================================================================
|
|
702
702
|
// Remote Ingress Actions
|
|
703
703
|
// ============================================================================
|
|
704
704
|
|
|
705
|
-
export const fetchRemoteIngressAction = remoteIngressStatePart.createAction(async (statePartArg) => {
|
|
705
|
+
export const fetchRemoteIngressAction = remoteIngressStatePart.createAction(async (statePartArg): Promise<IRemoteIngressState> => {
|
|
706
706
|
const context = getActionContext();
|
|
707
|
-
const currentState = statePartArg.getState()
|
|
707
|
+
const currentState = statePartArg.getState()!;
|
|
708
708
|
if (!context.identity) return currentState;
|
|
709
709
|
|
|
710
710
|
try {
|
|
@@ -743,9 +743,9 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
743
743
|
listenPorts?: number[];
|
|
744
744
|
autoDerivePorts?: boolean;
|
|
745
745
|
tags?: string[];
|
|
746
|
-
}>(async (statePartArg, dataArg, actionContext) => {
|
|
746
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IRemoteIngressState> => {
|
|
747
747
|
const context = getActionContext();
|
|
748
|
-
const currentState = statePartArg.getState()
|
|
748
|
+
const currentState = statePartArg.getState()!;
|
|
749
749
|
|
|
750
750
|
try {
|
|
751
751
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -753,7 +753,7 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
753
753
|
>('/typedrequest', 'createRemoteIngress');
|
|
754
754
|
|
|
755
755
|
const response = await request.fire({
|
|
756
|
-
identity: context.identity
|
|
756
|
+
identity: context.identity!,
|
|
757
757
|
name: dataArg.name,
|
|
758
758
|
listenPorts: dataArg.listenPorts,
|
|
759
759
|
autoDerivePorts: dataArg.autoDerivePorts,
|
|
@@ -762,16 +762,16 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
762
762
|
|
|
763
763
|
if (response.success) {
|
|
764
764
|
// Refresh the list
|
|
765
|
-
await actionContext
|
|
765
|
+
await actionContext!.dispatch(fetchRemoteIngressAction, null);
|
|
766
766
|
|
|
767
767
|
return {
|
|
768
|
-
...statePartArg.getState()
|
|
768
|
+
...statePartArg.getState()!,
|
|
769
769
|
newEdgeId: response.edge.id,
|
|
770
770
|
};
|
|
771
771
|
}
|
|
772
772
|
|
|
773
773
|
return currentState;
|
|
774
|
-
} catch (error) {
|
|
774
|
+
} catch (error: unknown) {
|
|
775
775
|
return {
|
|
776
776
|
...currentState,
|
|
777
777
|
error: error instanceof Error ? error.message : 'Failed to create edge',
|
|
@@ -780,9 +780,9 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
780
780
|
});
|
|
781
781
|
|
|
782
782
|
export const deleteRemoteIngressAction = remoteIngressStatePart.createAction<string>(
|
|
783
|
-
async (statePartArg, edgeId, actionContext) => {
|
|
783
|
+
async (statePartArg, edgeId, actionContext): Promise<IRemoteIngressState> => {
|
|
784
784
|
const context = getActionContext();
|
|
785
|
-
const currentState = statePartArg.getState()
|
|
785
|
+
const currentState = statePartArg.getState()!;
|
|
786
786
|
|
|
787
787
|
try {
|
|
788
788
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -790,12 +790,12 @@ export const deleteRemoteIngressAction = remoteIngressStatePart.createAction<str
|
|
|
790
790
|
>('/typedrequest', 'deleteRemoteIngress');
|
|
791
791
|
|
|
792
792
|
await request.fire({
|
|
793
|
-
identity: context.identity
|
|
793
|
+
identity: context.identity!,
|
|
794
794
|
id: edgeId,
|
|
795
795
|
});
|
|
796
796
|
|
|
797
|
-
return await actionContext
|
|
798
|
-
} catch (error) {
|
|
797
|
+
return await actionContext!.dispatch(fetchRemoteIngressAction, null);
|
|
798
|
+
} catch (error: unknown) {
|
|
799
799
|
return {
|
|
800
800
|
...currentState,
|
|
801
801
|
error: error instanceof Error ? error.message : 'Failed to delete edge',
|
|
@@ -810,9 +810,9 @@ export const updateRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
810
810
|
listenPorts?: number[];
|
|
811
811
|
autoDerivePorts?: boolean;
|
|
812
812
|
tags?: string[];
|
|
813
|
-
}>(async (statePartArg, dataArg, actionContext) => {
|
|
813
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IRemoteIngressState> => {
|
|
814
814
|
const context = getActionContext();
|
|
815
|
-
const currentState = statePartArg.getState()
|
|
815
|
+
const currentState = statePartArg.getState()!;
|
|
816
816
|
|
|
817
817
|
try {
|
|
818
818
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -820,7 +820,7 @@ export const updateRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
820
820
|
>('/typedrequest', 'updateRemoteIngress');
|
|
821
821
|
|
|
822
822
|
await request.fire({
|
|
823
|
-
identity: context.identity
|
|
823
|
+
identity: context.identity!,
|
|
824
824
|
id: dataArg.id,
|
|
825
825
|
name: dataArg.name,
|
|
826
826
|
listenPorts: dataArg.listenPorts,
|
|
@@ -828,8 +828,8 @@ export const updateRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
828
828
|
tags: dataArg.tags,
|
|
829
829
|
});
|
|
830
830
|
|
|
831
|
-
return await actionContext
|
|
832
|
-
} catch (error) {
|
|
831
|
+
return await actionContext!.dispatch(fetchRemoteIngressAction, null);
|
|
832
|
+
} catch (error: unknown) {
|
|
833
833
|
return {
|
|
834
834
|
...currentState,
|
|
835
835
|
error: error instanceof Error ? error.message : 'Failed to update edge',
|
|
@@ -838,9 +838,9 @@ export const updateRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
838
838
|
});
|
|
839
839
|
|
|
840
840
|
export const regenerateRemoteIngressSecretAction = remoteIngressStatePart.createAction<string>(
|
|
841
|
-
async (statePartArg, edgeId) => {
|
|
841
|
+
async (statePartArg, edgeId): Promise<IRemoteIngressState> => {
|
|
842
842
|
const context = getActionContext();
|
|
843
|
-
const currentState = statePartArg.getState()
|
|
843
|
+
const currentState = statePartArg.getState()!;
|
|
844
844
|
|
|
845
845
|
try {
|
|
846
846
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -848,7 +848,7 @@ export const regenerateRemoteIngressSecretAction = remoteIngressStatePart.create
|
|
|
848
848
|
>('/typedrequest', 'regenerateRemoteIngressSecret');
|
|
849
849
|
|
|
850
850
|
const response = await request.fire({
|
|
851
|
-
identity: context.identity
|
|
851
|
+
identity: context.identity!,
|
|
852
852
|
id: edgeId,
|
|
853
853
|
});
|
|
854
854
|
|
|
@@ -870,9 +870,9 @@ export const regenerateRemoteIngressSecretAction = remoteIngressStatePart.create
|
|
|
870
870
|
);
|
|
871
871
|
|
|
872
872
|
export const clearNewEdgeIdAction = remoteIngressStatePart.createAction(
|
|
873
|
-
async (statePartArg) => {
|
|
873
|
+
async (statePartArg): Promise<IRemoteIngressState> => {
|
|
874
874
|
return {
|
|
875
|
-
...statePartArg.getState()
|
|
875
|
+
...statePartArg.getState()!,
|
|
876
876
|
newEdgeId: null,
|
|
877
877
|
};
|
|
878
878
|
}
|
|
@@ -881,9 +881,9 @@ export const clearNewEdgeIdAction = remoteIngressStatePart.createAction(
|
|
|
881
881
|
export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
882
882
|
id: string;
|
|
883
883
|
enabled: boolean;
|
|
884
|
-
}>(async (statePartArg, dataArg, actionContext) => {
|
|
884
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IRemoteIngressState> => {
|
|
885
885
|
const context = getActionContext();
|
|
886
|
-
const currentState = statePartArg.getState()
|
|
886
|
+
const currentState = statePartArg.getState()!;
|
|
887
887
|
|
|
888
888
|
try {
|
|
889
889
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -891,13 +891,13 @@ export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
891
891
|
>('/typedrequest', 'updateRemoteIngress');
|
|
892
892
|
|
|
893
893
|
await request.fire({
|
|
894
|
-
identity: context.identity
|
|
894
|
+
identity: context.identity!,
|
|
895
895
|
id: dataArg.id,
|
|
896
896
|
enabled: dataArg.enabled,
|
|
897
897
|
});
|
|
898
898
|
|
|
899
|
-
return await actionContext
|
|
900
|
-
} catch (error) {
|
|
899
|
+
return await actionContext!.dispatch(fetchRemoteIngressAction, null);
|
|
900
|
+
} catch (error: unknown) {
|
|
901
901
|
return {
|
|
902
902
|
...currentState,
|
|
903
903
|
error: error instanceof Error ? error.message : 'Failed to toggle edge',
|
|
@@ -909,9 +909,9 @@ export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|
|
909
909
|
// Route Management Actions
|
|
910
910
|
// ============================================================================
|
|
911
911
|
|
|
912
|
-
export const fetchMergedRoutesAction = routeManagementStatePart.createAction(async (statePartArg) => {
|
|
912
|
+
export const fetchMergedRoutesAction = routeManagementStatePart.createAction(async (statePartArg): Promise<IRouteManagementState> => {
|
|
913
913
|
const context = getActionContext();
|
|
914
|
-
const currentState = statePartArg.getState()
|
|
914
|
+
const currentState = statePartArg.getState()!;
|
|
915
915
|
if (!context.identity) return currentState;
|
|
916
916
|
|
|
917
917
|
try {
|
|
@@ -943,9 +943,9 @@ export const fetchMergedRoutesAction = routeManagementStatePart.createAction(asy
|
|
|
943
943
|
export const createRouteAction = routeManagementStatePart.createAction<{
|
|
944
944
|
route: any;
|
|
945
945
|
enabled?: boolean;
|
|
946
|
-
}>(async (statePartArg, dataArg, actionContext) => {
|
|
946
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IRouteManagementState> => {
|
|
947
947
|
const context = getActionContext();
|
|
948
|
-
const currentState = statePartArg.getState()
|
|
948
|
+
const currentState = statePartArg.getState()!;
|
|
949
949
|
|
|
950
950
|
try {
|
|
951
951
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -953,13 +953,13 @@ export const createRouteAction = routeManagementStatePart.createAction<{
|
|
|
953
953
|
>('/typedrequest', 'createRoute');
|
|
954
954
|
|
|
955
955
|
await request.fire({
|
|
956
|
-
identity: context.identity
|
|
956
|
+
identity: context.identity!,
|
|
957
957
|
route: dataArg.route,
|
|
958
958
|
enabled: dataArg.enabled,
|
|
959
959
|
});
|
|
960
960
|
|
|
961
|
-
return await actionContext
|
|
962
|
-
} catch (error) {
|
|
961
|
+
return await actionContext!.dispatch(fetchMergedRoutesAction, null);
|
|
962
|
+
} catch (error: unknown) {
|
|
963
963
|
return {
|
|
964
964
|
...currentState,
|
|
965
965
|
error: error instanceof Error ? error.message : 'Failed to create route',
|
|
@@ -968,9 +968,9 @@ export const createRouteAction = routeManagementStatePart.createAction<{
|
|
|
968
968
|
});
|
|
969
969
|
|
|
970
970
|
export const deleteRouteAction = routeManagementStatePart.createAction<string>(
|
|
971
|
-
async (statePartArg, routeId, actionContext) => {
|
|
971
|
+
async (statePartArg, routeId, actionContext): Promise<IRouteManagementState> => {
|
|
972
972
|
const context = getActionContext();
|
|
973
|
-
const currentState = statePartArg.getState()
|
|
973
|
+
const currentState = statePartArg.getState()!;
|
|
974
974
|
|
|
975
975
|
try {
|
|
976
976
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -978,12 +978,12 @@ export const deleteRouteAction = routeManagementStatePart.createAction<string>(
|
|
|
978
978
|
>('/typedrequest', 'deleteRoute');
|
|
979
979
|
|
|
980
980
|
await request.fire({
|
|
981
|
-
identity: context.identity
|
|
981
|
+
identity: context.identity!,
|
|
982
982
|
id: routeId,
|
|
983
983
|
});
|
|
984
984
|
|
|
985
|
-
return await actionContext
|
|
986
|
-
} catch (error) {
|
|
985
|
+
return await actionContext!.dispatch(fetchMergedRoutesAction, null);
|
|
986
|
+
} catch (error: unknown) {
|
|
987
987
|
return {
|
|
988
988
|
...currentState,
|
|
989
989
|
error: error instanceof Error ? error.message : 'Failed to delete route',
|
|
@@ -995,9 +995,9 @@ export const deleteRouteAction = routeManagementStatePart.createAction<string>(
|
|
|
995
995
|
export const toggleRouteAction = routeManagementStatePart.createAction<{
|
|
996
996
|
id: string;
|
|
997
997
|
enabled: boolean;
|
|
998
|
-
}>(async (statePartArg, dataArg, actionContext) => {
|
|
998
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IRouteManagementState> => {
|
|
999
999
|
const context = getActionContext();
|
|
1000
|
-
const currentState = statePartArg.getState()
|
|
1000
|
+
const currentState = statePartArg.getState()!;
|
|
1001
1001
|
|
|
1002
1002
|
try {
|
|
1003
1003
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -1005,13 +1005,13 @@ export const toggleRouteAction = routeManagementStatePart.createAction<{
|
|
|
1005
1005
|
>('/typedrequest', 'toggleRoute');
|
|
1006
1006
|
|
|
1007
1007
|
await request.fire({
|
|
1008
|
-
identity: context.identity
|
|
1008
|
+
identity: context.identity!,
|
|
1009
1009
|
id: dataArg.id,
|
|
1010
1010
|
enabled: dataArg.enabled,
|
|
1011
1011
|
});
|
|
1012
1012
|
|
|
1013
|
-
return await actionContext
|
|
1014
|
-
} catch (error) {
|
|
1013
|
+
return await actionContext!.dispatch(fetchMergedRoutesAction, null);
|
|
1014
|
+
} catch (error: unknown) {
|
|
1015
1015
|
return {
|
|
1016
1016
|
...currentState,
|
|
1017
1017
|
error: error instanceof Error ? error.message : 'Failed to toggle route',
|
|
@@ -1022,9 +1022,9 @@ export const toggleRouteAction = routeManagementStatePart.createAction<{
|
|
|
1022
1022
|
export const setRouteOverrideAction = routeManagementStatePart.createAction<{
|
|
1023
1023
|
routeName: string;
|
|
1024
1024
|
enabled: boolean;
|
|
1025
|
-
}>(async (statePartArg, dataArg, actionContext) => {
|
|
1025
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IRouteManagementState> => {
|
|
1026
1026
|
const context = getActionContext();
|
|
1027
|
-
const currentState = statePartArg.getState()
|
|
1027
|
+
const currentState = statePartArg.getState()!;
|
|
1028
1028
|
|
|
1029
1029
|
try {
|
|
1030
1030
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -1032,13 +1032,13 @@ export const setRouteOverrideAction = routeManagementStatePart.createAction<{
|
|
|
1032
1032
|
>('/typedrequest', 'setRouteOverride');
|
|
1033
1033
|
|
|
1034
1034
|
await request.fire({
|
|
1035
|
-
identity: context.identity
|
|
1035
|
+
identity: context.identity!,
|
|
1036
1036
|
routeName: dataArg.routeName,
|
|
1037
1037
|
enabled: dataArg.enabled,
|
|
1038
1038
|
});
|
|
1039
1039
|
|
|
1040
|
-
return await actionContext
|
|
1041
|
-
} catch (error) {
|
|
1040
|
+
return await actionContext!.dispatch(fetchMergedRoutesAction, null);
|
|
1041
|
+
} catch (error: unknown) {
|
|
1042
1042
|
return {
|
|
1043
1043
|
...currentState,
|
|
1044
1044
|
error: error instanceof Error ? error.message : 'Failed to set override',
|
|
@@ -1047,9 +1047,9 @@ export const setRouteOverrideAction = routeManagementStatePart.createAction<{
|
|
|
1047
1047
|
});
|
|
1048
1048
|
|
|
1049
1049
|
export const removeRouteOverrideAction = routeManagementStatePart.createAction<string>(
|
|
1050
|
-
async (statePartArg, routeName, actionContext) => {
|
|
1050
|
+
async (statePartArg, routeName, actionContext): Promise<IRouteManagementState> => {
|
|
1051
1051
|
const context = getActionContext();
|
|
1052
|
-
const currentState = statePartArg.getState()
|
|
1052
|
+
const currentState = statePartArg.getState()!;
|
|
1053
1053
|
|
|
1054
1054
|
try {
|
|
1055
1055
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -1057,12 +1057,12 @@ export const removeRouteOverrideAction = routeManagementStatePart.createAction<s
|
|
|
1057
1057
|
>('/typedrequest', 'removeRouteOverride');
|
|
1058
1058
|
|
|
1059
1059
|
await request.fire({
|
|
1060
|
-
identity: context.identity
|
|
1060
|
+
identity: context.identity!,
|
|
1061
1061
|
routeName,
|
|
1062
1062
|
});
|
|
1063
1063
|
|
|
1064
|
-
return await actionContext
|
|
1065
|
-
} catch (error) {
|
|
1064
|
+
return await actionContext!.dispatch(fetchMergedRoutesAction, null);
|
|
1065
|
+
} catch (error: unknown) {
|
|
1066
1066
|
return {
|
|
1067
1067
|
...currentState,
|
|
1068
1068
|
error: error instanceof Error ? error.message : 'Failed to remove override',
|
|
@@ -1075,9 +1075,9 @@ export const removeRouteOverrideAction = routeManagementStatePart.createAction<s
|
|
|
1075
1075
|
// API Token Actions
|
|
1076
1076
|
// ============================================================================
|
|
1077
1077
|
|
|
1078
|
-
export const fetchApiTokensAction = routeManagementStatePart.createAction(async (statePartArg) => {
|
|
1078
|
+
export const fetchApiTokensAction = routeManagementStatePart.createAction(async (statePartArg): Promise<IRouteManagementState> => {
|
|
1079
1079
|
const context = getActionContext();
|
|
1080
|
-
const currentState = statePartArg.getState()
|
|
1080
|
+
const currentState = statePartArg.getState()!;
|
|
1081
1081
|
if (!context.identity) return currentState;
|
|
1082
1082
|
|
|
1083
1083
|
try {
|
|
@@ -1108,7 +1108,7 @@ export async function createApiToken(name: string, scopes: interfaces.data.TApiT
|
|
|
1108
1108
|
>('/typedrequest', 'createApiToken');
|
|
1109
1109
|
|
|
1110
1110
|
return request.fire({
|
|
1111
|
-
identity: context.identity
|
|
1111
|
+
identity: context.identity!,
|
|
1112
1112
|
name,
|
|
1113
1113
|
scopes,
|
|
1114
1114
|
expiresInDays,
|
|
@@ -1122,15 +1122,15 @@ export async function rollApiToken(id: string) {
|
|
|
1122
1122
|
>('/typedrequest', 'rollApiToken');
|
|
1123
1123
|
|
|
1124
1124
|
return request.fire({
|
|
1125
|
-
identity: context.identity
|
|
1125
|
+
identity: context.identity!,
|
|
1126
1126
|
id,
|
|
1127
1127
|
});
|
|
1128
1128
|
}
|
|
1129
1129
|
|
|
1130
1130
|
export const revokeApiTokenAction = routeManagementStatePart.createAction<string>(
|
|
1131
|
-
async (statePartArg, tokenId, actionContext) => {
|
|
1131
|
+
async (statePartArg, tokenId, actionContext): Promise<IRouteManagementState> => {
|
|
1132
1132
|
const context = getActionContext();
|
|
1133
|
-
const currentState = statePartArg.getState()
|
|
1133
|
+
const currentState = statePartArg.getState()!;
|
|
1134
1134
|
|
|
1135
1135
|
try {
|
|
1136
1136
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -1138,12 +1138,12 @@ export const revokeApiTokenAction = routeManagementStatePart.createAction<string
|
|
|
1138
1138
|
>('/typedrequest', 'revokeApiToken');
|
|
1139
1139
|
|
|
1140
1140
|
await request.fire({
|
|
1141
|
-
identity: context.identity
|
|
1141
|
+
identity: context.identity!,
|
|
1142
1142
|
id: tokenId,
|
|
1143
1143
|
});
|
|
1144
1144
|
|
|
1145
|
-
return await actionContext
|
|
1146
|
-
} catch (error) {
|
|
1145
|
+
return await actionContext!.dispatch(fetchApiTokensAction, null);
|
|
1146
|
+
} catch (error: unknown) {
|
|
1147
1147
|
return {
|
|
1148
1148
|
...currentState,
|
|
1149
1149
|
error: error instanceof Error ? error.message : 'Failed to revoke token',
|
|
@@ -1155,9 +1155,9 @@ export const revokeApiTokenAction = routeManagementStatePart.createAction<string
|
|
|
1155
1155
|
export const toggleApiTokenAction = routeManagementStatePart.createAction<{
|
|
1156
1156
|
id: string;
|
|
1157
1157
|
enabled: boolean;
|
|
1158
|
-
}>(async (statePartArg, dataArg, actionContext) => {
|
|
1158
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IRouteManagementState> => {
|
|
1159
1159
|
const context = getActionContext();
|
|
1160
|
-
const currentState = statePartArg.getState()
|
|
1160
|
+
const currentState = statePartArg.getState()!;
|
|
1161
1161
|
|
|
1162
1162
|
try {
|
|
1163
1163
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
@@ -1165,13 +1165,13 @@ export const toggleApiTokenAction = routeManagementStatePart.createAction<{
|
|
|
1165
1165
|
>('/typedrequest', 'toggleApiToken');
|
|
1166
1166
|
|
|
1167
1167
|
await request.fire({
|
|
1168
|
-
identity: context.identity
|
|
1168
|
+
identity: context.identity!,
|
|
1169
1169
|
id: dataArg.id,
|
|
1170
1170
|
enabled: dataArg.enabled,
|
|
1171
1171
|
});
|
|
1172
1172
|
|
|
1173
|
-
return await actionContext
|
|
1174
|
-
} catch (error) {
|
|
1173
|
+
return await actionContext!.dispatch(fetchApiTokensAction, null);
|
|
1174
|
+
} catch (error: unknown) {
|
|
1175
1175
|
return {
|
|
1176
1176
|
...currentState,
|
|
1177
1177
|
error: error instanceof Error ? error.message : 'Failed to toggle token',
|
|
@@ -1191,13 +1191,13 @@ socketRouter.addTypedHandler(
|
|
|
1191
1191
|
new plugins.domtools.plugins.typedrequest.TypedHandler<interfaces.requests.IReq_PushLogEntry>(
|
|
1192
1192
|
'pushLogEntry',
|
|
1193
1193
|
async (dataArg) => {
|
|
1194
|
-
const current = logStatePart.getState()
|
|
1194
|
+
const current = logStatePart.getState()!;
|
|
1195
1195
|
const updated = [...current.recentLogs, dataArg.entry];
|
|
1196
1196
|
// Cap at 2000 entries
|
|
1197
1197
|
if (updated.length > 2000) {
|
|
1198
1198
|
updated.splice(0, updated.length - 2000);
|
|
1199
1199
|
}
|
|
1200
|
-
logStatePart.setState({ ...current, recentLogs: updated });
|
|
1200
|
+
logStatePart.setState({ ...current, recentLogs: updated } as ILogState);
|
|
1201
1201
|
return {};
|
|
1202
1202
|
}
|
|
1203
1203
|
)
|
|
@@ -1232,14 +1232,14 @@ async function disconnectSocket() {
|
|
|
1232
1232
|
async function dispatchCombinedRefreshAction() {
|
|
1233
1233
|
const context = getActionContext();
|
|
1234
1234
|
if (!context.identity) return;
|
|
1235
|
-
const currentView = uiStatePart.getState()
|
|
1235
|
+
const currentView = uiStatePart.getState()!.activeView;
|
|
1236
1236
|
|
|
1237
1237
|
try {
|
|
1238
1238
|
// Always fetch basic stats for dashboard widgets
|
|
1239
1239
|
const combinedRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1240
1240
|
interfaces.requests.IReq_GetCombinedMetrics
|
|
1241
1241
|
>('/typedrequest', 'getCombinedMetrics');
|
|
1242
|
-
|
|
1242
|
+
|
|
1243
1243
|
const combinedResponse = await combinedRequest.fire({
|
|
1244
1244
|
identity: context.identity,
|
|
1245
1245
|
sections: {
|
|
@@ -1252,12 +1252,13 @@ async function dispatchCombinedRefreshAction() {
|
|
|
1252
1252
|
});
|
|
1253
1253
|
|
|
1254
1254
|
// Update all stats from combined response
|
|
1255
|
+
const currentStatsState = statsStatePart.getState()!;
|
|
1255
1256
|
statsStatePart.setState({
|
|
1256
|
-
...
|
|
1257
|
-
serverStats: combinedResponse.metrics.server ||
|
|
1258
|
-
emailStats: combinedResponse.metrics.email ||
|
|
1259
|
-
dnsStats: combinedResponse.metrics.dns ||
|
|
1260
|
-
securityMetrics: combinedResponse.metrics.security ||
|
|
1257
|
+
...currentStatsState,
|
|
1258
|
+
serverStats: combinedResponse.metrics.server || currentStatsState.serverStats,
|
|
1259
|
+
emailStats: combinedResponse.metrics.email || currentStatsState.emailStats,
|
|
1260
|
+
dnsStats: combinedResponse.metrics.dns || currentStatsState.dnsStats,
|
|
1261
|
+
securityMetrics: combinedResponse.metrics.security || currentStatsState.securityMetrics,
|
|
1261
1262
|
lastUpdated: Date.now(),
|
|
1262
1263
|
isLoading: false,
|
|
1263
1264
|
error: null,
|
|
@@ -1284,7 +1285,7 @@ async function dispatchCombinedRefreshAction() {
|
|
|
1284
1285
|
});
|
|
1285
1286
|
|
|
1286
1287
|
networkStatePart.setState({
|
|
1287
|
-
...networkStatePart.getState()
|
|
1288
|
+
...networkStatePart.getState()!,
|
|
1288
1289
|
connections: connectionsResponse.connections,
|
|
1289
1290
|
connectionsByIP,
|
|
1290
1291
|
throughputRate: {
|
|
@@ -1297,14 +1298,15 @@ async function dispatchCombinedRefreshAction() {
|
|
|
1297
1298
|
throughputHistory: network.throughputHistory || [],
|
|
1298
1299
|
requestsPerSecond: network.requestsPerSecond || 0,
|
|
1299
1300
|
requestsTotal: network.requestsTotal || 0,
|
|
1301
|
+
backends: network.backends || [],
|
|
1300
1302
|
lastUpdated: Date.now(),
|
|
1301
1303
|
isLoading: false,
|
|
1302
1304
|
error: null,
|
|
1303
1305
|
});
|
|
1304
|
-
} catch (error) {
|
|
1306
|
+
} catch (error: unknown) {
|
|
1305
1307
|
console.error('Failed to fetch connections:', error);
|
|
1306
1308
|
networkStatePart.setState({
|
|
1307
|
-
...networkStatePart.getState()
|
|
1309
|
+
...networkStatePart.getState()!,
|
|
1308
1310
|
connections: [],
|
|
1309
1311
|
connectionsByIP,
|
|
1310
1312
|
throughputRate: {
|
|
@@ -1317,6 +1319,7 @@ async function dispatchCombinedRefreshAction() {
|
|
|
1317
1319
|
throughputHistory: network.throughputHistory || [],
|
|
1318
1320
|
requestsPerSecond: network.requestsPerSecond || 0,
|
|
1319
1321
|
requestsTotal: network.requestsTotal || 0,
|
|
1322
|
+
backends: network.backends || [],
|
|
1320
1323
|
lastUpdated: Date.now(),
|
|
1321
1324
|
isLoading: false,
|
|
1322
1325
|
error: null,
|
|
@@ -1359,9 +1362,9 @@ let currentRefreshRate = 1000; // Track current refresh rate to avoid unnecessar
|
|
|
1359
1362
|
// Initialize auto-refresh when UI state is ready
|
|
1360
1363
|
(() => {
|
|
1361
1364
|
const startAutoRefresh = () => {
|
|
1362
|
-
const uiState = uiStatePart.getState()
|
|
1363
|
-
const loginState = loginStatePart.getState()
|
|
1364
|
-
|
|
1365
|
+
const uiState = uiStatePart.getState()!;
|
|
1366
|
+
const loginState = loginStatePart.getState()!;
|
|
1367
|
+
|
|
1365
1368
|
// Only start if conditions are met and not already running at the same rate
|
|
1366
1369
|
if (uiState.autoRefresh && loginState.isLoggedIn) {
|
|
1367
1370
|
// Check if we need to restart the interval (rate changed or not running)
|
|
@@ -1387,9 +1390,9 @@ let currentRefreshRate = 1000; // Track current refresh rate to avoid unnecessar
|
|
|
1387
1390
|
};
|
|
1388
1391
|
|
|
1389
1392
|
// Watch for relevant changes only
|
|
1390
|
-
let previousAutoRefresh = uiStatePart.getState()
|
|
1391
|
-
let previousRefreshInterval = uiStatePart.getState()
|
|
1392
|
-
let previousIsLoggedIn = loginStatePart.getState()
|
|
1393
|
+
let previousAutoRefresh = uiStatePart.getState()!.autoRefresh;
|
|
1394
|
+
let previousRefreshInterval = uiStatePart.getState()!.refreshInterval;
|
|
1395
|
+
let previousIsLoggedIn = loginStatePart.getState()!.isLoggedIn;
|
|
1393
1396
|
|
|
1394
1397
|
uiStatePart.state.subscribe((state) => {
|
|
1395
1398
|
// Only restart if relevant values changed
|
|
@@ -1420,7 +1423,7 @@ let currentRefreshRate = 1000; // Track current refresh rate to avoid unnecessar
|
|
|
1420
1423
|
startAutoRefresh();
|
|
1421
1424
|
|
|
1422
1425
|
// Connect TypedSocket if already logged in (e.g., persistent session)
|
|
1423
|
-
if (loginStatePart.getState()
|
|
1426
|
+
if (loginStatePart.getState()!.isLoggedIn) {
|
|
1424
1427
|
connectSocket();
|
|
1425
1428
|
}
|
|
1426
1429
|
})();
|