@serve.zone/dcrouter 13.31.0 → 13.32.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 +721 -721
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/opsserver/classes.opsserver.d.ts +4 -2
- package/dist_ts/opsserver/classes.opsserver.js +2 -11
- package/dist_ts/opsserver/handlers/acme-config.handler.js +7 -24
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +1 -0
- package/dist_ts/opsserver/handlers/admin.handler.js +58 -88
- package/dist_ts/opsserver/handlers/api-token.handler.js +28 -2
- package/dist_ts/opsserver/handlers/certificate.handler.js +7 -24
- package/dist_ts/opsserver/handlers/config.handler.js +3 -1
- package/dist_ts/opsserver/handlers/dns-provider.handler.js +7 -24
- package/dist_ts/opsserver/handlers/dns-record.handler.js +7 -24
- package/dist_ts/opsserver/handlers/domain.handler.js +7 -24
- package/dist_ts/opsserver/handlers/email-domain.handler.js +7 -24
- package/dist_ts/opsserver/handlers/email-ops.handler.js +8 -1
- package/dist_ts/opsserver/handlers/logs.handler.js +4 -1
- package/dist_ts/opsserver/handlers/network-target.handler.js +7 -24
- package/dist_ts/opsserver/handlers/radius.handler.js +32 -1
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +24 -1
- package/dist_ts/opsserver/handlers/route-management.handler.js +7 -26
- package/dist_ts/opsserver/handlers/security.handler.js +32 -7
- package/dist_ts/opsserver/handlers/source-profile.handler.js +7 -24
- package/dist_ts/opsserver/handlers/stats.handler.js +8 -1
- package/dist_ts/opsserver/handlers/target-profile.handler.js +7 -24
- package/dist_ts/opsserver/handlers/users.handler.js +33 -13
- package/dist_ts/opsserver/handlers/vpn.handler.js +34 -1
- package/dist_ts/opsserver/handlers/workhoster.handler.js +16 -35
- package/dist_ts/opsserver/helpers/auth.d.ts +21 -0
- package/dist_ts/opsserver/helpers/auth.js +63 -0
- package/dist_ts_interfaces/data/route-management.d.ts +2 -1
- package/dist_ts_interfaces/data/route-management.js +48 -2
- package/dist_ts_interfaces/requests/api-tokens.d.ts +10 -5
- package/dist_ts_interfaces/requests/combined.stats.d.ts +2 -1
- package/dist_ts_interfaces/requests/config.d.ts +2 -1
- package/dist_ts_interfaces/requests/email-ops.d.ts +6 -3
- package/dist_ts_interfaces/requests/logs.d.ts +4 -2
- package/dist_ts_interfaces/requests/radius.d.ts +24 -12
- package/dist_ts_interfaces/requests/remoteingress.d.ts +14 -7
- package/dist_ts_interfaces/requests/security-policy.d.ts +16 -8
- package/dist_ts_interfaces/requests/stats.d.ts +18 -9
- package/dist_ts_interfaces/requests/users.d.ts +6 -3
- package/dist_ts_interfaces/requests/vpn.d.ts +22 -11
- package/dist_ts_interfaces/requests/workhoster.d.ts +10 -5
- package/dist_ts_migrations/index.js +3 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/access/ops-view-apitokens.js +2 -21
- package/package.json +2 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/opsserver/classes.opsserver.ts +3 -14
- package/ts/opsserver/handlers/acme-config.handler.ts +6 -23
- package/ts/opsserver/handlers/admin.handler.ts +64 -101
- package/ts/opsserver/handlers/api-token.handler.ts +27 -1
- package/ts/opsserver/handlers/certificate.handler.ts +6 -23
- package/ts/opsserver/handlers/config.handler.ts +2 -0
- package/ts/opsserver/handlers/dns-provider.handler.ts +6 -23
- package/ts/opsserver/handlers/dns-record.handler.ts +6 -23
- package/ts/opsserver/handlers/domain.handler.ts +6 -23
- package/ts/opsserver/handlers/email-domain.handler.ts +6 -23
- package/ts/opsserver/handlers/email-ops.handler.ts +7 -0
- package/ts/opsserver/handlers/logs.handler.ts +3 -0
- package/ts/opsserver/handlers/network-target.handler.ts +6 -23
- package/ts/opsserver/handlers/radius.handler.ts +31 -0
- package/ts/opsserver/handlers/remoteingress.handler.ts +23 -0
- package/ts/opsserver/handlers/route-management.handler.ts +6 -25
- package/ts/opsserver/handlers/security.handler.ts +31 -6
- package/ts/opsserver/handlers/source-profile.handler.ts +6 -23
- package/ts/opsserver/handlers/stats.handler.ts +7 -0
- package/ts/opsserver/handlers/target-profile.handler.ts +6 -23
- package/ts/opsserver/handlers/users.handler.ts +32 -12
- package/ts/opsserver/handlers/vpn.handler.ts +33 -0
- package/ts/opsserver/handlers/workhoster.handler.ts +18 -33
- package/ts/opsserver/helpers/auth.ts +91 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/access/ops-view-apitokens.ts +1 -20
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* CRUD handlers for DomainDoc.
|
|
@@ -17,29 +18,11 @@ export class DomainHandler {
|
|
|
17
18
|
request: { identity?: interfaces.data.IIdentity; apiToken?: string },
|
|
18
19
|
requiredScope?: interfaces.data.TApiTokenScope,
|
|
19
20
|
): Promise<string> {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (isAdmin) return request.identity.userId;
|
|
26
|
-
} catch { /* fall through */ }
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (request.apiToken) {
|
|
30
|
-
const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
31
|
-
if (tokenManager) {
|
|
32
|
-
const token = await tokenManager.validateToken(request.apiToken);
|
|
33
|
-
if (token) {
|
|
34
|
-
if (!requiredScope || tokenManager.hasScope(token, requiredScope)) {
|
|
35
|
-
return token.createdBy;
|
|
36
|
-
}
|
|
37
|
-
throw new plugins.typedrequest.TypedResponseError('insufficient scope');
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
|
21
|
+
const auth = await requireOpsAuth(this.opsServerRef, request, {
|
|
22
|
+
scope: requiredScope,
|
|
23
|
+
requireAdminIdentity: requiredScope?.endsWith(':write'),
|
|
24
|
+
});
|
|
25
|
+
return auth.userId;
|
|
43
26
|
}
|
|
44
27
|
|
|
45
28
|
private registerHandlers(): void {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* CRUD + DNS provisioning handler for email domains.
|
|
@@ -19,29 +20,11 @@ export class EmailDomainHandler {
|
|
|
19
20
|
request: { identity?: interfaces.data.IIdentity; apiToken?: string },
|
|
20
21
|
requiredScope?: interfaces.data.TApiTokenScope,
|
|
21
22
|
): Promise<string> {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (isAdmin) return request.identity.userId;
|
|
28
|
-
} catch { /* fall through */ }
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (request.apiToken) {
|
|
32
|
-
const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
33
|
-
if (tokenManager) {
|
|
34
|
-
const token = await tokenManager.validateToken(request.apiToken);
|
|
35
|
-
if (token) {
|
|
36
|
-
if (!requiredScope || tokenManager.hasScope(token, requiredScope)) {
|
|
37
|
-
return token.createdBy;
|
|
38
|
-
}
|
|
39
|
-
throw new plugins.typedrequest.TypedResponseError('insufficient scope');
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
|
23
|
+
const auth = await requireOpsAuth(this.opsServerRef, request, {
|
|
24
|
+
scope: requiredScope,
|
|
25
|
+
requireAdminIdentity: requiredScope?.endsWith(':write'),
|
|
26
|
+
});
|
|
27
|
+
return auth.userId;
|
|
45
28
|
}
|
|
46
29
|
|
|
47
30
|
private get manager() {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
4
5
|
|
|
5
6
|
export class EmailOpsHandler {
|
|
6
7
|
constructor(private opsServerRef: OpsServer) {
|
|
@@ -18,6 +19,7 @@ export class EmailOpsHandler {
|
|
|
18
19
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetAllEmails>(
|
|
19
20
|
'getAllEmails',
|
|
20
21
|
async (dataArg) => {
|
|
22
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'emails:read' });
|
|
21
23
|
const emails = this.getAllQueueEmails();
|
|
22
24
|
return { emails };
|
|
23
25
|
}
|
|
@@ -29,6 +31,7 @@ export class EmailOpsHandler {
|
|
|
29
31
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetEmailDetail>(
|
|
30
32
|
'getEmailDetail',
|
|
31
33
|
async (dataArg) => {
|
|
34
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'emails:read' });
|
|
32
35
|
const email = this.getEmailDetail(dataArg.emailId);
|
|
33
36
|
return { email };
|
|
34
37
|
}
|
|
@@ -42,6 +45,10 @@ export class EmailOpsHandler {
|
|
|
42
45
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ResendEmail>(
|
|
43
46
|
'resendEmail',
|
|
44
47
|
async (dataArg) => {
|
|
48
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
49
|
+
scope: 'emails:write',
|
|
50
|
+
requireAdminIdentity: true,
|
|
51
|
+
});
|
|
45
52
|
const emailServer = this.opsServerRef.dcRouterRef.emailServer;
|
|
46
53
|
if (!emailServer?.deliveryQueue) {
|
|
47
54
|
return { success: false, error: 'Email server not available' };
|
|
@@ -2,6 +2,7 @@ import * as plugins from '../../plugins.js';
|
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
4
|
import { logBuffer, baseLogger } from '../../logger.js';
|
|
5
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
5
6
|
|
|
6
7
|
// Module-level singleton: the log push destination is added once and reuses
|
|
7
8
|
// the current OpsServer reference so it survives OpsServer restarts without
|
|
@@ -40,6 +41,7 @@ export class LogsHandler {
|
|
|
40
41
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRecentLogs>(
|
|
41
42
|
'getRecentLogs',
|
|
42
43
|
async (dataArg, toolsArg) => {
|
|
44
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'logs:read' });
|
|
43
45
|
const logs = await this.getRecentLogs(
|
|
44
46
|
dataArg.level,
|
|
45
47
|
dataArg.category,
|
|
@@ -63,6 +65,7 @@ export class LogsHandler {
|
|
|
63
65
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetLogStream>(
|
|
64
66
|
'getLogStream',
|
|
65
67
|
async (dataArg, toolsArg) => {
|
|
68
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'logs:read' });
|
|
66
69
|
// Create a virtual stream for log streaming
|
|
67
70
|
const virtualStream = new plugins.typedrequest.VirtualStream<Uint8Array>();
|
|
68
71
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
4
5
|
|
|
5
6
|
export class NetworkTargetHandler {
|
|
6
7
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
@@ -14,29 +15,11 @@ export class NetworkTargetHandler {
|
|
|
14
15
|
request: { identity?: interfaces.data.IIdentity; apiToken?: string },
|
|
15
16
|
requiredScope?: interfaces.data.TApiTokenScope,
|
|
16
17
|
): Promise<string> {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (isAdmin) return request.identity.userId;
|
|
23
|
-
} catch { /* fall through */ }
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (request.apiToken) {
|
|
27
|
-
const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
28
|
-
if (tokenManager) {
|
|
29
|
-
const token = await tokenManager.validateToken(request.apiToken);
|
|
30
|
-
if (token) {
|
|
31
|
-
if (!requiredScope || tokenManager.hasScope(token, requiredScope)) {
|
|
32
|
-
return token.createdBy;
|
|
33
|
-
}
|
|
34
|
-
throw new plugins.typedrequest.TypedResponseError('insufficient scope');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
|
18
|
+
const auth = await requireOpsAuth(this.opsServerRef, request, {
|
|
19
|
+
scope: requiredScope,
|
|
20
|
+
requireAdminIdentity: requiredScope?.endsWith(':write'),
|
|
21
|
+
});
|
|
22
|
+
return auth.userId;
|
|
40
23
|
}
|
|
41
24
|
|
|
42
25
|
private registerHandlers(): void {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
4
5
|
|
|
5
6
|
export class RadiusHandler {
|
|
6
7
|
constructor(private opsServerRef: OpsServer) {
|
|
@@ -19,6 +20,7 @@ export class RadiusHandler {
|
|
|
19
20
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusClients>(
|
|
20
21
|
'getRadiusClients',
|
|
21
22
|
async (dataArg, toolsArg) => {
|
|
23
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
|
|
22
24
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
23
25
|
|
|
24
26
|
if (!radiusServer) {
|
|
@@ -43,6 +45,10 @@ export class RadiusHandler {
|
|
|
43
45
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SetRadiusClient>(
|
|
44
46
|
'setRadiusClient',
|
|
45
47
|
async (dataArg, toolsArg) => {
|
|
48
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
49
|
+
scope: 'radius:write',
|
|
50
|
+
requireAdminIdentity: true,
|
|
51
|
+
});
|
|
46
52
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
47
53
|
|
|
48
54
|
if (!radiusServer) {
|
|
@@ -64,6 +70,10 @@ export class RadiusHandler {
|
|
|
64
70
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RemoveRadiusClient>(
|
|
65
71
|
'removeRadiusClient',
|
|
66
72
|
async (dataArg, toolsArg) => {
|
|
73
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
74
|
+
scope: 'radius:write',
|
|
75
|
+
requireAdminIdentity: true,
|
|
76
|
+
});
|
|
67
77
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
68
78
|
|
|
69
79
|
if (!radiusServer) {
|
|
@@ -88,6 +98,7 @@ export class RadiusHandler {
|
|
|
88
98
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetVlanMappings>(
|
|
89
99
|
'getVlanMappings',
|
|
90
100
|
async (dataArg, toolsArg) => {
|
|
101
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
|
|
91
102
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
92
103
|
|
|
93
104
|
if (!radiusServer) {
|
|
@@ -124,6 +135,10 @@ export class RadiusHandler {
|
|
|
124
135
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SetVlanMapping>(
|
|
125
136
|
'setVlanMapping',
|
|
126
137
|
async (dataArg, toolsArg) => {
|
|
138
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
139
|
+
scope: 'radius:write',
|
|
140
|
+
requireAdminIdentity: true,
|
|
141
|
+
});
|
|
127
142
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
128
143
|
|
|
129
144
|
if (!radiusServer) {
|
|
@@ -156,6 +171,10 @@ export class RadiusHandler {
|
|
|
156
171
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RemoveVlanMapping>(
|
|
157
172
|
'removeVlanMapping',
|
|
158
173
|
async (dataArg, toolsArg) => {
|
|
174
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
175
|
+
scope: 'radius:write',
|
|
176
|
+
requireAdminIdentity: true,
|
|
177
|
+
});
|
|
159
178
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
160
179
|
|
|
161
180
|
if (!radiusServer) {
|
|
@@ -177,6 +196,10 @@ export class RadiusHandler {
|
|
|
177
196
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateVlanConfig>(
|
|
178
197
|
'updateVlanConfig',
|
|
179
198
|
async (dataArg, toolsArg) => {
|
|
199
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
200
|
+
scope: 'radius:write',
|
|
201
|
+
requireAdminIdentity: true,
|
|
202
|
+
});
|
|
180
203
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
181
204
|
|
|
182
205
|
if (!radiusServer) {
|
|
@@ -209,6 +232,7 @@ export class RadiusHandler {
|
|
|
209
232
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_TestVlanAssignment>(
|
|
210
233
|
'testVlanAssignment',
|
|
211
234
|
async (dataArg, toolsArg) => {
|
|
235
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
|
|
212
236
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
213
237
|
|
|
214
238
|
if (!radiusServer) {
|
|
@@ -243,6 +267,7 @@ export class RadiusHandler {
|
|
|
243
267
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusSessions>(
|
|
244
268
|
'getRadiusSessions',
|
|
245
269
|
async (dataArg, toolsArg) => {
|
|
270
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
|
|
246
271
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
247
272
|
|
|
248
273
|
if (!radiusServer) {
|
|
@@ -292,6 +317,10 @@ export class RadiusHandler {
|
|
|
292
317
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DisconnectRadiusSession>(
|
|
293
318
|
'disconnectRadiusSession',
|
|
294
319
|
async (dataArg, toolsArg) => {
|
|
320
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
321
|
+
scope: 'radius:write',
|
|
322
|
+
requireAdminIdentity: true,
|
|
323
|
+
});
|
|
295
324
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
296
325
|
|
|
297
326
|
if (!radiusServer) {
|
|
@@ -317,6 +346,7 @@ export class RadiusHandler {
|
|
|
317
346
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusAccountingSummary>(
|
|
318
347
|
'getRadiusAccountingSummary',
|
|
319
348
|
async (dataArg, toolsArg) => {
|
|
349
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
|
|
320
350
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
321
351
|
|
|
322
352
|
if (!radiusServer) {
|
|
@@ -354,6 +384,7 @@ export class RadiusHandler {
|
|
|
354
384
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusStatistics>(
|
|
355
385
|
'getRadiusStatistics',
|
|
356
386
|
async (dataArg, toolsArg) => {
|
|
387
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
|
|
357
388
|
const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
|
|
358
389
|
|
|
359
390
|
if (!radiusServer) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
4
5
|
|
|
5
6
|
export class RemoteIngressHandler {
|
|
6
7
|
constructor(private opsServerRef: OpsServer) {
|
|
@@ -18,6 +19,7 @@ export class RemoteIngressHandler {
|
|
|
18
19
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngresses>(
|
|
19
20
|
'getRemoteIngresses',
|
|
20
21
|
async (dataArg, toolsArg) => {
|
|
22
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'remote-ingress:read' });
|
|
21
23
|
const manager = this.opsServerRef.dcRouterRef.remoteIngressManager;
|
|
22
24
|
if (!manager) {
|
|
23
25
|
return { edges: [] };
|
|
@@ -46,6 +48,10 @@ export class RemoteIngressHandler {
|
|
|
46
48
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateRemoteIngress>(
|
|
47
49
|
'createRemoteIngress',
|
|
48
50
|
async (dataArg, toolsArg) => {
|
|
51
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
52
|
+
scope: 'remote-ingress:write',
|
|
53
|
+
requireAdminIdentity: true,
|
|
54
|
+
});
|
|
49
55
|
const manager = this.opsServerRef.dcRouterRef.remoteIngressManager;
|
|
50
56
|
const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager;
|
|
51
57
|
|
|
@@ -78,6 +84,10 @@ export class RemoteIngressHandler {
|
|
|
78
84
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteRemoteIngress>(
|
|
79
85
|
'deleteRemoteIngress',
|
|
80
86
|
async (dataArg, toolsArg) => {
|
|
87
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
88
|
+
scope: 'remote-ingress:write',
|
|
89
|
+
requireAdminIdentity: true,
|
|
90
|
+
});
|
|
81
91
|
const manager = this.opsServerRef.dcRouterRef.remoteIngressManager;
|
|
82
92
|
const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager;
|
|
83
93
|
|
|
@@ -103,6 +113,10 @@ export class RemoteIngressHandler {
|
|
|
103
113
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateRemoteIngress>(
|
|
104
114
|
'updateRemoteIngress',
|
|
105
115
|
async (dataArg, toolsArg) => {
|
|
116
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
117
|
+
scope: 'remote-ingress:write',
|
|
118
|
+
requireAdminIdentity: true,
|
|
119
|
+
});
|
|
106
120
|
const manager = this.opsServerRef.dcRouterRef.remoteIngressManager;
|
|
107
121
|
const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager;
|
|
108
122
|
|
|
@@ -148,6 +162,10 @@ export class RemoteIngressHandler {
|
|
|
148
162
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RegenerateRemoteIngressSecret>(
|
|
149
163
|
'regenerateRemoteIngressSecret',
|
|
150
164
|
async (dataArg, toolsArg) => {
|
|
165
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
166
|
+
scope: 'remote-ingress:write',
|
|
167
|
+
requireAdminIdentity: true,
|
|
168
|
+
});
|
|
151
169
|
const manager = this.opsServerRef.dcRouterRef.remoteIngressManager;
|
|
152
170
|
const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager;
|
|
153
171
|
|
|
@@ -175,6 +193,7 @@ export class RemoteIngressHandler {
|
|
|
175
193
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngressStatus>(
|
|
176
194
|
'getRemoteIngressStatus',
|
|
177
195
|
async (dataArg, toolsArg) => {
|
|
196
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'remote-ingress:read' });
|
|
178
197
|
const tunnelManager = this.opsServerRef.dcRouterRef.tunnelManager;
|
|
179
198
|
if (!tunnelManager) {
|
|
180
199
|
return { statuses: [] };
|
|
@@ -189,6 +208,10 @@ export class RemoteIngressHandler {
|
|
|
189
208
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngressConnectionToken>(
|
|
190
209
|
'getRemoteIngressConnectionToken',
|
|
191
210
|
async (dataArg, toolsArg) => {
|
|
211
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
212
|
+
scope: 'remote-ingress:write',
|
|
213
|
+
requireAdminIdentity: true,
|
|
214
|
+
});
|
|
192
215
|
const manager = this.opsServerRef.dcRouterRef.remoteIngressManager;
|
|
193
216
|
if (!manager) {
|
|
194
217
|
return { success: false, message: 'RemoteIngress not configured' };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
4
5
|
|
|
5
6
|
export class RouteManagementHandler {
|
|
6
7
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
@@ -18,31 +19,11 @@ export class RouteManagementHandler {
|
|
|
18
19
|
request: { identity?: interfaces.data.IIdentity; apiToken?: string },
|
|
19
20
|
requiredScope?: interfaces.data.TApiTokenScope,
|
|
20
21
|
): Promise<string> {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
});
|
|
27
|
-
if (isAdmin) return request.identity.userId;
|
|
28
|
-
} catch { /* fall through */ }
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Try API token
|
|
32
|
-
if (request.apiToken) {
|
|
33
|
-
const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
34
|
-
if (tokenManager) {
|
|
35
|
-
const token = await tokenManager.validateToken(request.apiToken);
|
|
36
|
-
if (token) {
|
|
37
|
-
if (!requiredScope || tokenManager.hasScope(token, requiredScope)) {
|
|
38
|
-
return token.createdBy;
|
|
39
|
-
}
|
|
40
|
-
throw new plugins.typedrequest.TypedResponseError('insufficient scope');
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
|
22
|
+
const auth = await requireOpsAuth(this.opsServerRef, request, {
|
|
23
|
+
scope: requiredScope,
|
|
24
|
+
requireAdminIdentity: requiredScope?.endsWith(':write'),
|
|
25
|
+
});
|
|
26
|
+
return auth.userId;
|
|
46
27
|
}
|
|
47
28
|
|
|
48
29
|
private registerHandlers(): void {
|
|
@@ -2,6 +2,7 @@ import * as plugins from '../../plugins.js';
|
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
4
|
import { MetricsManager } from '../../monitoring/index.js';
|
|
5
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
5
6
|
|
|
6
7
|
export class SecurityHandler {
|
|
7
8
|
constructor(private opsServerRef: OpsServer) {
|
|
@@ -17,6 +18,7 @@ export class SecurityHandler {
|
|
|
17
18
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetSecurityMetrics>(
|
|
18
19
|
'getSecurityMetrics',
|
|
19
20
|
async (dataArg, toolsArg) => {
|
|
21
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
|
20
22
|
const metrics = await this.collectSecurityMetrics();
|
|
21
23
|
return {
|
|
22
24
|
metrics: {
|
|
@@ -43,6 +45,7 @@ export class SecurityHandler {
|
|
|
43
45
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetActiveConnections>(
|
|
44
46
|
'getActiveConnections',
|
|
45
47
|
async (dataArg, toolsArg) => {
|
|
48
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
|
46
49
|
const connections = await this.getActiveConnections(dataArg.protocol, dataArg.state);
|
|
47
50
|
const connectionInfos: interfaces.data.IConnectionInfo[] = connections.map(conn => ({
|
|
48
51
|
id: conn.id,
|
|
@@ -82,6 +85,7 @@ export class SecurityHandler {
|
|
|
82
85
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetNetworkStats>(
|
|
83
86
|
'getNetworkStats',
|
|
84
87
|
async (dataArg, toolsArg) => {
|
|
88
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
|
85
89
|
// Get network stats from MetricsManager if available
|
|
86
90
|
if (this.opsServerRef.dcRouterRef.metricsManager) {
|
|
87
91
|
const networkStats = await this.opsServerRef.dcRouterRef.metricsManager.getNetworkStats();
|
|
@@ -136,6 +140,7 @@ export class SecurityHandler {
|
|
|
136
140
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRateLimitStatus>(
|
|
137
141
|
'getRateLimitStatus',
|
|
138
142
|
async (dataArg, toolsArg) => {
|
|
143
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
|
139
144
|
const status = await this.getRateLimitStatus(dataArg.domain, dataArg.ip);
|
|
140
145
|
const limits: interfaces.data.IRateLimitInfo[] = status.limits.map(limit => ({
|
|
141
146
|
domain: limit.identifier,
|
|
@@ -161,7 +166,8 @@ export class SecurityHandler {
|
|
|
161
166
|
router.addTypedHandler(
|
|
162
167
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListSecurityBlockRules>(
|
|
163
168
|
'listSecurityBlockRules',
|
|
164
|
-
async () => {
|
|
169
|
+
async (dataArg) => {
|
|
170
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
|
165
171
|
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
|
166
172
|
return { rules: manager ? await manager.listBlockRules() : [] };
|
|
167
173
|
},
|
|
@@ -171,7 +177,8 @@ export class SecurityHandler {
|
|
|
171
177
|
router.addTypedHandler(
|
|
172
178
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListIpIntelligence>(
|
|
173
179
|
'listIpIntelligence',
|
|
174
|
-
async () => {
|
|
180
|
+
async (dataArg) => {
|
|
181
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
|
175
182
|
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
|
176
183
|
return { records: manager ? await manager.listIpIntelligence() : [] };
|
|
177
184
|
},
|
|
@@ -181,7 +188,8 @@ export class SecurityHandler {
|
|
|
181
188
|
router.addTypedHandler(
|
|
182
189
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetCompiledSecurityPolicy>(
|
|
183
190
|
'getCompiledSecurityPolicy',
|
|
184
|
-
async () => {
|
|
191
|
+
async (dataArg) => {
|
|
192
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
|
185
193
|
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
|
186
194
|
return {
|
|
187
195
|
policy: manager
|
|
@@ -196,6 +204,7 @@ export class SecurityHandler {
|
|
|
196
204
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListSecurityPolicyAudit>(
|
|
197
205
|
'listSecurityPolicyAudit',
|
|
198
206
|
async (dataArg) => {
|
|
207
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
|
199
208
|
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
|
200
209
|
return { events: manager ? await manager.listAuditEvents(dataArg.limit || 100) : [] };
|
|
201
210
|
},
|
|
@@ -208,6 +217,10 @@ export class SecurityHandler {
|
|
|
208
217
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateSecurityBlockRule>(
|
|
209
218
|
'createSecurityBlockRule',
|
|
210
219
|
async (dataArg) => {
|
|
220
|
+
const auth = await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
221
|
+
scope: 'security:write',
|
|
222
|
+
requireAdminIdentity: true,
|
|
223
|
+
});
|
|
211
224
|
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
|
212
225
|
if (!manager) return { success: false, message: 'Security policy manager not initialized' };
|
|
213
226
|
const rule = await manager.createBlockRule({
|
|
@@ -216,7 +229,7 @@ export class SecurityHandler {
|
|
|
216
229
|
matchMode: dataArg.matchMode,
|
|
217
230
|
reason: dataArg.reason,
|
|
218
231
|
enabled: dataArg.enabled,
|
|
219
|
-
},
|
|
232
|
+
}, auth.userId);
|
|
220
233
|
return { success: true, rule };
|
|
221
234
|
},
|
|
222
235
|
),
|
|
@@ -226,6 +239,10 @@ export class SecurityHandler {
|
|
|
226
239
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateSecurityBlockRule>(
|
|
227
240
|
'updateSecurityBlockRule',
|
|
228
241
|
async (dataArg) => {
|
|
242
|
+
const auth = await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
243
|
+
scope: 'security:write',
|
|
244
|
+
requireAdminIdentity: true,
|
|
245
|
+
});
|
|
229
246
|
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
|
230
247
|
if (!manager) return { success: false, message: 'Security policy manager not initialized' };
|
|
231
248
|
const rule = await manager.updateBlockRule(dataArg.id, {
|
|
@@ -233,7 +250,7 @@ export class SecurityHandler {
|
|
|
233
250
|
matchMode: dataArg.matchMode,
|
|
234
251
|
reason: dataArg.reason,
|
|
235
252
|
enabled: dataArg.enabled,
|
|
236
|
-
},
|
|
253
|
+
}, auth.userId);
|
|
237
254
|
return rule ? { success: true, rule } : { success: false, message: 'Rule not found' };
|
|
238
255
|
},
|
|
239
256
|
),
|
|
@@ -243,9 +260,13 @@ export class SecurityHandler {
|
|
|
243
260
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteSecurityBlockRule>(
|
|
244
261
|
'deleteSecurityBlockRule',
|
|
245
262
|
async (dataArg) => {
|
|
263
|
+
const auth = await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
264
|
+
scope: 'security:write',
|
|
265
|
+
requireAdminIdentity: true,
|
|
266
|
+
});
|
|
246
267
|
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
|
247
268
|
if (!manager) return { success: false, message: 'Security policy manager not initialized' };
|
|
248
|
-
const success = await manager.deleteBlockRule(dataArg.id,
|
|
269
|
+
const success = await manager.deleteBlockRule(dataArg.id, auth.userId);
|
|
249
270
|
return { success, message: success ? undefined : 'Rule not found' };
|
|
250
271
|
},
|
|
251
272
|
),
|
|
@@ -255,6 +276,10 @@ export class SecurityHandler {
|
|
|
255
276
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RefreshIpIntelligence>(
|
|
256
277
|
'refreshIpIntelligence',
|
|
257
278
|
async (dataArg) => {
|
|
279
|
+
await requireOpsAuth(this.opsServerRef, dataArg, {
|
|
280
|
+
scope: 'security:write',
|
|
281
|
+
requireAdminIdentity: true,
|
|
282
|
+
});
|
|
258
283
|
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
|
259
284
|
if (!manager) return { success: false, message: 'Security policy manager not initialized' };
|
|
260
285
|
const record = await manager.refreshIpIntelligence(dataArg.ipAddress);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
3
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
4
5
|
|
|
5
6
|
export class SourceProfileHandler {
|
|
6
7
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
@@ -14,29 +15,11 @@ export class SourceProfileHandler {
|
|
|
14
15
|
request: { identity?: interfaces.data.IIdentity; apiToken?: string },
|
|
15
16
|
requiredScope?: interfaces.data.TApiTokenScope,
|
|
16
17
|
): Promise<string> {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (isAdmin) return request.identity.userId;
|
|
23
|
-
} catch { /* fall through */ }
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (request.apiToken) {
|
|
27
|
-
const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
28
|
-
if (tokenManager) {
|
|
29
|
-
const token = await tokenManager.validateToken(request.apiToken);
|
|
30
|
-
if (token) {
|
|
31
|
-
if (!requiredScope || tokenManager.hasScope(token, requiredScope)) {
|
|
32
|
-
return token.createdBy;
|
|
33
|
-
}
|
|
34
|
-
throw new plugins.typedrequest.TypedResponseError('insufficient scope');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
|
18
|
+
const auth = await requireOpsAuth(this.opsServerRef, request, {
|
|
19
|
+
scope: requiredScope,
|
|
20
|
+
requireAdminIdentity: requiredScope?.endsWith(':write'),
|
|
21
|
+
});
|
|
22
|
+
return auth.userId;
|
|
40
23
|
}
|
|
41
24
|
|
|
42
25
|
private registerHandlers(): void {
|
|
@@ -4,6 +4,7 @@ import * as interfaces from '../../../ts_interfaces/index.js';
|
|
|
4
4
|
import { MetricsManager } from '../../monitoring/index.js';
|
|
5
5
|
import { SecurityLogger } from '../../security/classes.securitylogger.js';
|
|
6
6
|
import { commitinfo } from '../../00_commitinfo_data.js';
|
|
7
|
+
import { requireOpsAuth } from '../helpers/auth.js';
|
|
7
8
|
|
|
8
9
|
export class StatsHandler {
|
|
9
10
|
constructor(private opsServerRef: OpsServer) {
|
|
@@ -19,6 +20,7 @@ export class StatsHandler {
|
|
|
19
20
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetServerStatistics>(
|
|
20
21
|
'getServerStatistics',
|
|
21
22
|
async (dataArg, toolsArg) => {
|
|
23
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
|
22
24
|
const stats = await this.collectServerStats();
|
|
23
25
|
return {
|
|
24
26
|
stats: {
|
|
@@ -42,6 +44,7 @@ export class StatsHandler {
|
|
|
42
44
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetEmailStatistics>(
|
|
43
45
|
'getEmailStatistics',
|
|
44
46
|
async (dataArg, toolsArg) => {
|
|
47
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
|
45
48
|
const emailServer = this.opsServerRef.dcRouterRef.emailServer;
|
|
46
49
|
if (!emailServer) {
|
|
47
50
|
return {
|
|
@@ -81,6 +84,7 @@ export class StatsHandler {
|
|
|
81
84
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDnsStatistics>(
|
|
82
85
|
'getDnsStatistics',
|
|
83
86
|
async (dataArg, toolsArg) => {
|
|
87
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
|
84
88
|
const dnsServer = this.opsServerRef.dcRouterRef.dnsServer;
|
|
85
89
|
if (!dnsServer) {
|
|
86
90
|
return {
|
|
@@ -118,6 +122,7 @@ export class StatsHandler {
|
|
|
118
122
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetQueueStatus>(
|
|
119
123
|
'getQueueStatus',
|
|
120
124
|
async (dataArg, toolsArg) => {
|
|
125
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
|
121
126
|
const emailServer = this.opsServerRef.dcRouterRef.emailServer;
|
|
122
127
|
const queues: interfaces.data.IQueueStatus[] = [];
|
|
123
128
|
|
|
@@ -146,6 +151,7 @@ export class StatsHandler {
|
|
|
146
151
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetHealthStatus>(
|
|
147
152
|
'getHealthStatus',
|
|
148
153
|
async (dataArg, toolsArg) => {
|
|
154
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
|
149
155
|
const health = await this.checkHealthStatus();
|
|
150
156
|
return {
|
|
151
157
|
health: {
|
|
@@ -171,6 +177,7 @@ export class StatsHandler {
|
|
|
171
177
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetCombinedMetrics>(
|
|
172
178
|
'getCombinedMetrics',
|
|
173
179
|
async (dataArg, toolsArg) => {
|
|
180
|
+
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
|
174
181
|
const sections = dataArg.sections || {
|
|
175
182
|
server: true,
|
|
176
183
|
email: true,
|