@serve.zone/dcrouter 7.4.3 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_serve/bundle.js +11567 -3516
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +9 -0
- package/dist_ts/classes.dcrouter.js +27 -1
- package/dist_ts/config/classes.api-token-manager.d.ts +38 -0
- package/dist_ts/config/classes.api-token-manager.js +134 -0
- package/dist_ts/config/classes.route-config-manager.d.ts +35 -0
- package/dist_ts/config/classes.route-config-manager.js +231 -0
- package/dist_ts/config/index.d.ts +2 -0
- package/dist_ts/config/index.js +3 -1
- package/dist_ts/opsserver/classes.opsserver.d.ts +2 -0
- package/dist_ts/opsserver/classes.opsserver.js +5 -1
- package/dist_ts/opsserver/handlers/{email-ops.handler.d.ts → api-token.handler.d.ts} +4 -4
- package/dist_ts/opsserver/handlers/api-token.handler.js +66 -0
- package/dist_ts/opsserver/handlers/index.d.ts +2 -0
- package/dist_ts/opsserver/handlers/index.js +3 -1
- package/dist_ts/opsserver/handlers/{radius.handler.d.ts → route-management.handler.d.ts} +6 -1
- package/dist_ts/opsserver/handlers/route-management.handler.js +117 -0
- package/dist_ts_interfaces/data/index.d.ts +1 -0
- package/dist_ts_interfaces/data/index.js +2 -1
- package/dist_ts_interfaces/data/route-management.d.ts +68 -0
- package/dist_ts_interfaces/data/route-management.js +2 -0
- package/dist_ts_interfaces/requests/api-tokens.d.ts +63 -0
- package/dist_ts_interfaces/requests/api-tokens.js +2 -0
- package/dist_ts_interfaces/requests/email-ops.d.ts +51 -108
- package/dist_ts_interfaces/requests/index.d.ts +2 -0
- package/dist_ts_interfaces/requests/index.js +3 -1
- package/dist_ts_interfaces/requests/route-management.d.ts +114 -0
- package/dist_ts_interfaces/requests/route-management.js +2 -0
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +38 -16
- package/dist_ts_web/appstate.js +226 -177
- package/dist_ts_web/elements/index.d.ts +2 -0
- package/dist_ts_web/elements/index.js +3 -1
- package/dist_ts_web/elements/ops-dashboard.js +11 -1
- package/dist_ts_web/elements/ops-view-apitokens.d.ts +12 -0
- package/dist_ts_web/elements/ops-view-apitokens.js +306 -0
- package/dist_ts_web/elements/ops-view-emails.d.ts +8 -31
- package/dist_ts_web/elements/ops-view-emails.js +54 -769
- package/dist_ts_web/elements/ops-view-logs.d.ts +2 -8
- package/dist_ts_web/elements/ops-view-logs.js +4 -101
- package/dist_ts_web/elements/ops-view-routes.d.ts +12 -0
- package/dist_ts_web/elements/ops-view-routes.js +404 -0
- package/dist_ts_web/plugins.d.ts +2 -1
- package/dist_ts_web/plugins.js +4 -2
- package/dist_ts_web/router.d.ts +1 -7
- package/dist_ts_web/router.js +8 -82
- package/package.json +2 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +37 -1
- package/ts/config/classes.api-token-manager.ts +155 -0
- package/ts/config/classes.route-config-manager.ts +271 -0
- package/ts/config/index.ts +3 -1
- package/ts/opsserver/classes.opsserver.ts +4 -0
- package/ts/opsserver/handlers/api-token.handler.ts +96 -0
- package/ts/opsserver/handlers/email-ops.handler.ts +177 -225
- package/ts/opsserver/handlers/index.ts +3 -1
- package/ts/opsserver/handlers/route-management.handler.ts +163 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +316 -222
- package/ts_web/elements/index.ts +2 -0
- package/ts_web/elements/ops-dashboard.ts +10 -0
- package/ts_web/elements/ops-view-apitokens.ts +281 -0
- package/ts_web/elements/ops-view-emails.ts +40 -749
- package/ts_web/elements/ops-view-logs.ts +2 -87
- package/ts_web/elements/ops-view-routes.ts +389 -0
- package/ts_web/plugins.ts +4 -0
- package/ts_web/router.ts +7 -82
- package/dist_ts/cache/classes.cache.cleaner.d.ts +0 -47
- package/dist_ts/cache/classes.cache.cleaner.js +0 -130
- package/dist_ts/cache/classes.cached.document.d.ts +0 -76
- package/dist_ts/cache/classes.cached.document.js +0 -100
- package/dist_ts/cache/classes.cachedb.d.ts +0 -60
- package/dist_ts/cache/classes.cachedb.js +0 -126
- package/dist_ts/cache/documents/classes.cached.email.d.ts +0 -125
- package/dist_ts/cache/documents/classes.cached.email.js +0 -337
- package/dist_ts/cache/documents/classes.cached.ip.reputation.d.ts +0 -119
- package/dist_ts/cache/documents/classes.cached.ip.reputation.js +0 -323
- package/dist_ts/cache/documents/index.d.ts +0 -2
- package/dist_ts/cache/documents/index.js +0 -3
- package/dist_ts/cache/index.d.ts +0 -4
- package/dist_ts/cache/index.js +0 -7
- package/dist_ts/monitoring/classes.metricscache.d.ts +0 -32
- package/dist_ts/monitoring/classes.metricscache.js +0 -63
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +0 -169
- package/dist_ts/monitoring/classes.metricsmanager.js +0 -591
- package/dist_ts/monitoring/index.d.ts +0 -1
- package/dist_ts/monitoring/index.js +0 -2
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +0 -31
- package/dist_ts/opsserver/handlers/admin.handler.js +0 -180
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -34
- package/dist_ts/opsserver/handlers/certificate.handler.js +0 -419
- package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -9
- package/dist_ts/opsserver/handlers/config.handler.js +0 -67
- package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -219
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -17
- package/dist_ts/opsserver/handlers/logs.handler.js +0 -215
- package/dist_ts/opsserver/handlers/radius.handler.js +0 -296
- package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -8
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -154
- package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -11
- package/dist_ts/opsserver/handlers/security.handler.js +0 -232
- package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -13
- package/dist_ts/opsserver/handlers/stats.handler.js +0 -400
- package/dist_ts/security/classes.securitylogger.d.ts +0 -140
- package/dist_ts/security/classes.securitylogger.js +0 -235
- package/dist_ts/storage/classes.storagemanager.d.ts +0 -82
- package/dist_ts/storage/classes.storagemanager.js +0 -344
- package/dist_ts/storage/index.d.ts +0 -1
- package/dist_ts/storage/index.js +0 -3
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
import type { StorageManager } from '../storage/index.js';
|
|
4
|
+
import type {
|
|
5
|
+
IStoredRoute,
|
|
6
|
+
IRouteOverride,
|
|
7
|
+
IMergedRoute,
|
|
8
|
+
IRouteWarning,
|
|
9
|
+
} from '../../ts_interfaces/data/route-management.js';
|
|
10
|
+
|
|
11
|
+
const ROUTES_PREFIX = '/config-api/routes/';
|
|
12
|
+
const OVERRIDES_PREFIX = '/config-api/overrides/';
|
|
13
|
+
|
|
14
|
+
export class RouteConfigManager {
|
|
15
|
+
private storedRoutes = new Map<string, IStoredRoute>();
|
|
16
|
+
private overrides = new Map<string, IRouteOverride>();
|
|
17
|
+
private warnings: IRouteWarning[] = [];
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
private storageManager: StorageManager,
|
|
21
|
+
private getHardcodedRoutes: () => plugins.smartproxy.IRouteConfig[],
|
|
22
|
+
private getSmartProxy: () => plugins.smartproxy.SmartProxy | undefined,
|
|
23
|
+
) {}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Load persisted routes and overrides, compute warnings, apply to SmartProxy.
|
|
27
|
+
*/
|
|
28
|
+
public async initialize(): Promise<void> {
|
|
29
|
+
await this.loadStoredRoutes();
|
|
30
|
+
await this.loadOverrides();
|
|
31
|
+
this.computeWarnings();
|
|
32
|
+
this.logWarnings();
|
|
33
|
+
await this.applyRoutes();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// =========================================================================
|
|
37
|
+
// Merged view
|
|
38
|
+
// =========================================================================
|
|
39
|
+
|
|
40
|
+
public getMergedRoutes(): { routes: IMergedRoute[]; warnings: IRouteWarning[] } {
|
|
41
|
+
const merged: IMergedRoute[] = [];
|
|
42
|
+
|
|
43
|
+
// Hardcoded routes
|
|
44
|
+
for (const route of this.getHardcodedRoutes()) {
|
|
45
|
+
const name = route.name || '';
|
|
46
|
+
const override = this.overrides.get(name);
|
|
47
|
+
merged.push({
|
|
48
|
+
route,
|
|
49
|
+
source: 'hardcoded',
|
|
50
|
+
enabled: override ? override.enabled : true,
|
|
51
|
+
overridden: !!override,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Programmatic routes
|
|
56
|
+
for (const stored of this.storedRoutes.values()) {
|
|
57
|
+
merged.push({
|
|
58
|
+
route: stored.route,
|
|
59
|
+
source: 'programmatic',
|
|
60
|
+
enabled: stored.enabled,
|
|
61
|
+
overridden: false,
|
|
62
|
+
storedRouteId: stored.id,
|
|
63
|
+
createdAt: stored.createdAt,
|
|
64
|
+
updatedAt: stored.updatedAt,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { routes: merged, warnings: [...this.warnings] };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// =========================================================================
|
|
72
|
+
// Programmatic route CRUD
|
|
73
|
+
// =========================================================================
|
|
74
|
+
|
|
75
|
+
public async createRoute(
|
|
76
|
+
route: plugins.smartproxy.IRouteConfig,
|
|
77
|
+
createdBy: string,
|
|
78
|
+
enabled = true,
|
|
79
|
+
): Promise<string> {
|
|
80
|
+
const id = plugins.uuid.v4();
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
|
|
83
|
+
// Ensure route has a name
|
|
84
|
+
if (!route.name) {
|
|
85
|
+
route.name = `programmatic-${id.slice(0, 8)}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const stored: IStoredRoute = {
|
|
89
|
+
id,
|
|
90
|
+
route,
|
|
91
|
+
enabled,
|
|
92
|
+
createdAt: now,
|
|
93
|
+
updatedAt: now,
|
|
94
|
+
createdBy,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
this.storedRoutes.set(id, stored);
|
|
98
|
+
await this.persistRoute(stored);
|
|
99
|
+
await this.applyRoutes();
|
|
100
|
+
return id;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public async updateRoute(
|
|
104
|
+
id: string,
|
|
105
|
+
patch: { route?: Partial<plugins.smartproxy.IRouteConfig>; enabled?: boolean },
|
|
106
|
+
): Promise<boolean> {
|
|
107
|
+
const stored = this.storedRoutes.get(id);
|
|
108
|
+
if (!stored) return false;
|
|
109
|
+
|
|
110
|
+
if (patch.route) {
|
|
111
|
+
stored.route = { ...stored.route, ...patch.route } as plugins.smartproxy.IRouteConfig;
|
|
112
|
+
}
|
|
113
|
+
if (patch.enabled !== undefined) {
|
|
114
|
+
stored.enabled = patch.enabled;
|
|
115
|
+
}
|
|
116
|
+
stored.updatedAt = Date.now();
|
|
117
|
+
|
|
118
|
+
await this.persistRoute(stored);
|
|
119
|
+
await this.applyRoutes();
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public async deleteRoute(id: string): Promise<boolean> {
|
|
124
|
+
if (!this.storedRoutes.has(id)) return false;
|
|
125
|
+
this.storedRoutes.delete(id);
|
|
126
|
+
await this.storageManager.delete(`${ROUTES_PREFIX}${id}.json`);
|
|
127
|
+
await this.applyRoutes();
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public async toggleRoute(id: string, enabled: boolean): Promise<boolean> {
|
|
132
|
+
return this.updateRoute(id, { enabled });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// =========================================================================
|
|
136
|
+
// Hardcoded route overrides
|
|
137
|
+
// =========================================================================
|
|
138
|
+
|
|
139
|
+
public async setOverride(routeName: string, enabled: boolean, updatedBy: string): Promise<void> {
|
|
140
|
+
const override: IRouteOverride = {
|
|
141
|
+
routeName,
|
|
142
|
+
enabled,
|
|
143
|
+
updatedAt: Date.now(),
|
|
144
|
+
updatedBy,
|
|
145
|
+
};
|
|
146
|
+
this.overrides.set(routeName, override);
|
|
147
|
+
await this.storageManager.setJSON(`${OVERRIDES_PREFIX}${routeName}.json`, override);
|
|
148
|
+
this.computeWarnings();
|
|
149
|
+
await this.applyRoutes();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public async removeOverride(routeName: string): Promise<boolean> {
|
|
153
|
+
if (!this.overrides.has(routeName)) return false;
|
|
154
|
+
this.overrides.delete(routeName);
|
|
155
|
+
await this.storageManager.delete(`${OVERRIDES_PREFIX}${routeName}.json`);
|
|
156
|
+
this.computeWarnings();
|
|
157
|
+
await this.applyRoutes();
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// =========================================================================
|
|
162
|
+
// Private: persistence
|
|
163
|
+
// =========================================================================
|
|
164
|
+
|
|
165
|
+
private async loadStoredRoutes(): Promise<void> {
|
|
166
|
+
const keys = await this.storageManager.list(ROUTES_PREFIX);
|
|
167
|
+
for (const key of keys) {
|
|
168
|
+
if (!key.endsWith('.json')) continue;
|
|
169
|
+
const stored = await this.storageManager.getJSON<IStoredRoute>(key);
|
|
170
|
+
if (stored?.id) {
|
|
171
|
+
this.storedRoutes.set(stored.id, stored);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (this.storedRoutes.size > 0) {
|
|
175
|
+
logger.log('info', `Loaded ${this.storedRoutes.size} programmatic route(s) from storage`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private async loadOverrides(): Promise<void> {
|
|
180
|
+
const keys = await this.storageManager.list(OVERRIDES_PREFIX);
|
|
181
|
+
for (const key of keys) {
|
|
182
|
+
if (!key.endsWith('.json')) continue;
|
|
183
|
+
const override = await this.storageManager.getJSON<IRouteOverride>(key);
|
|
184
|
+
if (override?.routeName) {
|
|
185
|
+
this.overrides.set(override.routeName, override);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (this.overrides.size > 0) {
|
|
189
|
+
logger.log('info', `Loaded ${this.overrides.size} route override(s) from storage`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private async persistRoute(stored: IStoredRoute): Promise<void> {
|
|
194
|
+
await this.storageManager.setJSON(`${ROUTES_PREFIX}${stored.id}.json`, stored);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// =========================================================================
|
|
198
|
+
// Private: warnings
|
|
199
|
+
// =========================================================================
|
|
200
|
+
|
|
201
|
+
private computeWarnings(): void {
|
|
202
|
+
this.warnings = [];
|
|
203
|
+
const hardcodedNames = new Set(this.getHardcodedRoutes().map((r) => r.name || ''));
|
|
204
|
+
|
|
205
|
+
// Check overrides
|
|
206
|
+
for (const [routeName, override] of this.overrides) {
|
|
207
|
+
if (!hardcodedNames.has(routeName)) {
|
|
208
|
+
this.warnings.push({
|
|
209
|
+
type: 'orphaned-override',
|
|
210
|
+
routeName,
|
|
211
|
+
message: `Orphaned override for route '${routeName}' — hardcoded route no longer exists`,
|
|
212
|
+
});
|
|
213
|
+
} else if (!override.enabled) {
|
|
214
|
+
this.warnings.push({
|
|
215
|
+
type: 'disabled-hardcoded',
|
|
216
|
+
routeName,
|
|
217
|
+
message: `Route '${routeName}' is disabled via API override`,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Check disabled programmatic routes
|
|
223
|
+
for (const stored of this.storedRoutes.values()) {
|
|
224
|
+
if (!stored.enabled) {
|
|
225
|
+
const name = stored.route.name || stored.id;
|
|
226
|
+
this.warnings.push({
|
|
227
|
+
type: 'disabled-programmatic',
|
|
228
|
+
routeName: name,
|
|
229
|
+
message: `Programmatic route '${name}' (id: ${stored.id}) is disabled`,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private logWarnings(): void {
|
|
236
|
+
for (const w of this.warnings) {
|
|
237
|
+
logger.log('warn', w.message);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// =========================================================================
|
|
242
|
+
// Private: apply merged routes to SmartProxy
|
|
243
|
+
// =========================================================================
|
|
244
|
+
|
|
245
|
+
private async applyRoutes(): Promise<void> {
|
|
246
|
+
const smartProxy = this.getSmartProxy();
|
|
247
|
+
if (!smartProxy) return;
|
|
248
|
+
|
|
249
|
+
const enabledRoutes: plugins.smartproxy.IRouteConfig[] = [];
|
|
250
|
+
|
|
251
|
+
// Add enabled hardcoded routes (respecting overrides)
|
|
252
|
+
for (const route of this.getHardcodedRoutes()) {
|
|
253
|
+
const name = route.name || '';
|
|
254
|
+
const override = this.overrides.get(name);
|
|
255
|
+
if (override && !override.enabled) {
|
|
256
|
+
continue; // Skip disabled hardcoded route
|
|
257
|
+
}
|
|
258
|
+
enabledRoutes.push(route);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Add enabled programmatic routes
|
|
262
|
+
for (const stored of this.storedRoutes.values()) {
|
|
263
|
+
if (stored.enabled) {
|
|
264
|
+
enabledRoutes.push(stored.route);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
await smartProxy.updateRoutes(enabledRoutes);
|
|
269
|
+
logger.log('info', `Applied ${enabledRoutes.length} routes to SmartProxy (${this.storedRoutes.size} programmatic, ${this.overrides.size} overrides)`);
|
|
270
|
+
}
|
|
271
|
+
}
|
package/ts/config/index.ts
CHANGED
|
@@ -20,6 +20,8 @@ export class OpsServer {
|
|
|
20
20
|
private emailOpsHandler: handlers.EmailOpsHandler;
|
|
21
21
|
private certificateHandler: handlers.CertificateHandler;
|
|
22
22
|
private remoteIngressHandler: handlers.RemoteIngressHandler;
|
|
23
|
+
private routeManagementHandler: handlers.RouteManagementHandler;
|
|
24
|
+
private apiTokenHandler: handlers.ApiTokenHandler;
|
|
23
25
|
|
|
24
26
|
constructor(dcRouterRefArg: DcRouter) {
|
|
25
27
|
this.dcRouterRef = dcRouterRefArg;
|
|
@@ -61,6 +63,8 @@ export class OpsServer {
|
|
|
61
63
|
this.emailOpsHandler = new handlers.EmailOpsHandler(this);
|
|
62
64
|
this.certificateHandler = new handlers.CertificateHandler(this);
|
|
63
65
|
this.remoteIngressHandler = new handlers.RemoteIngressHandler(this);
|
|
66
|
+
this.routeManagementHandler = new handlers.RouteManagementHandler(this);
|
|
67
|
+
this.apiTokenHandler = new handlers.ApiTokenHandler(this);
|
|
64
68
|
|
|
65
69
|
console.log('✅ OpsServer TypedRequest handlers initialized');
|
|
66
70
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
|
+
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
|
|
5
|
+
export class ApiTokenHandler {
|
|
6
|
+
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
7
|
+
|
|
8
|
+
constructor(private opsServerRef: OpsServer) {
|
|
9
|
+
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
10
|
+
this.registerHandlers();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Token management requires admin JWT only (tokens cannot manage tokens).
|
|
15
|
+
*/
|
|
16
|
+
private async requireAdmin(identity?: interfaces.data.IIdentity): Promise<string> {
|
|
17
|
+
if (!identity?.jwt) {
|
|
18
|
+
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
|
19
|
+
}
|
|
20
|
+
const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({ identity });
|
|
21
|
+
if (!isAdmin) {
|
|
22
|
+
throw new plugins.typedrequest.TypedResponseError('admin access required');
|
|
23
|
+
}
|
|
24
|
+
return identity.userId;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private registerHandlers(): void {
|
|
28
|
+
// Create API token
|
|
29
|
+
this.typedrouter.addTypedHandler(
|
|
30
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateApiToken>(
|
|
31
|
+
'createApiToken',
|
|
32
|
+
async (dataArg) => {
|
|
33
|
+
const userId = await this.requireAdmin(dataArg.identity);
|
|
34
|
+
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
35
|
+
if (!manager) {
|
|
36
|
+
return { success: false, message: 'Token management not initialized' };
|
|
37
|
+
}
|
|
38
|
+
const result = await manager.createToken(
|
|
39
|
+
dataArg.name,
|
|
40
|
+
dataArg.scopes,
|
|
41
|
+
dataArg.expiresInDays ?? null,
|
|
42
|
+
userId,
|
|
43
|
+
);
|
|
44
|
+
return { success: true, tokenId: result.id, tokenValue: result.rawToken };
|
|
45
|
+
},
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// List API tokens
|
|
50
|
+
this.typedrouter.addTypedHandler(
|
|
51
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListApiTokens>(
|
|
52
|
+
'listApiTokens',
|
|
53
|
+
async (dataArg) => {
|
|
54
|
+
await this.requireAdmin(dataArg.identity);
|
|
55
|
+
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
56
|
+
if (!manager) {
|
|
57
|
+
return { tokens: [] };
|
|
58
|
+
}
|
|
59
|
+
return { tokens: manager.listTokens() };
|
|
60
|
+
},
|
|
61
|
+
),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Revoke API token
|
|
65
|
+
this.typedrouter.addTypedHandler(
|
|
66
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RevokeApiToken>(
|
|
67
|
+
'revokeApiToken',
|
|
68
|
+
async (dataArg) => {
|
|
69
|
+
await this.requireAdmin(dataArg.identity);
|
|
70
|
+
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
71
|
+
if (!manager) {
|
|
72
|
+
return { success: false, message: 'Token management not initialized' };
|
|
73
|
+
}
|
|
74
|
+
const ok = await manager.revokeToken(dataArg.id);
|
|
75
|
+
return { success: ok, message: ok ? undefined : 'Token not found' };
|
|
76
|
+
},
|
|
77
|
+
),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// Toggle API token
|
|
81
|
+
this.typedrouter.addTypedHandler(
|
|
82
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ToggleApiToken>(
|
|
83
|
+
'toggleApiToken',
|
|
84
|
+
async (dataArg) => {
|
|
85
|
+
await this.requireAdmin(dataArg.identity);
|
|
86
|
+
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
87
|
+
if (!manager) {
|
|
88
|
+
return { success: false, message: 'Token management not initialized' };
|
|
89
|
+
}
|
|
90
|
+
const ok = await manager.toggleToken(dataArg.id, dataArg.enabled);
|
|
91
|
+
return { success: ok, message: ok ? undefined : 'Token not found' };
|
|
92
|
+
},
|
|
93
|
+
),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|