@serve.zone/dcrouter 15.0.2 → 15.0.3
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/deno.json +1 -1
- package/dist_serve/bundle.js +768 -768
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate/acme.d.ts +17 -0
- package/dist_ts_web/appstate/acme.js +64 -0
- package/dist_ts_web/appstate/certificates.d.ts +37 -0
- package/dist_ts_web/appstate/certificates.js +107 -0
- package/dist_ts_web/appstate/config.d.ts +9 -0
- package/dist_ts_web/appstate/config.js +35 -0
- package/dist_ts_web/appstate/domains.d.ts +80 -0
- package/dist_ts_web/appstate/domains.js +324 -0
- package/dist_ts_web/appstate/email-domains.d.ts +25 -0
- package/dist_ts_web/appstate/email-domains.js +104 -0
- package/dist_ts_web/appstate/email-ops.d.ts +10 -0
- package/dist_ts_web/appstate/email-ops.js +40 -0
- package/dist_ts_web/appstate/login.d.ts +30 -0
- package/dist_ts_web/appstate/login.js +83 -0
- package/dist_ts_web/appstate/logs.d.ts +16 -0
- package/dist_ts_web/appstate/logs.js +27 -0
- package/dist_ts_web/appstate/network.d.ts +50 -0
- package/dist_ts_web/appstate/network.js +122 -0
- package/dist_ts_web/appstate/profiles-targets.d.ts +45 -0
- package/dist_ts_web/appstate/profiles-targets.js +173 -0
- package/dist_ts_web/appstate/remoteingress.d.ts +47 -0
- package/dist_ts_web/appstate/remoteingress.js +204 -0
- package/dist_ts_web/appstate/routes.d.ts +76 -0
- package/dist_ts_web/appstate/routes.js +316 -0
- package/dist_ts_web/appstate/runtime.d.ts +1 -0
- package/dist_ts_web/appstate/runtime.js +276 -0
- package/dist_ts_web/appstate/security.d.ts +29 -0
- package/dist_ts_web/appstate/security.js +167 -0
- package/dist_ts_web/appstate/shared.d.ts +3 -0
- package/dist_ts_web/appstate/shared.js +13 -0
- package/dist_ts_web/appstate/stats.d.ts +15 -0
- package/dist_ts_web/appstate/stats.js +59 -0
- package/dist_ts_web/appstate/target-profiles.d.ts +37 -0
- package/dist_ts_web/appstate/target-profiles.js +118 -0
- package/dist_ts_web/appstate/ui.d.ts +11 -0
- package/dist_ts_web/appstate/ui.js +55 -0
- package/dist_ts_web/appstate/users.d.ts +27 -0
- package/dist_ts_web/appstate/users.js +85 -0
- package/dist_ts_web/appstate/vpn.d.ts +44 -0
- package/dist_ts_web/appstate/vpn.js +148 -0
- package/dist_ts_web/appstate.d.ts +20 -568
- package/dist_ts_web/appstate.js +24 -2418
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate/acme.ts +93 -0
- package/ts_web/appstate/certificates.ts +159 -0
- package/ts_web/appstate/config.ts +49 -0
- package/ts_web/appstate/domains.ts +429 -0
- package/ts_web/appstate/email-domains.ts +155 -0
- package/ts_web/appstate/email-ops.ts +57 -0
- package/ts_web/appstate/login.ts +128 -0
- package/ts_web/appstate/logs.ts +50 -0
- package/ts_web/appstate/network.ts +161 -0
- package/ts_web/appstate/profiles-targets.ts +240 -0
- package/ts_web/appstate/remoteingress.ts +300 -0
- package/ts_web/appstate/routes.ts +447 -0
- package/ts_web/appstate/runtime.ts +308 -0
- package/ts_web/appstate/security.ts +229 -0
- package/ts_web/appstate/shared.ts +15 -0
- package/ts_web/appstate/stats.ts +79 -0
- package/ts_web/appstate/target-profiles.ts +164 -0
- package/ts_web/appstate/ui.ts +75 -0
- package/ts_web/appstate/users.ts +133 -0
- package/ts_web/appstate/vpn.ts +234 -0
- package/ts_web/appstate.ts +24 -3403
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
|
3
|
+
import { appState } from './shared.js';
|
|
4
|
+
import { getActionContext } from './login.js';
|
|
5
|
+
export const targetProfilesStatePart = await appState.getStatePart('targetProfiles', {
|
|
6
|
+
profiles: [],
|
|
7
|
+
isLoading: false,
|
|
8
|
+
error: null,
|
|
9
|
+
lastUpdated: 0,
|
|
10
|
+
}, 'soft');
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Target Profiles Actions
|
|
13
|
+
// ============================================================================
|
|
14
|
+
export const fetchTargetProfilesAction = targetProfilesStatePart.createAction(async (statePartArg) => {
|
|
15
|
+
const context = getActionContext();
|
|
16
|
+
const currentState = statePartArg.getState();
|
|
17
|
+
if (!context.identity)
|
|
18
|
+
return currentState;
|
|
19
|
+
try {
|
|
20
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'getTargetProfiles');
|
|
21
|
+
const response = await request.fire({ identity: context.identity });
|
|
22
|
+
return {
|
|
23
|
+
profiles: response.profiles,
|
|
24
|
+
isLoading: false,
|
|
25
|
+
error: null,
|
|
26
|
+
lastUpdated: Date.now(),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return {
|
|
31
|
+
...currentState,
|
|
32
|
+
isLoading: false,
|
|
33
|
+
error: error instanceof Error ? error.message : 'Failed to fetch target profiles',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
export const createTargetProfileAction = targetProfilesStatePart.createAction(async (statePartArg, dataArg, actionContext) => {
|
|
38
|
+
const context = getActionContext();
|
|
39
|
+
try {
|
|
40
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'createTargetProfile');
|
|
41
|
+
const response = await request.fire({
|
|
42
|
+
identity: context.identity,
|
|
43
|
+
name: dataArg.name,
|
|
44
|
+
description: dataArg.description,
|
|
45
|
+
domains: dataArg.domains,
|
|
46
|
+
targets: dataArg.targets,
|
|
47
|
+
routeRefs: dataArg.routeRefs,
|
|
48
|
+
allowRoutesByClientSourceIp: dataArg.allowRoutesByClientSourceIp,
|
|
49
|
+
});
|
|
50
|
+
if (!response.success) {
|
|
51
|
+
return {
|
|
52
|
+
...statePartArg.getState(),
|
|
53
|
+
error: response.message || 'Failed to create target profile',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return await actionContext.dispatch(fetchTargetProfilesAction, null);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return {
|
|
60
|
+
...statePartArg.getState(),
|
|
61
|
+
error: error instanceof Error ? error.message : 'Failed to create target profile',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
export const updateTargetProfileAction = targetProfilesStatePart.createAction(async (statePartArg, dataArg, actionContext) => {
|
|
66
|
+
const context = getActionContext();
|
|
67
|
+
try {
|
|
68
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'updateTargetProfile');
|
|
69
|
+
const response = await request.fire({
|
|
70
|
+
identity: context.identity,
|
|
71
|
+
id: dataArg.id,
|
|
72
|
+
name: dataArg.name,
|
|
73
|
+
description: dataArg.description,
|
|
74
|
+
domains: dataArg.domains,
|
|
75
|
+
targets: dataArg.targets,
|
|
76
|
+
routeRefs: dataArg.routeRefs,
|
|
77
|
+
allowRoutesByClientSourceIp: dataArg.allowRoutesByClientSourceIp,
|
|
78
|
+
});
|
|
79
|
+
if (!response.success) {
|
|
80
|
+
return {
|
|
81
|
+
...statePartArg.getState(),
|
|
82
|
+
error: response.message || 'Failed to update target profile',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return await actionContext.dispatch(fetchTargetProfilesAction, null);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
return {
|
|
89
|
+
...statePartArg.getState(),
|
|
90
|
+
error: error instanceof Error ? error.message : 'Failed to update target profile',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
export const deleteTargetProfileAction = targetProfilesStatePart.createAction(async (statePartArg, dataArg, actionContext) => {
|
|
95
|
+
const context = getActionContext();
|
|
96
|
+
try {
|
|
97
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'deleteTargetProfile');
|
|
98
|
+
const response = await request.fire({
|
|
99
|
+
identity: context.identity,
|
|
100
|
+
id: dataArg.id,
|
|
101
|
+
force: dataArg.force,
|
|
102
|
+
});
|
|
103
|
+
if (!response.success) {
|
|
104
|
+
return {
|
|
105
|
+
...statePartArg.getState(),
|
|
106
|
+
error: response.message || 'Failed to delete target profile',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return await actionContext.dispatch(fetchTargetProfilesAction, null);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
return {
|
|
113
|
+
...statePartArg.getState(),
|
|
114
|
+
error: error instanceof Error ? error.message : 'Failed to delete target profile',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFyZ2V0LXByb2ZpbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHNfd2ViL2FwcHN0YXRlL3RhcmdldC1wcm9maWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssVUFBVSxNQUFNLDhCQUE4QixDQUFDO0FBQzNELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBWTlDLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLE1BQU0sUUFBUSxDQUFDLFlBQVksQ0FDaEUsZ0JBQWdCLEVBQ2hCO0lBQ0UsUUFBUSxFQUFFLEVBQUU7SUFDWixTQUFTLEVBQUUsS0FBSztJQUNoQixLQUFLLEVBQUUsSUFBSTtJQUNYLFdBQVcsRUFBRSxDQUFDO0NBQ2YsRUFDRCxNQUFNLENBQ1AsQ0FBQztBQUVGLCtFQUErRTtBQUMvRSwwQkFBMEI7QUFDMUIsK0VBQStFO0FBRS9FLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLHVCQUF1QixDQUFDLFlBQVksQ0FDM0UsS0FBSyxFQUFFLFlBQVksRUFBaUMsRUFBRTtJQUNwRCxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ25DLE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxRQUFRLEVBQUcsQ0FBQztJQUM5QyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVE7UUFBRSxPQUFPLFlBQVksQ0FBQztJQUUzQyxJQUFJLENBQUM7UUFDSCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxZQUFZLENBRXBFLGVBQWUsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1FBRXhDLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLFFB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
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface IUiState {
|
|
2
|
+
activeView: string;
|
|
3
|
+
activeSubview: string | null;
|
|
4
|
+
sidebarCollapsed: boolean;
|
|
5
|
+
autoRefresh: boolean;
|
|
6
|
+
refreshInterval: number;
|
|
7
|
+
theme: 'light' | 'dark';
|
|
8
|
+
}
|
|
9
|
+
export declare const uiStatePart: import("@push.rocks/smartstate").StatePart<string, IUiState>;
|
|
10
|
+
export declare const toggleAutoRefreshAction: import("@push.rocks/smartstate").StateAction<IUiState, unknown>;
|
|
11
|
+
export declare const setActiveViewAction: import("@push.rocks/smartstate").StateAction<IUiState, string>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { appState } from './shared.js';
|
|
2
|
+
import { networkStatePart, fetchNetworkStatsAction } from './network.js';
|
|
3
|
+
import { certificateStatePart, fetchCertificateOverviewAction } from './certificates.js';
|
|
4
|
+
// Determine initial view from URL path
|
|
5
|
+
const getInitialView = () => {
|
|
6
|
+
const path = typeof window !== 'undefined' ? window.location.pathname : '/';
|
|
7
|
+
const validViews = ['overview', 'network', 'email', 'logs', 'access', 'security', 'domains'];
|
|
8
|
+
const segments = path.split('/').filter(Boolean);
|
|
9
|
+
const view = segments[0];
|
|
10
|
+
return validViews.includes(view) ? view : 'overview';
|
|
11
|
+
};
|
|
12
|
+
// Determine initial subview (second URL segment) from the path
|
|
13
|
+
const getInitialSubview = () => {
|
|
14
|
+
const path = typeof window !== 'undefined' ? window.location.pathname : '/';
|
|
15
|
+
const segments = path.split('/').filter(Boolean);
|
|
16
|
+
return segments[1] ?? null;
|
|
17
|
+
};
|
|
18
|
+
export const uiStatePart = await appState.getStatePart('ui', {
|
|
19
|
+
activeView: getInitialView(),
|
|
20
|
+
activeSubview: getInitialSubview(),
|
|
21
|
+
sidebarCollapsed: false,
|
|
22
|
+
autoRefresh: true,
|
|
23
|
+
refreshInterval: 1000, // 1 second
|
|
24
|
+
theme: 'light',
|
|
25
|
+
});
|
|
26
|
+
// Toggle Auto Refresh Action
|
|
27
|
+
export const toggleAutoRefreshAction = uiStatePart.createAction(async (statePartArg) => {
|
|
28
|
+
const currentState = statePartArg.getState();
|
|
29
|
+
return {
|
|
30
|
+
...currentState,
|
|
31
|
+
autoRefresh: !currentState.autoRefresh,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
// Set Active View Action
|
|
35
|
+
export const setActiveViewAction = uiStatePart.createAction(async (statePartArg, viewName) => {
|
|
36
|
+
const currentState = statePartArg.getState();
|
|
37
|
+
// If switching to network view, ensure we fetch network data
|
|
38
|
+
if (viewName === 'network' && currentState.activeView !== 'network') {
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
networkStatePart.dispatchAction(fetchNetworkStatsAction, null);
|
|
41
|
+
}, 100);
|
|
42
|
+
}
|
|
43
|
+
// If switching to the Domains group, ensure we fetch certificate data
|
|
44
|
+
// (Certificates is a subview of Domains).
|
|
45
|
+
if (viewName === 'domains' && currentState.activeView !== 'domains') {
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null);
|
|
48
|
+
}, 100);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
...currentState,
|
|
52
|
+
activeView: viewName,
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90c193ZWIvYXBwc3RhdGUvdWkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLDhCQUE4QixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFXekYsdUNBQXVDO0FBQ3ZDLE1BQU0sY0FBYyxHQUFHLEdBQVcsRUFBRTtJQUNsQyxNQUFNLElBQUksR0FBRyxPQUFPLE1BQU0sS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDNUUsTUFBTSxVQUFVLEdBQUcsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUM3RixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqRCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekIsT0FBTyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztBQUN2RCxDQUFDLENBQUM7QUFFRiwrREFBK0Q7QUFDL0QsTUFBTSxpQkFBaUIsR0FBRyxHQUFrQixFQUFFO0lBQzVDLE1BQU0sSUFBSSxHQUFHLE9BQU8sTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUM1RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqRCxPQUFPLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7QUFDN0IsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLFlBQVksQ0FDcEQsSUFBSSxFQUNKO0lBQ0UsVUFBVSxFQUFFLGNBQWMsRUFBRTtJQUM1QixhQUFhLEVBQUUsaUJBQWlCLEVBQUU7SUFDbEMsZ0JBQWdCLEVBQUUsS0FBSztJQUN2QixXQUFXLEVBQUUsSUFBSTtJQUNqQixlQUFlLEVBQUUsSUFBSSxFQUFFLFdBQVc7SUFDbEMsS0FBSyxFQUFFLE9BQU87Q0FDZixDQUNGLENBQUM7QUFFRiw2QkFBNkI7QUFDN0IsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsV0FBVyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsWUFBWSxFQUFxQixFQUFFO0lBQ3hHLE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxRQUFRLEVBQUcsQ0FBQztJQUM5QyxPQUFPO1FBQ0wsR0FBRyxZQUFZO1FBQ2YsV0FBVyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVc7S0FDdkMsQ0FBQztBQUNKLENBQUMsQ0FBQyxDQUFDO0FBRUgseUJBQXlCO0FBQ3pCLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQVMsS0FBSyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQXFCLEVBQUU7SUFDdEgsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRyxDQUFDO0lBRTlDLDZEQUE2RDtJQUM3RCxJQUFJLFFBQVEsS0FBSyxTQUFTLElBQUksWUFBWSxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNwRSxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2pFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNWLENBQUM7SUFFRCxzRUFBc0U7SUFDdEUsMENBQTBDO0lBQzFDLElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxZQUFZLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3BFLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxvQkFBb0IsQ0FBQyxjQUFjLENBQUMsOEJBQThCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDNUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsQ0FBQztJQUVELE9BQU87UUFDTCxHQUFHLFlBQVk7UUFDZixVQUFVLEVBQUUsUUFBUTtLQUNyQixDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUMifQ==
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
|
3
|
+
export interface IUser {
|
|
4
|
+
id: string;
|
|
5
|
+
username: string;
|
|
6
|
+
email?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
role: string;
|
|
9
|
+
status?: 'active' | 'disabled';
|
|
10
|
+
authSources?: Array<'local' | 'idp.global'>;
|
|
11
|
+
}
|
|
12
|
+
export interface IUsersState {
|
|
13
|
+
users: IUser[];
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
error: string | null;
|
|
16
|
+
lastUpdated: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const usersStatePart: plugins.deesElement.domtools.plugins.smartstate.StatePart<string, IUsersState>;
|
|
19
|
+
export declare const fetchUsersAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IUsersState, unknown>;
|
|
20
|
+
export declare const createUserAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IUsersState, {
|
|
21
|
+
email: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
role: interfaces.requests.TUserManagementRole;
|
|
24
|
+
password: string;
|
|
25
|
+
enableIdpGlobalAuth?: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
export declare const deleteUserAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IUsersState, string>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
|
3
|
+
import { appState } from './shared.js';
|
|
4
|
+
import { getActionContext } from './login.js';
|
|
5
|
+
export const usersStatePart = await appState.getStatePart('users', {
|
|
6
|
+
users: [],
|
|
7
|
+
isLoading: false,
|
|
8
|
+
error: null,
|
|
9
|
+
lastUpdated: 0,
|
|
10
|
+
}, 'soft');
|
|
11
|
+
export const fetchUsersAction = usersStatePart.createAction(async (statePartArg) => {
|
|
12
|
+
const context = getActionContext();
|
|
13
|
+
const currentState = statePartArg.getState();
|
|
14
|
+
if (!context.identity)
|
|
15
|
+
return currentState;
|
|
16
|
+
try {
|
|
17
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'listUsers');
|
|
18
|
+
const response = await request.fire({
|
|
19
|
+
identity: context.identity,
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
...currentState,
|
|
23
|
+
users: response.users,
|
|
24
|
+
error: null,
|
|
25
|
+
lastUpdated: Date.now(),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return {
|
|
30
|
+
...currentState,
|
|
31
|
+
error: error instanceof Error ? error.message : 'Failed to fetch users',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
export const createUserAction = usersStatePart.createAction(async (statePartArg, dataArg, actionContext) => {
|
|
36
|
+
const context = getActionContext();
|
|
37
|
+
const currentState = statePartArg.getState();
|
|
38
|
+
if (!context.identity)
|
|
39
|
+
return currentState;
|
|
40
|
+
try {
|
|
41
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'createUser');
|
|
42
|
+
const response = await request.fire({
|
|
43
|
+
identity: context.identity,
|
|
44
|
+
email: dataArg.email,
|
|
45
|
+
name: dataArg.name,
|
|
46
|
+
role: dataArg.role,
|
|
47
|
+
password: dataArg.password,
|
|
48
|
+
enableIdpGlobalAuth: dataArg.enableIdpGlobalAuth,
|
|
49
|
+
});
|
|
50
|
+
if (!response.success) {
|
|
51
|
+
throw new Error(response.message || 'Failed to create user');
|
|
52
|
+
}
|
|
53
|
+
return await actionContext.dispatch(fetchUsersAction, null);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return {
|
|
57
|
+
...currentState,
|
|
58
|
+
error: error instanceof Error ? error.message : 'Failed to create user',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
export const deleteUserAction = usersStatePart.createAction(async (statePartArg, userIdArg, actionContext) => {
|
|
63
|
+
const context = getActionContext();
|
|
64
|
+
const currentState = statePartArg.getState();
|
|
65
|
+
if (!context.identity)
|
|
66
|
+
return currentState;
|
|
67
|
+
try {
|
|
68
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'deleteUser');
|
|
69
|
+
const response = await request.fire({
|
|
70
|
+
identity: context.identity,
|
|
71
|
+
id: userIdArg,
|
|
72
|
+
});
|
|
73
|
+
if (!response.success) {
|
|
74
|
+
throw new Error(response.message || 'Failed to delete user');
|
|
75
|
+
}
|
|
76
|
+
return await actionContext.dispatch(fetchUsersAction, null);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return {
|
|
80
|
+
...currentState,
|
|
81
|
+
error: error instanceof Error ? error.message : 'Failed to delete user',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90c193ZWIvYXBwc3RhdGUvdXNlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxLQUFLLFVBQVUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQXVCOUMsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLE1BQU0sUUFBUSxDQUFDLFlBQVksQ0FDdkQsT0FBTyxFQUNQO0lBQ0UsS0FBSyxFQUFFLEVBQUU7SUFDVCxTQUFTLEVBQUUsS0FBSztJQUNoQixLQUFLLEVBQUUsSUFBSTtJQUNYLFdBQVcsRUFBRSxDQUFDO0NBQ2YsRUFDRCxNQUFNLENBQ1AsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLGNBQWMsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFlBQVksRUFBd0IsRUFBRTtJQUN2RyxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ25DLE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxRQUFRLEVBQUcsQ0FBQztJQUM5QyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVE7UUFBRSxPQUFPLFlBQVksQ0FBQztJQUUzQyxJQUFJLENBQUM7UUFDSCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxZQUFZLENBRXBFLGVBQWUsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUVoQyxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDbEMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1NBQzNCLENBQUMsQ0FBQztRQUVILE9BQU87WUFDTCxHQUFHLFlBQVk7WUFDZixLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUs7WUFDckIsS0FBSyxFQUFFLElBQUk7WUFDWCxXQUFXLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtTQUN4QixDQUFDO0lBQ0osQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPO1lBQ0wsR0FBRyxZQUFZO1lBQ2YsS0FBSyxFQUFFLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLHVCQUF1QjtTQUN4RSxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsY0FBYyxDQUFDLFlBQVksQ0FNeEQsS0FBSyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUF3QixFQUFFO0lBQ3RFLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixFQUFFLENBQUM7SUFDbkMsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRyxDQUFDO0lBQzlDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUTtRQUFFLE9BQU8sWUFBWSxDQUFDO0lBRTNDLElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FFcEUsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRWpDLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQztZQUNsQyxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7WUFDMUIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1lBQ3BCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtZQUNsQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1lBQzFCLG1CQUFtQixFQUFFLE9BQU8sQ0FBQyxtQkFBbUI7U0FDakQsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLElBQUksdUJBQXVCLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBRUQsT0FBTyxNQUFNLGFBQWMsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPO1lBQ0wsR0FBRyxZQUFZO1lBQ2YsS0FBSyxFQUFFLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLHVCQUF1QjtTQUN4RSxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsY0FBYyxDQUFDLFlBQVksQ0FDekQsS0FBSyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUF3QixFQUFFO0lBQ3JFLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixFQUFFLENBQUM7SUFDbkMsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRyxDQUFDO0lBQzlDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUTtRQUFFLE9BQU8sWUFBWSxDQUFDO0lBRTNDLElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FFcEUsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRWpDLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQztZQUNsQyxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7WUFDMUIsRUFBRSxFQUFFLFNBQVM7U0FDZCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sSUFBSSx1QkFBdUIsQ0FBQyxDQUFDO1FBQy9ELENBQUM7UUFFRCxPQUFPLE1BQU0sYUFBYyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE9BQU87WUFDTCxHQUFHLFlBQVk7WUFDZixLQUFLLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsdUJBQXVCO1NBQ3hFLENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQyxDQUNGLENBQUMifQ==
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
|
3
|
+
export interface IVpnState {
|
|
4
|
+
clients: interfaces.data.IVpnClient[];
|
|
5
|
+
connectedClients: interfaces.data.IVpnConnectedClient[];
|
|
6
|
+
status: interfaces.data.IVpnServerStatus | null;
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
error: string | null;
|
|
9
|
+
lastUpdated: number;
|
|
10
|
+
/** WireGuard config shown after create/rotate (only shown once) */
|
|
11
|
+
newClientConfig: string | null;
|
|
12
|
+
}
|
|
13
|
+
export declare const vpnStatePart: plugins.deesElement.domtools.plugins.smartstate.StatePart<string, IVpnState>;
|
|
14
|
+
export declare const fetchVpnAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IVpnState, unknown>;
|
|
15
|
+
export declare const createVpnClientAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IVpnState, {
|
|
16
|
+
clientId: string;
|
|
17
|
+
targetProfileIds?: string[];
|
|
18
|
+
description?: string;
|
|
19
|
+
destinationAllowList?: string[];
|
|
20
|
+
destinationBlockList?: string[];
|
|
21
|
+
useHostIp?: boolean;
|
|
22
|
+
useDhcp?: boolean;
|
|
23
|
+
staticIp?: string;
|
|
24
|
+
forceVlan?: boolean;
|
|
25
|
+
vlanId?: number;
|
|
26
|
+
}>;
|
|
27
|
+
export declare const deleteVpnClientAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IVpnState, string>;
|
|
28
|
+
export declare const toggleVpnClientAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IVpnState, {
|
|
29
|
+
clientId: string;
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
export declare const updateVpnClientAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IVpnState, {
|
|
33
|
+
clientId: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
targetProfileIds?: string[];
|
|
36
|
+
destinationAllowList?: string[];
|
|
37
|
+
destinationBlockList?: string[];
|
|
38
|
+
useHostIp?: boolean;
|
|
39
|
+
useDhcp?: boolean;
|
|
40
|
+
staticIp?: string;
|
|
41
|
+
forceVlan?: boolean;
|
|
42
|
+
vlanId?: number;
|
|
43
|
+
}>;
|
|
44
|
+
export declare const clearNewClientConfigAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IVpnState, unknown>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
|
3
|
+
import { appState } from './shared.js';
|
|
4
|
+
import { getActionContext } from './login.js';
|
|
5
|
+
export const vpnStatePart = await appState.getStatePart('vpn', {
|
|
6
|
+
clients: [],
|
|
7
|
+
connectedClients: [],
|
|
8
|
+
status: null,
|
|
9
|
+
isLoading: false,
|
|
10
|
+
error: null,
|
|
11
|
+
lastUpdated: 0,
|
|
12
|
+
newClientConfig: null,
|
|
13
|
+
}, 'soft');
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// VPN Actions
|
|
16
|
+
// ============================================================================
|
|
17
|
+
export const fetchVpnAction = vpnStatePart.createAction(async (statePartArg) => {
|
|
18
|
+
const context = getActionContext();
|
|
19
|
+
const currentState = statePartArg.getState();
|
|
20
|
+
if (!context.identity)
|
|
21
|
+
return currentState;
|
|
22
|
+
try {
|
|
23
|
+
const clientsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'getVpnClients');
|
|
24
|
+
const statusRequest = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'getVpnStatus');
|
|
25
|
+
const connectedRequest = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'getVpnConnectedClients');
|
|
26
|
+
const [clientsResponse, statusResponse, connectedResponse] = await Promise.all([
|
|
27
|
+
clientsRequest.fire({ identity: context.identity }),
|
|
28
|
+
statusRequest.fire({ identity: context.identity }),
|
|
29
|
+
connectedRequest.fire({ identity: context.identity }),
|
|
30
|
+
]);
|
|
31
|
+
return {
|
|
32
|
+
...currentState,
|
|
33
|
+
clients: clientsResponse.clients,
|
|
34
|
+
connectedClients: connectedResponse.connectedClients,
|
|
35
|
+
status: statusResponse.status,
|
|
36
|
+
isLoading: false,
|
|
37
|
+
error: null,
|
|
38
|
+
lastUpdated: Date.now(),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return {
|
|
43
|
+
...currentState,
|
|
44
|
+
isLoading: false,
|
|
45
|
+
error: error instanceof Error ? error.message : 'Failed to fetch VPN data',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
export const createVpnClientAction = vpnStatePart.createAction(async (statePartArg, dataArg, actionContext) => {
|
|
50
|
+
const context = getActionContext();
|
|
51
|
+
const currentState = statePartArg.getState();
|
|
52
|
+
try {
|
|
53
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'createVpnClient');
|
|
54
|
+
const response = await request.fire({
|
|
55
|
+
identity: context.identity,
|
|
56
|
+
clientId: dataArg.clientId,
|
|
57
|
+
targetProfileIds: dataArg.targetProfileIds,
|
|
58
|
+
description: dataArg.description,
|
|
59
|
+
destinationAllowList: dataArg.destinationAllowList,
|
|
60
|
+
destinationBlockList: dataArg.destinationBlockList,
|
|
61
|
+
useHostIp: dataArg.useHostIp,
|
|
62
|
+
useDhcp: dataArg.useDhcp,
|
|
63
|
+
staticIp: dataArg.staticIp,
|
|
64
|
+
forceVlan: dataArg.forceVlan,
|
|
65
|
+
vlanId: dataArg.vlanId,
|
|
66
|
+
});
|
|
67
|
+
if (!response.success) {
|
|
68
|
+
return { ...currentState, error: response.message || 'Failed to create client' };
|
|
69
|
+
}
|
|
70
|
+
const refreshed = await actionContext.dispatch(fetchVpnAction, null);
|
|
71
|
+
return {
|
|
72
|
+
...refreshed,
|
|
73
|
+
newClientConfig: response.wireguardConfig || null,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return {
|
|
78
|
+
...currentState,
|
|
79
|
+
error: error instanceof Error ? error.message : 'Failed to create VPN client',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
export const deleteVpnClientAction = vpnStatePart.createAction(async (statePartArg, clientId, actionContext) => {
|
|
84
|
+
const context = getActionContext();
|
|
85
|
+
const currentState = statePartArg.getState();
|
|
86
|
+
try {
|
|
87
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'deleteVpnClient');
|
|
88
|
+
await request.fire({ identity: context.identity, clientId });
|
|
89
|
+
return await actionContext.dispatch(fetchVpnAction, null);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return {
|
|
93
|
+
...currentState,
|
|
94
|
+
error: error instanceof Error ? error.message : 'Failed to delete VPN client',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
export const toggleVpnClientAction = vpnStatePart.createAction(async (statePartArg, dataArg, actionContext) => {
|
|
99
|
+
const context = getActionContext();
|
|
100
|
+
const currentState = statePartArg.getState();
|
|
101
|
+
try {
|
|
102
|
+
const method = dataArg.enabled ? 'enableVpnClient' : 'disableVpnClient';
|
|
103
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', method);
|
|
104
|
+
await request.fire({ identity: context.identity, clientId: dataArg.clientId });
|
|
105
|
+
return await actionContext.dispatch(fetchVpnAction, null);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
return {
|
|
109
|
+
...currentState,
|
|
110
|
+
error: error instanceof Error ? error.message : 'Failed to toggle VPN client',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
export const updateVpnClientAction = vpnStatePart.createAction(async (statePartArg, dataArg, actionContext) => {
|
|
115
|
+
const context = getActionContext();
|
|
116
|
+
const currentState = statePartArg.getState();
|
|
117
|
+
try {
|
|
118
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'updateVpnClient');
|
|
119
|
+
const response = await request.fire({
|
|
120
|
+
identity: context.identity,
|
|
121
|
+
clientId: dataArg.clientId,
|
|
122
|
+
description: dataArg.description,
|
|
123
|
+
targetProfileIds: dataArg.targetProfileIds,
|
|
124
|
+
destinationAllowList: dataArg.destinationAllowList,
|
|
125
|
+
destinationBlockList: dataArg.destinationBlockList,
|
|
126
|
+
useHostIp: dataArg.useHostIp,
|
|
127
|
+
useDhcp: dataArg.useDhcp,
|
|
128
|
+
staticIp: dataArg.staticIp,
|
|
129
|
+
forceVlan: dataArg.forceVlan,
|
|
130
|
+
vlanId: dataArg.vlanId,
|
|
131
|
+
});
|
|
132
|
+
if (!response.success) {
|
|
133
|
+
return { ...currentState, error: response.message || 'Failed to update client' };
|
|
134
|
+
}
|
|
135
|
+
return await actionContext.dispatch(fetchVpnAction, null);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
return {
|
|
139
|
+
...currentState,
|
|
140
|
+
error: error instanceof Error ? error.message : 'Failed to update VPN client',
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
export const clearNewClientConfigAction = vpnStatePart.createAction(async (statePartArg) => {
|
|
145
|
+
return { ...statePartArg.getState(), newClientConfig: null };
|
|
146
|
+
});
|
|
147
|
+
// ============================================================================
|
|
148
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidnBuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHNfd2ViL2FwcHN0YXRlL3Zwbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssVUFBVSxNQUFNLDhCQUE4QixDQUFDO0FBQzNELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBaUI5QyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsTUFBTSxRQUFRLENBQUMsWUFBWSxDQUNyRCxLQUFLLEVBQ0w7SUFDRSxPQUFPLEVBQUUsRUFBRTtJQUNYLGdCQUFnQixFQUFFLEVBQUU7SUFDcEIsTUFBTSxFQUFFLElBQUk7SUFDWixTQUFTLEVBQUUsS0FBSztJQUNoQixLQUFLLEVBQUUsSUFBSTtJQUNYLFdBQVcsRUFBRSxDQUFDO0lBQ2QsZUFBZSxFQUFFLElBQUk7Q0FDdEIsRUFDRCxNQUFNLENBQ1AsQ0FBQztBQUVGLCtFQUErRTtBQUMvRSxjQUFjO0FBQ2QsK0VBQStFO0FBRS9FLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxZQUFZLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxZQUFZLEVBQXNCLEVBQUU7SUFDakcsTUFBTSxPQUFPLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQztJQUNuQyxNQUFNLFlBQVksR0FBRyxZQUFZLENBQUMsUUFBUSxFQUFHLENBQUM7SUFDOUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRO1FBQUUsT0FBTyxZQUFZLENBQUM7SUFFM0MsSUFBSSxDQUFDO1FBQ0gsTUFBTSxjQUFjLEdBQUcsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUUzRSxlQUFlLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFFcEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxP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
|