@serve.zone/dcrouter 13.31.0 → 13.32.1

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.
Files changed (80) hide show
  1. package/dist_serve/bundle.js +721 -721
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/config/classes.route-config-manager.d.ts +1 -0
  4. package/dist_ts/config/classes.route-config-manager.js +28 -3
  5. package/dist_ts/config/classes.target-profile-manager.d.ts +1 -0
  6. package/dist_ts/config/classes.target-profile-manager.js +11 -8
  7. package/dist_ts/opsserver/classes.opsserver.d.ts +4 -2
  8. package/dist_ts/opsserver/classes.opsserver.js +2 -11
  9. package/dist_ts/opsserver/handlers/acme-config.handler.js +7 -24
  10. package/dist_ts/opsserver/handlers/admin.handler.d.ts +3 -1
  11. package/dist_ts/opsserver/handlers/admin.handler.js +95 -110
  12. package/dist_ts/opsserver/handlers/api-token.handler.js +28 -2
  13. package/dist_ts/opsserver/handlers/certificate.handler.js +7 -24
  14. package/dist_ts/opsserver/handlers/config.handler.js +3 -1
  15. package/dist_ts/opsserver/handlers/dns-provider.handler.js +7 -24
  16. package/dist_ts/opsserver/handlers/dns-record.handler.js +7 -24
  17. package/dist_ts/opsserver/handlers/domain.handler.js +7 -24
  18. package/dist_ts/opsserver/handlers/email-domain.handler.js +7 -24
  19. package/dist_ts/opsserver/handlers/email-ops.handler.js +8 -1
  20. package/dist_ts/opsserver/handlers/logs.handler.js +4 -1
  21. package/dist_ts/opsserver/handlers/network-target.handler.js +7 -24
  22. package/dist_ts/opsserver/handlers/radius.handler.js +32 -1
  23. package/dist_ts/opsserver/handlers/remoteingress.handler.js +24 -1
  24. package/dist_ts/opsserver/handlers/route-management.handler.js +7 -26
  25. package/dist_ts/opsserver/handlers/security.handler.js +32 -7
  26. package/dist_ts/opsserver/handlers/source-profile.handler.js +7 -24
  27. package/dist_ts/opsserver/handlers/stats.handler.js +8 -1
  28. package/dist_ts/opsserver/handlers/target-profile.handler.js +7 -24
  29. package/dist_ts/opsserver/handlers/users.handler.js +33 -13
  30. package/dist_ts/opsserver/handlers/vpn.handler.js +34 -1
  31. package/dist_ts/opsserver/handlers/workhoster.handler.js +16 -35
  32. package/dist_ts/opsserver/helpers/auth.d.ts +21 -0
  33. package/dist_ts/opsserver/helpers/auth.js +63 -0
  34. package/dist_ts_interfaces/data/route-management.d.ts +2 -1
  35. package/dist_ts_interfaces/data/route-management.js +48 -2
  36. package/dist_ts_interfaces/requests/api-tokens.d.ts +10 -5
  37. package/dist_ts_interfaces/requests/combined.stats.d.ts +2 -1
  38. package/dist_ts_interfaces/requests/config.d.ts +2 -1
  39. package/dist_ts_interfaces/requests/email-ops.d.ts +6 -3
  40. package/dist_ts_interfaces/requests/logs.d.ts +4 -2
  41. package/dist_ts_interfaces/requests/radius.d.ts +24 -12
  42. package/dist_ts_interfaces/requests/remoteingress.d.ts +14 -7
  43. package/dist_ts_interfaces/requests/security-policy.d.ts +16 -8
  44. package/dist_ts_interfaces/requests/stats.d.ts +18 -9
  45. package/dist_ts_interfaces/requests/users.d.ts +6 -3
  46. package/dist_ts_interfaces/requests/vpn.d.ts +22 -11
  47. package/dist_ts_interfaces/requests/workhoster.d.ts +10 -5
  48. package/dist_ts_migrations/index.js +3 -1
  49. package/dist_ts_web/00_commitinfo_data.js +1 -1
  50. package/dist_ts_web/elements/access/ops-view-apitokens.js +2 -21
  51. package/package.json +4 -4
  52. package/ts/00_commitinfo_data.ts +1 -1
  53. package/ts/config/classes.route-config-manager.ts +35 -2
  54. package/ts/config/classes.target-profile-manager.ts +10 -7
  55. package/ts/opsserver/classes.opsserver.ts +3 -14
  56. package/ts/opsserver/handlers/acme-config.handler.ts +6 -23
  57. package/ts/opsserver/handlers/admin.handler.ts +109 -123
  58. package/ts/opsserver/handlers/api-token.handler.ts +27 -1
  59. package/ts/opsserver/handlers/certificate.handler.ts +6 -23
  60. package/ts/opsserver/handlers/config.handler.ts +2 -0
  61. package/ts/opsserver/handlers/dns-provider.handler.ts +6 -23
  62. package/ts/opsserver/handlers/dns-record.handler.ts +6 -23
  63. package/ts/opsserver/handlers/domain.handler.ts +6 -23
  64. package/ts/opsserver/handlers/email-domain.handler.ts +6 -23
  65. package/ts/opsserver/handlers/email-ops.handler.ts +7 -0
  66. package/ts/opsserver/handlers/logs.handler.ts +3 -0
  67. package/ts/opsserver/handlers/network-target.handler.ts +6 -23
  68. package/ts/opsserver/handlers/radius.handler.ts +31 -0
  69. package/ts/opsserver/handlers/remoteingress.handler.ts +23 -0
  70. package/ts/opsserver/handlers/route-management.handler.ts +6 -25
  71. package/ts/opsserver/handlers/security.handler.ts +31 -6
  72. package/ts/opsserver/handlers/source-profile.handler.ts +6 -23
  73. package/ts/opsserver/handlers/stats.handler.ts +7 -0
  74. package/ts/opsserver/handlers/target-profile.handler.ts +6 -23
  75. package/ts/opsserver/handlers/users.handler.ts +32 -12
  76. package/ts/opsserver/handlers/vpn.handler.ts +33 -0
  77. package/ts/opsserver/handlers/workhoster.handler.ts +18 -33
  78. package/ts/opsserver/helpers/auth.ts +91 -0
  79. package/ts_web/00_commitinfo_data.ts +1 -1
  80. 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 DnsRecordDoc.
@@ -17,29 +18,11 @@ export class DnsRecordHandler {
17
18
  request: { identity?: interfaces.data.IIdentity; apiToken?: string },
18
19
  requiredScope?: interfaces.data.TApiTokenScope,
19
20
  ): Promise<string> {
20
- if (request.identity?.jwt) {
21
- try {
22
- const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
23
- identity: request.identity,
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 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
- if (request.identity?.jwt) {
21
- try {
22
- const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
23
- identity: request.identity,
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
- if (request.identity?.jwt) {
23
- try {
24
- const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
25
- identity: request.identity,
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
- if (request.identity?.jwt) {
18
- try {
19
- const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
20
- identity: request.identity,
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
- // Try JWT identity first
22
- if (request.identity?.jwt) {
23
- try {
24
- const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
25
- identity: request.identity,
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
- }, dataArg.identity.userId);
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
- }, dataArg.identity.userId);
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, dataArg.identity.userId);
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
- if (request.identity?.jwt) {
18
- try {
19
- const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
20
- identity: request.identity,
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 {