@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.
Files changed (74) hide show
  1. package/dist_serve/bundle.js +721 -721
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/opsserver/classes.opsserver.d.ts +4 -2
  4. package/dist_ts/opsserver/classes.opsserver.js +2 -11
  5. package/dist_ts/opsserver/handlers/acme-config.handler.js +7 -24
  6. package/dist_ts/opsserver/handlers/admin.handler.d.ts +1 -0
  7. package/dist_ts/opsserver/handlers/admin.handler.js +58 -88
  8. package/dist_ts/opsserver/handlers/api-token.handler.js +28 -2
  9. package/dist_ts/opsserver/handlers/certificate.handler.js +7 -24
  10. package/dist_ts/opsserver/handlers/config.handler.js +3 -1
  11. package/dist_ts/opsserver/handlers/dns-provider.handler.js +7 -24
  12. package/dist_ts/opsserver/handlers/dns-record.handler.js +7 -24
  13. package/dist_ts/opsserver/handlers/domain.handler.js +7 -24
  14. package/dist_ts/opsserver/handlers/email-domain.handler.js +7 -24
  15. package/dist_ts/opsserver/handlers/email-ops.handler.js +8 -1
  16. package/dist_ts/opsserver/handlers/logs.handler.js +4 -1
  17. package/dist_ts/opsserver/handlers/network-target.handler.js +7 -24
  18. package/dist_ts/opsserver/handlers/radius.handler.js +32 -1
  19. package/dist_ts/opsserver/handlers/remoteingress.handler.js +24 -1
  20. package/dist_ts/opsserver/handlers/route-management.handler.js +7 -26
  21. package/dist_ts/opsserver/handlers/security.handler.js +32 -7
  22. package/dist_ts/opsserver/handlers/source-profile.handler.js +7 -24
  23. package/dist_ts/opsserver/handlers/stats.handler.js +8 -1
  24. package/dist_ts/opsserver/handlers/target-profile.handler.js +7 -24
  25. package/dist_ts/opsserver/handlers/users.handler.js +33 -13
  26. package/dist_ts/opsserver/handlers/vpn.handler.js +34 -1
  27. package/dist_ts/opsserver/handlers/workhoster.handler.js +16 -35
  28. package/dist_ts/opsserver/helpers/auth.d.ts +21 -0
  29. package/dist_ts/opsserver/helpers/auth.js +63 -0
  30. package/dist_ts_interfaces/data/route-management.d.ts +2 -1
  31. package/dist_ts_interfaces/data/route-management.js +48 -2
  32. package/dist_ts_interfaces/requests/api-tokens.d.ts +10 -5
  33. package/dist_ts_interfaces/requests/combined.stats.d.ts +2 -1
  34. package/dist_ts_interfaces/requests/config.d.ts +2 -1
  35. package/dist_ts_interfaces/requests/email-ops.d.ts +6 -3
  36. package/dist_ts_interfaces/requests/logs.d.ts +4 -2
  37. package/dist_ts_interfaces/requests/radius.d.ts +24 -12
  38. package/dist_ts_interfaces/requests/remoteingress.d.ts +14 -7
  39. package/dist_ts_interfaces/requests/security-policy.d.ts +16 -8
  40. package/dist_ts_interfaces/requests/stats.d.ts +18 -9
  41. package/dist_ts_interfaces/requests/users.d.ts +6 -3
  42. package/dist_ts_interfaces/requests/vpn.d.ts +22 -11
  43. package/dist_ts_interfaces/requests/workhoster.d.ts +10 -5
  44. package/dist_ts_migrations/index.js +3 -1
  45. package/dist_ts_web/00_commitinfo_data.js +1 -1
  46. package/dist_ts_web/elements/access/ops-view-apitokens.js +2 -21
  47. package/package.json +2 -2
  48. package/ts/00_commitinfo_data.ts +1 -1
  49. package/ts/opsserver/classes.opsserver.ts +3 -14
  50. package/ts/opsserver/handlers/acme-config.handler.ts +6 -23
  51. package/ts/opsserver/handlers/admin.handler.ts +64 -101
  52. package/ts/opsserver/handlers/api-token.handler.ts +27 -1
  53. package/ts/opsserver/handlers/certificate.handler.ts +6 -23
  54. package/ts/opsserver/handlers/config.handler.ts +2 -0
  55. package/ts/opsserver/handlers/dns-provider.handler.ts +6 -23
  56. package/ts/opsserver/handlers/dns-record.handler.ts +6 -23
  57. package/ts/opsserver/handlers/domain.handler.ts +6 -23
  58. package/ts/opsserver/handlers/email-domain.handler.ts +6 -23
  59. package/ts/opsserver/handlers/email-ops.handler.ts +7 -0
  60. package/ts/opsserver/handlers/logs.handler.ts +3 -0
  61. package/ts/opsserver/handlers/network-target.handler.ts +6 -23
  62. package/ts/opsserver/handlers/radius.handler.ts +31 -0
  63. package/ts/opsserver/handlers/remoteingress.handler.ts +23 -0
  64. package/ts/opsserver/handlers/route-management.handler.ts +6 -25
  65. package/ts/opsserver/handlers/security.handler.ts +31 -6
  66. package/ts/opsserver/handlers/source-profile.handler.ts +6 -23
  67. package/ts/opsserver/handlers/stats.handler.ts +7 -0
  68. package/ts/opsserver/handlers/target-profile.handler.ts +6 -23
  69. package/ts/opsserver/handlers/users.handler.ts +32 -12
  70. package/ts/opsserver/handlers/vpn.handler.ts +33 -0
  71. package/ts/opsserver/handlers/workhoster.handler.ts +18 -33
  72. package/ts/opsserver/helpers/auth.ts +91 -0
  73. package/ts_web/00_commitinfo_data.ts +1 -1
  74. 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
  export class TargetProfileHandler {
6
7
  public typedrouter = new plugins.typedrequest.TypedRouter();
@@ -14,29 +15,11 @@ export class TargetProfileHandler {
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
  /**
6
7
  * Handler for OpsServer user accounts. Registers on adminRouter,
@@ -20,7 +21,12 @@ export class UsersHandler {
20
21
  router.addTypedHandler(
21
22
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListUsers>(
22
23
  'listUsers',
23
- async (_dataArg) => {
24
+ async (dataArg) => {
25
+ await requireOpsAuth(this.opsServerRef, dataArg, {
26
+ scope: 'users:read',
27
+ requireAdminIdentity: true,
28
+ requireAdminToken: true,
29
+ });
24
30
  const users = await this.opsServerRef.adminHandler.listUsers();
25
31
  return { users };
26
32
  },
@@ -30,23 +36,37 @@ export class UsersHandler {
30
36
  router.addTypedHandler(
31
37
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateUser>(
32
38
  'createUser',
33
- async (dataArg) => this.opsServerRef.adminHandler.createUser({
34
- email: dataArg.email,
35
- name: dataArg.name,
36
- role: dataArg.role,
37
- password: dataArg.password,
38
- enableIdpGlobalAuth: dataArg.enableIdpGlobalAuth,
39
- }),
39
+ async (dataArg) => {
40
+ await requireOpsAuth(this.opsServerRef, dataArg, {
41
+ scope: 'users:manage',
42
+ requireAdminIdentity: true,
43
+ requireAdminToken: true,
44
+ });
45
+ return this.opsServerRef.adminHandler.createUser({
46
+ email: dataArg.email,
47
+ name: dataArg.name,
48
+ role: dataArg.role,
49
+ password: dataArg.password,
50
+ enableIdpGlobalAuth: dataArg.enableIdpGlobalAuth,
51
+ });
52
+ },
40
53
  ),
41
54
  );
42
55
 
43
56
  router.addTypedHandler(
44
57
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteUser>(
45
58
  'deleteUser',
46
- async (dataArg) => this.opsServerRef.adminHandler.deleteUser({
47
- id: dataArg.id,
48
- requestingUserId: dataArg.identity.userId,
49
- }),
59
+ async (dataArg) => {
60
+ const auth = await requireOpsAuth(this.opsServerRef, dataArg, {
61
+ scope: 'users:manage',
62
+ requireAdminIdentity: true,
63
+ requireAdminToken: true,
64
+ });
65
+ return this.opsServerRef.adminHandler.deleteUser({
66
+ id: dataArg.id,
67
+ requestingUserId: auth.userId,
68
+ });
69
+ },
50
70
  ),
51
71
  );
52
72
  }
@@ -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 VpnHandler {
6
7
  constructor(private opsServerRef: OpsServer) {
@@ -18,6 +19,7 @@ export class VpnHandler {
18
19
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetVpnClients>(
19
20
  'getVpnClients',
20
21
  async (dataArg, toolsArg) => {
22
+ await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'vpn:read' });
21
23
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
22
24
  if (!manager) {
23
25
  return { clients: [] };
@@ -49,6 +51,7 @@ export class VpnHandler {
49
51
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetVpnStatus>(
50
52
  'getVpnStatus',
51
53
  async (dataArg, toolsArg) => {
54
+ await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'vpn:read' });
52
55
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
53
56
  const vpnConfig = this.opsServerRef.dcRouterRef.options.vpnConfig;
54
57
  if (!manager) {
@@ -84,6 +87,7 @@ export class VpnHandler {
84
87
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetVpnConnectedClients>(
85
88
  'getVpnConnectedClients',
86
89
  async (dataArg, toolsArg) => {
90
+ await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'vpn:read' });
87
91
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
88
92
  if (!manager) {
89
93
  return { connectedClients: [] };
@@ -111,6 +115,10 @@ export class VpnHandler {
111
115
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateVpnClient>(
112
116
  'createVpnClient',
113
117
  async (dataArg, toolsArg) => {
118
+ await requireOpsAuth(this.opsServerRef, dataArg, {
119
+ scope: 'vpn:write',
120
+ requireAdminIdentity: true,
121
+ });
114
122
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
115
123
  if (!manager) {
116
124
  return { success: false, message: 'VPN not configured' };
@@ -168,6 +176,10 @@ export class VpnHandler {
168
176
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateVpnClient>(
169
177
  'updateVpnClient',
170
178
  async (dataArg, toolsArg) => {
179
+ await requireOpsAuth(this.opsServerRef, dataArg, {
180
+ scope: 'vpn:write',
181
+ requireAdminIdentity: true,
182
+ });
171
183
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
172
184
  if (!manager) {
173
185
  return { success: false, message: 'VPN not configured' };
@@ -198,6 +210,10 @@ export class VpnHandler {
198
210
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteVpnClient>(
199
211
  'deleteVpnClient',
200
212
  async (dataArg, toolsArg) => {
213
+ await requireOpsAuth(this.opsServerRef, dataArg, {
214
+ scope: 'vpn:write',
215
+ requireAdminIdentity: true,
216
+ });
201
217
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
202
218
  if (!manager) {
203
219
  return { success: false, message: 'VPN not configured' };
@@ -218,6 +234,10 @@ export class VpnHandler {
218
234
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_EnableVpnClient>(
219
235
  'enableVpnClient',
220
236
  async (dataArg, toolsArg) => {
237
+ await requireOpsAuth(this.opsServerRef, dataArg, {
238
+ scope: 'vpn:write',
239
+ requireAdminIdentity: true,
240
+ });
221
241
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
222
242
  if (!manager) {
223
243
  return { success: false, message: 'VPN not configured' };
@@ -238,6 +258,10 @@ export class VpnHandler {
238
258
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DisableVpnClient>(
239
259
  'disableVpnClient',
240
260
  async (dataArg, toolsArg) => {
261
+ await requireOpsAuth(this.opsServerRef, dataArg, {
262
+ scope: 'vpn:write',
263
+ requireAdminIdentity: true,
264
+ });
241
265
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
242
266
  if (!manager) {
243
267
  return { success: false, message: 'VPN not configured' };
@@ -258,6 +282,10 @@ export class VpnHandler {
258
282
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RotateVpnClientKey>(
259
283
  'rotateVpnClientKey',
260
284
  async (dataArg, toolsArg) => {
285
+ await requireOpsAuth(this.opsServerRef, dataArg, {
286
+ scope: 'vpn:write',
287
+ requireAdminIdentity: true,
288
+ });
261
289
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
262
290
  if (!manager) {
263
291
  return { success: false, message: 'VPN not configured' };
@@ -281,6 +309,10 @@ export class VpnHandler {
281
309
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ExportVpnClientConfig>(
282
310
  'exportVpnClientConfig',
283
311
  async (dataArg, toolsArg) => {
312
+ await requireOpsAuth(this.opsServerRef, dataArg, {
313
+ scope: 'vpn:write',
314
+ requireAdminIdentity: true,
315
+ });
284
316
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
285
317
  if (!manager) {
286
318
  return { success: false, message: 'VPN not configured' };
@@ -301,6 +333,7 @@ export class VpnHandler {
301
333
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetVpnClientTelemetry>(
302
334
  'getVpnClientTelemetry',
303
335
  async (dataArg, toolsArg) => {
336
+ await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'vpn:read' });
304
337
  const manager = this.opsServerRef.dcRouterRef.vpnManager;
305
338
  if (!manager) {
306
339
  return { success: false, message: 'VPN 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
  type TAuthContext = {
6
7
  userId: string;
@@ -20,39 +21,23 @@ export class WorkHosterHandler {
20
21
  request: { identity?: interfaces.data.IIdentity; apiToken?: string },
21
22
  requiredScope?: interfaces.data.TApiTokenScope,
22
23
  ): Promise<TAuthContext> {
23
- if (request.identity?.jwt) {
24
- try {
25
- const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
26
- identity: request.identity,
27
- });
28
- if (isAdmin) return { userId: request.identity.userId, isAdmin: true };
29
- } catch { /* fall through */ }
30
- }
31
-
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 { userId: token.createdBy, isAdmin: token.policy?.role === 'admin', token };
39
- }
40
- throw new plugins.typedrequest.TypedResponseError('insufficient scope');
41
- }
42
- }
43
- }
44
-
45
- throw new plugins.typedrequest.TypedResponseError('unauthorized');
24
+ const auth = await requireOpsAuth(this.opsServerRef, request, {
25
+ scope: requiredScope,
26
+ requireAdminIdentity: requiredScope?.endsWith(':write'),
27
+ });
28
+ return { userId: auth.userId, isAdmin: auth.isAdmin, token: auth.token };
46
29
  }
