@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
package/package.json
CHANGED
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as interfaces from '../../ts_interfaces/index.js';
|
|
3
|
+
import { appState } from './shared.js';
|
|
4
|
+
import { getActionContext } from './login.js';
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// ACME Config State (DB-backed singleton, managed via Domains > Certificates)
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
export interface IAcmeConfigState {
|
|
11
|
+
config: interfaces.data.IAcmeConfig | null;
|
|
12
|
+
isLoading: boolean;
|
|
13
|
+
error: string | null;
|
|
14
|
+
lastUpdated: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const acmeConfigStatePart = await appState.getStatePart<IAcmeConfigState>(
|
|
18
|
+
'acmeConfig',
|
|
19
|
+
{
|
|
20
|
+
config: null,
|
|
21
|
+
isLoading: false,
|
|
22
|
+
error: null,
|
|
23
|
+
lastUpdated: 0,
|
|
24
|
+
},
|
|
25
|
+
'soft',
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// ACME Config Actions
|
|
29
|
+
// ============================================================================
|
|
30
|
+
|
|
31
|
+
export const fetchAcmeConfigAction = acmeConfigStatePart.createAction(
|
|
32
|
+
async (statePartArg): Promise<IAcmeConfigState> => {
|
|
33
|
+
const context = getActionContext();
|
|
34
|
+
const currentState = statePartArg.getState()!;
|
|
35
|
+
if (!context.identity) return currentState;
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
39
|
+
interfaces.requests.IReq_GetAcmeConfig
|
|
40
|
+
>('/typedrequest', 'getAcmeConfig');
|
|
41
|
+
const response = await request.fire({ identity: context.identity });
|
|
42
|
+
return {
|
|
43
|
+
config: response.config,
|
|
44
|
+
isLoading: false,
|
|
45
|
+
error: null,
|
|
46
|
+
lastUpdated: Date.now(),
|
|
47
|
+
};
|
|
48
|
+
} catch (error: unknown) {
|
|
49
|
+
return {
|
|
50
|
+
...currentState,
|
|
51
|
+
isLoading: false,
|
|
52
|
+
error: error instanceof Error ? error.message : 'Failed to fetch ACME config',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export const updateAcmeConfigAction = acmeConfigStatePart.createAction<{
|
|
59
|
+
accountEmail?: string;
|
|
60
|
+
enabled?: boolean;
|
|
61
|
+
useProduction?: boolean;
|
|
62
|
+
autoRenew?: boolean;
|
|
63
|
+
renewThresholdDays?: number;
|
|
64
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IAcmeConfigState> => {
|
|
65
|
+
const context = getActionContext();
|
|
66
|
+
try {
|
|
67
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
68
|
+
interfaces.requests.IReq_UpdateAcmeConfig
|
|
69
|
+
>('/typedrequest', 'updateAcmeConfig');
|
|
70
|
+
const response = await request.fire({
|
|
71
|
+
identity: context.identity!,
|
|
72
|
+
accountEmail: dataArg.accountEmail,
|
|
73
|
+
enabled: dataArg.enabled,
|
|
74
|
+
useProduction: dataArg.useProduction,
|
|
75
|
+
autoRenew: dataArg.autoRenew,
|
|
76
|
+
renewThresholdDays: dataArg.renewThresholdDays,
|
|
77
|
+
});
|
|
78
|
+
if (!response.success) {
|
|
79
|
+
return {
|
|
80
|
+
...statePartArg.getState()!,
|
|
81
|
+
error: response.message || 'Failed to update ACME config',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return await actionContext!.dispatch(fetchAcmeConfigAction, null);
|
|
85
|
+
} catch (error: unknown) {
|
|
86
|
+
return {
|
|
87
|
+
...statePartArg.getState()!,
|
|
88
|
+
error: error instanceof Error ? error.message : 'Failed to update ACME config',
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// ============================================================================
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import type * as servezoneInterfaces from '@serve.zone/interfaces';
|
|
3
|
+
import * as interfaces from '../../ts_interfaces/index.js';
|
|
4
|
+
import { appState } from './shared.js';
|
|
5
|
+
import { getActionContext } from './login.js';
|
|
6
|
+
|
|
7
|
+
export interface ICertificateState {
|
|
8
|
+
certificates: interfaces.requests.ICertificateInfo[];
|
|
9
|
+
summary: { total: number; valid: number; expiring: number; expired: number; failed: number; unknown: number };
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
error: string | null;
|
|
12
|
+
lastUpdated: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const certificateStatePart = await appState.getStatePart<ICertificateState>(
|
|
16
|
+
'certificates',
|
|
17
|
+
{
|
|
18
|
+
certificates: [],
|
|
19
|
+
summary: { total: 0, valid: 0, expiring: 0, expired: 0, failed: 0, unknown: 0 },
|
|
20
|
+
isLoading: false,
|
|
21
|
+
error: null,
|
|
22
|
+
lastUpdated: 0,
|
|
23
|
+
},
|
|
24
|
+
'soft'
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Certificate Actions
|
|
28
|
+
// ============================================================================
|
|
29
|
+
|
|
30
|
+
export const fetchCertificateOverviewAction = certificateStatePart.createAction(async (statePartArg): Promise<ICertificateState> => {
|
|
31
|
+
const context = getActionContext();
|
|
32
|
+
const currentState = statePartArg.getState()!;
|
|
33
|
+
if (!context.identity) return currentState;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
37
|
+
interfaces.requests.IReq_GetCertificateOverview
|
|
38
|
+
>('/typedrequest', 'getCertificateOverview');
|
|
39
|
+
|
|
40
|
+
const response = await request.fire({
|
|
41
|
+
identity: context.identity,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
certificates: response.certificates,
|
|
46
|
+
summary: response.summary,
|
|
47
|
+
isLoading: false,
|
|
48
|
+
error: null,
|
|
49
|
+
lastUpdated: Date.now(),
|
|
50
|
+
};
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return {
|
|
53
|
+
...currentState,
|
|
54
|
+
isLoading: false,
|
|
55
|
+
error: error instanceof Error ? error.message : 'Failed to fetch certificate overview',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export const reprovisionCertificateAction = certificateStatePart.createAction<{ domain: string; forceRenew?: boolean }>(
|
|
61
|
+
async (statePartArg, dataArg, actionContext): Promise<ICertificateState> => {
|
|
62
|
+
const context = getActionContext();
|
|
63
|
+
const currentState = statePartArg.getState()!;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
67
|
+
interfaces.requests.IReq_ReprovisionCertificateDomain
|
|
68
|
+
>('/typedrequest', 'reprovisionCertificateDomain');
|
|
69
|
+
|
|
70
|
+
await request.fire({
|
|
71
|
+
identity: context.identity!,
|
|
72
|
+
domain: dataArg.domain,
|
|
73
|
+
forceRenew: dataArg.forceRenew,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Re-fetch overview after reprovisioning
|
|
77
|
+
return await actionContext!.dispatch(fetchCertificateOverviewAction, null);
|
|
78
|
+
} catch (error: unknown) {
|
|
79
|
+
return {
|
|
80
|
+
...currentState,
|
|
81
|
+
error: error instanceof Error ? error.message : 'Failed to reprovision certificate',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
export const deleteCertificateAction = certificateStatePart.createAction<string>(
|
|
88
|
+
async (statePartArg, domain, actionContext): Promise<ICertificateState> => {
|
|
89
|
+
const context = getActionContext();
|
|
90
|
+
const currentState = statePartArg.getState()!;
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
94
|
+
interfaces.requests.IReq_DeleteCertificate
|
|
95
|
+
>('/typedrequest', 'deleteCertificate');
|
|
96
|
+
|
|
97
|
+
await request.fire({
|
|
98
|
+
identity: context.identity!,
|
|
99
|
+
domain,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Re-fetch overview after deletion
|
|
103
|
+
return await actionContext!.dispatch(fetchCertificateOverviewAction, null);
|
|
104
|
+
} catch (error: unknown) {
|
|
105
|
+
return {
|
|
106
|
+
...currentState,
|
|
107
|
+
error: error instanceof Error ? error.message : 'Failed to delete certificate',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
export const importCertificateAction = certificateStatePart.createAction<{
|
|
114
|
+
id: string;
|
|
115
|
+
domainName: string;
|
|
116
|
+
created: number;
|
|
117
|
+
validUntil: number;
|
|
118
|
+
privateKey: string;
|
|
119
|
+
publicKey: string;
|
|
120
|
+
csr: string;
|
|
121
|
+
}>(
|
|
122
|
+
async (statePartArg, cert, actionContext): Promise<ICertificateState> => {
|
|
123
|
+
const context = getActionContext();
|
|
124
|
+
const currentState = statePartArg.getState()!;
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
128
|
+
servezoneInterfaces.requests.gateway.IReq_ImportCertificate
|
|
129
|
+
>('/typedrequest', 'importCertificate');
|
|
130
|
+
|
|
131
|
+
await request.fire({
|
|
132
|
+
identity: context.identity!,
|
|
133
|
+
cert,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Re-fetch overview after import
|
|
137
|
+
return await actionContext!.dispatch(fetchCertificateOverviewAction, null);
|
|
138
|
+
} catch (error: unknown) {
|
|
139
|
+
return {
|
|
140
|
+
...currentState,
|
|
141
|
+
error: error instanceof Error ? error.message : 'Failed to import certificate',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
export async function fetchCertificateExport(domain: string) {
|
|
148
|
+
const context = getActionContext();
|
|
149
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
150
|
+
servezoneInterfaces.requests.gateway.IReq_ExportCertificate
|
|
151
|
+
>('/typedrequest', 'exportCertificate');
|
|
152
|
+
|
|
153
|
+
return request.fire({
|
|
154
|
+
identity: context.identity!,
|
|
155
|
+
domain,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ============================================================================
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as interfaces from '../../ts_interfaces/index.js';
|
|
3
|
+
import { appState } from './shared.js';
|
|
4
|
+
import { getActionContext } from './login.js';
|
|
5
|
+
|
|
6
|
+
export interface IConfigState {
|
|
7
|
+
config: interfaces.requests.IConfigData | null;
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
error: string | null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const configStatePart = await appState.getStatePart<IConfigState>(
|
|
13
|
+
'config',
|
|
14
|
+
{
|
|
15
|
+
config: null,
|
|
16
|
+
isLoading: false,
|
|
17
|
+
error: null,
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// Fetch Configuration Action (read-only)
|
|
22
|
+
export const fetchConfigurationAction = configStatePart.createAction(async (statePartArg): Promise<IConfigState> => {
|
|
23
|
+
const context = getActionContext();
|
|
24
|
+
const currentState = statePartArg.getState()!;
|
|
25
|
+
if (!context.identity) return currentState;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const configRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
29
|
+
interfaces.requests.IReq_GetConfiguration
|
|
30
|
+
>('/typedrequest', 'getConfiguration');
|
|
31
|
+
|
|
32
|
+
const response = await configRequest.fire({
|
|
33
|
+
identity: context.identity,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
config: response.config,
|
|
38
|
+
isLoading: false,
|
|
39
|
+
error: null,
|
|
40
|
+
};
|
|
41
|
+
} catch (error: unknown) {
|
|
42
|
+
return {
|
|
43
|
+
...currentState,
|
|
44
|
+
isLoading: false,
|
|
45
|
+
error: (error as Error).message || 'Failed to fetch configuration',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|