47
30
 
48
- private async requireAdmin(request: { identity?: interfaces.data.IIdentity }): Promise<string> {
49
- if (request.identity?.jwt) {
50
- const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
51
- identity: request.identity,
52
- });
53
- if (isAdmin) return request.identity.userId;
54
- }
55
- throw new plugins.typedrequest.TypedResponseError('admin identity required');
31
+ private async requireAdmin(
32
+ request: { identity?: interfaces.data.IIdentity; apiToken?: string },
33
+ scope: interfaces.data.TApiTokenScope = 'gateway-clients:write',
34
+ ): Promise<string> {
35
+ const auth = await requireOpsAuth(this.opsServerRef, request, {
36
+ scope,
37
+ requireAdminIdentity: true,
38
+ requireAdminToken: true,
39
+ });
40
+ return auth.userId;
56
41
  }
57
42
 
58
43
  private registerHandlers(): void {
@@ -83,7 +68,7 @@ export class WorkHosterHandler {
83
68
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListGatewayClients>(
84
69
  'listGatewayClients',
85
70
  async (dataArg) => {
86
- await this.requireAdmin(dataArg);
71
+ await this.requireAdmin(dataArg, 'gateway-clients:read');
87
72
  return { gatewayClients: await this.listManagedGatewayClients() };
88
73
  },
89
74
  ),
@@ -154,7 +139,7 @@ export class WorkHosterHandler {
154
139
  new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateGatewayClientToken>(
155
140
  'createGatewayClientToken',
156
141
  async (dataArg) => {
157
- const userId = await this.requireAdmin(dataArg);
142
+ const userId = await this.requireAdmin(dataArg, 'tokens:manage');
158
143
  const gatewayClient = await this.opsServerRef.dcRouterRef.gatewayClientManager?.getClient(dataArg.gatewayClientId);
159
144
  const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager;
160
145
  if (!gatewayClient || !gatewayClient.enabled) {
@@ -0,0 +1,91 @@
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 interface IAuthRequest {
6
+ identity?: interfaces.data.IIdentity;
7
+ apiToken?: string;
8
+ }
9
+
10
+ export interface IAuthRequirement {
11
+ scope?: interfaces.data.TApiTokenScope;
12
+ requireAdminIdentity?: boolean;
13
+ requireAdminToken?: boolean;
14
+ }
15
+
16
+ export interface IAuthContext {
17
+ type: 'identity' | 'apiToken';
18
+ userId: string;
19
+ role?: string;
20
+ isAdmin: boolean;
21
+ scopes: interfaces.data.TApiTokenScope[];
22
+ identity?: interfaces.data.IIdentity;
23
+ token?: interfaces.data.IStoredApiToken;
24
+ }
25
+
26
+ const typedAuthError = (messageArg: string) => {
27
+ return new plugins.typedrequest.TypedResponseError(messageArg);
28
+ };
29
+
30
+ export async function requireOpsAuth(
31
+ opsServerRefArg: OpsServer,
32
+ requestArg: IAuthRequest,
33
+ requirementArg: IAuthRequirement = {},
34
+ ): Promise<IAuthContext> {
35
+ let identityNeedsAdmin = false;
36
+ let tokenNeedsAdmin = false;
37
+ let tokenNeedsScope = false;
38
+
39
+ if (requestArg.identity?.jwt) {
40
+ const identity = await opsServerRefArg.adminHandler.validateIdentity(requestArg.identity);
41
+ if (identity) {
42
+ const isAdmin = identity.role === 'admin';
43
+ if (!requirementArg.requireAdminIdentity || isAdmin) {
44
+ return {
45
+ type: 'identity',
46
+ userId: identity.userId,
47
+ role: identity.role,
48
+ isAdmin,
49
+ scopes: [],
50
+ identity,
51
+ };
52
+ }
53
+ identityNeedsAdmin = true;
54
+ }
55
+ }
56
+
57
+ if (requestArg.apiToken) {
58
+ const tokenManager = opsServerRefArg.dcRouterRef.apiTokenManager;
59
+ const token = tokenManager ? await tokenManager.validateToken(requestArg.apiToken) : null;
60
+ if (token) {
61
+ if (requirementArg.requireAdminToken && token.policy?.role !== 'admin') {
62
+ tokenNeedsAdmin = true;
63
+ } else if (requirementArg.scope && !tokenManager!.hasScope(token, requirementArg.scope)) {
64
+ tokenNeedsScope = true;
65
+ } else {
66
+ const scopes = token.policy?.role === 'admin'
67
+ ? ['*' as interfaces.data.TApiTokenScope]
68
+ : Array.from(new Set([...(token.scopes || []), ...(token.policy?.scopes || [])]));
69
+ return {
70
+ type: 'apiToken',
71
+ userId: token.createdBy,
72
+ role: token.policy?.role || 'operator',
73
+ isAdmin: token.policy?.role === 'admin',
74
+ scopes,
75
+ token,
76
+ };
77
+ }
78
+ }
79
+ }
80
+
81
+ if (tokenNeedsScope) {
82
+ throw typedAuthError('insufficient scope');
83
+ }
84
+ if (tokenNeedsAdmin) {
85
+ throw typedAuthError('admin API token required');
86
+ }
87
+ if (identityNeedsAdmin) {
88
+ throw typedAuthError('admin identity required');
89
+ }
90
+ throw typedAuthError('unauthorized');
91
+ }
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '13.31.0',
6
+ version: '13.32.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  }
@@ -200,26 +200,7 @@ export class OpsViewApiTokens extends DeesElement {
200
200
  private async showCreateTokenDialog() {
201
201
  const { DeesModal } = await import('@design.estate/dees-catalog');
202
202
 
203
- const allScopes = [
204
- '*',
205
- 'routes:read',
206
- 'routes:write',
207
- 'config:read',
208
- 'certificates:read',
209
- 'certificates:write',
210
- 'tokens:read',
211
- 'tokens:manage',
212
- 'domains:read',
213
- 'domains:write',
214
- 'dns-records:read',
215
- 'dns-records:write',
216
- 'email-domains:read',
217
- 'email-domains:write',
218
- 'gateway-clients:read',
219
- 'gateway-clients:write',
220
- 'workhosters:read',
221
- 'workhosters:write',
222
- ];
203
+ const allScopes = [...interfaces.data.apiTokenScopes];
223
204
 
224
205
  await DeesModal.createAndShow({
225
206
  heading: 'Create API Token',