@serve.zone/dcrouter 13.19.1 → 13.20.2
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 +700 -690
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +5 -0
- package/dist_ts/classes.dcrouter.js +34 -10
- package/dist_ts/config/classes.route-config-manager.d.ts +1 -0
- package/dist_ts/config/classes.route-config-manager.js +12 -2
- package/dist_ts/vpn/classes.vpn-manager.d.ts +5 -1
- package/dist_ts/vpn/classes.vpn-manager.js +55 -17
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/network/ops-view-routes.js +70 -10
- package/dist_ts_web/elements/network/ops-view-vpn.d.ts +3 -0
- package/dist_ts_web/elements/network/ops-view-vpn.js +44 -16
- package/package.json +1 -1
- package/readme.md +123 -155
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +51 -14
- package/ts/config/classes.route-config-manager.ts +16 -1
- package/ts/readme.md +46 -103
- package/ts/vpn/classes.vpn-manager.ts +66 -15
- package/ts_apiclient/readme.md +57 -59
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/network/ops-view-routes.ts +71 -8
- package/ts_web/elements/network/ops-view-vpn.ts +50 -14
- package/ts_web/readme.md +27 -47
package/ts/readme.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# @serve.zone/dcrouter
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
5
|
-
This is the main entry point for DcRouter. It provides the `DcRouter` class that wires together SmartProxy, smartmta, SmartDNS, SmartRadius, RemoteIngress, and the OpsServer dashboard into a single cohesive service.
|
|
3
|
+
The `ts/` directory is the main dcrouter runtime package. It exposes the `DcRouter` orchestrator, `IDcRouterOptions`, `runCli()`, and the server-side exports that matter when you want to boot the full router stack from code.
|
|
6
4
|
|
|
7
5
|
## Issue Reporting and Security
|
|
8
6
|
|
|
@@ -14,7 +12,19 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
14
12
|
pnpm add @serve.zone/dcrouter
|
|
15
13
|
```
|
|
16
14
|
|
|
17
|
-
##
|
|
15
|
+
## Core Exports
|
|
16
|
+
|
|
17
|
+
| Export | Purpose |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `DcRouter` | Main orchestrator for proxying, DNS, email, VPN, RADIUS, remote ingress, DB, and OpsServer |
|
|
20
|
+
| `IDcRouterOptions` | Top-level configuration shape |
|
|
21
|
+
| `runCli()` | Bootstrap helper; uses OCI env-driven config when `DCROUTER_MODE=OCI_CONTAINER` |
|
|
22
|
+
| `UnifiedEmailServer` and smartmta types | Re-exported email server primitives |
|
|
23
|
+
| `RadiusServer` and related types | RADIUS server runtime exports |
|
|
24
|
+
| `RemoteIngressManager` and `TunnelManager` | Remote ingress orchestration exports |
|
|
25
|
+
| `IHttp3Config` | HTTP/3 configuration for qualifying HTTPS routes |
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
18
28
|
|
|
19
29
|
```typescript
|
|
20
30
|
import { DcRouter } from '@serve.zone/dcrouter';
|
|
@@ -23,120 +33,53 @@ const router = new DcRouter({
|
|
|
23
33
|
smartProxyConfig: {
|
|
24
34
|
routes: [
|
|
25
35
|
{
|
|
26
|
-
name: '
|
|
27
|
-
match: {
|
|
36
|
+
name: 'local-app',
|
|
37
|
+
match: {
|
|
38
|
+
domains: ['localhost'],
|
|
39
|
+
ports: [18080],
|
|
40
|
+
},
|
|
28
41
|
action: {
|
|
29
42
|
type: 'forward',
|
|
30
|
-
targets: [{ host: '
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
43
|
+
targets: [{ host: '127.0.0.1', port: 3001 }],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
34
46
|
],
|
|
35
|
-
|
|
36
|
-
|
|
47
|
+
},
|
|
48
|
+
opsServerPort: 3000,
|
|
37
49
|
});
|
|
38
50
|
|
|
39
51
|
await router.start();
|
|
40
|
-
// OpsServer dashboard at http://localhost:3000 (configurable via opsServerPort)
|
|
41
|
-
|
|
42
|
-
// Graceful shutdown
|
|
43
|
-
await router.stop();
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Module Structure
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
ts/
|
|
50
|
-
├── index.ts # Main exports (DcRouter, re-exported smartmta types)
|
|
51
|
-
├── classes.dcrouter.ts # DcRouter orchestrator class + IDcRouterOptions
|
|
52
|
-
├── classes.cert-provision-scheduler.ts # Per-domain cert backoff scheduler
|
|
53
|
-
├── classes.storage-cert-manager.ts # SmartAcme cert manager backed by StorageManager
|
|
54
|
-
├── logger.ts # Structured logging utility
|
|
55
|
-
├── paths.ts # Centralized data directory paths
|
|
56
|
-
├── plugins.ts # All dependency imports
|
|
57
|
-
├── cache/ # Cache database (smartdata + LocalTsmDb)
|
|
58
|
-
│ ├── classes.cachedb.ts # CacheDb singleton
|
|
59
|
-
│ ├── classes.cachecleaner.ts # TTL-based cleanup
|
|
60
|
-
│ └── documents/ # Cached document models
|
|
61
|
-
├── config/ # Configuration utilities
|
|
62
|
-
├── errors/ # Error classes and retry logic
|
|
63
|
-
├── http3/ # HTTP/3 (QUIC) route augmentation
|
|
64
|
-
│ ├── index.ts # Barrel export
|
|
65
|
-
│ └── http3-route-augmentation.ts # Pure utility: augmentRoutesWithHttp3(), IHttp3Config
|
|
66
|
-
├── monitoring/ # MetricsManager (SmartMetrics integration)
|
|
67
|
-
├── opsserver/ # OpsServer dashboard + API handlers
|
|
68
|
-
│ ├── classes.opsserver.ts # HTTP server + TypedRouter setup
|
|
69
|
-
│ └── handlers/ # TypedRequest handlers by domain
|
|
70
|
-
│ ├── admin.handler.ts # Auth (login/logout/verify)
|
|
71
|
-
│ ├── stats.handler.ts # Statistics + health
|
|
72
|
-
│ ├── config.handler.ts # Configuration (read-only)
|
|
73
|
-
│ ├── logs.handler.ts # Log retrieval
|
|
74
|
-
│ ├── email.handler.ts # Email operations
|
|
75
|
-
│ ├── certificate.handler.ts # Certificate management
|
|
76
|
-
│ ├── radius.handler.ts # RADIUS management
|
|
77
|
-
│ ├── remoteingress.handler.ts # Remote ingress edge + token management
|
|
78
|
-
│ ├── route-management.handler.ts # Programmatic route CRUD
|
|
79
|
-
│ ├── api-token.handler.ts # API token management
|
|
80
|
-
│ └── security.handler.ts # Security metrics + connections
|
|
81
|
-
├── radius/ # RADIUS server integration
|
|
82
|
-
├── remoteingress/ # Remote ingress hub integration
|
|
83
|
-
│ ├── classes.remoteingress-manager.ts # Edge CRUD + port derivation
|
|
84
|
-
│ └── classes.tunnel-manager.ts # Rust hub lifecycle + status tracking
|
|
85
|
-
├── security/ # Security utilities
|
|
86
|
-
├── sms/ # SMS integration
|
|
87
|
-
└── storage/ # StorageManager (filesystem/custom/memory)
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Exports
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
// Main class
|
|
94
|
-
export { DcRouter, IDcRouterOptions } from './classes.dcrouter.js';
|
|
95
|
-
|
|
96
|
-
// Re-exported from smartmta
|
|
97
|
-
export { UnifiedEmailServer } from '@push.rocks/smartmta';
|
|
98
|
-
export type { IUnifiedEmailServerOptions, IEmailRoute, IEmailDomainConfig } from '@push.rocks/smartmta';
|
|
99
|
-
|
|
100
|
-
// RADIUS
|
|
101
|
-
export { RadiusServer, IRadiusServerConfig } from './radius/index.js';
|
|
102
|
-
|
|
103
|
-
// Remote Ingress
|
|
104
|
-
export { RemoteIngressManager, TunnelManager } from './remoteingress/index.js';
|
|
105
|
-
|
|
106
|
-
// HTTP/3
|
|
107
|
-
export type { IHttp3Config } from './http3/index.js';
|
|
108
52
|
```
|
|
109
53
|
|
|
110
|
-
##
|
|
111
|
-
|
|
112
|
-
### `DcRouter`
|
|
113
|
-
|
|
114
|
-
The central orchestrator. Accepts `IDcRouterOptions` and manages the lifecycle of all sub-services:
|
|
54
|
+
## What `DcRouter` Manages
|
|
115
55
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
| `remoteIngressConfig` | RemoteIngressManager + TunnelManager | `@serve.zone/remoteingress` |
|
|
123
|
-
| `tls` + `dnsChallenge` | SmartAcme (ACME cert provisioning) | `@push.rocks/smartacme` |
|
|
124
|
-
| `http3` | HTTP/3 route augmentation (enabled by default) | built-in |
|
|
125
|
-
| `cacheConfig` | CacheDb (embedded MongoDB) | `@push.rocks/smartdata` |
|
|
126
|
-
| *(always)* | OpsServer (dashboard + API) | `@api.global/typedserver` |
|
|
127
|
-
| *(always)* | MetricsManager | `@push.rocks/smartmetrics` |
|
|
56
|
+
- SmartProxy for HTTP/HTTPS/TCP routes
|
|
57
|
+
- `UnifiedEmailServer` for SMTP ingress and delivery when `emailConfig` is present
|
|
58
|
+
- DB-backed managers for routes, API tokens, target profiles, domains, records, ACME config, and email domains when the DB is enabled
|
|
59
|
+
- embedded authoritative DNS and DoH route generation from `dnsNsDomains` and `dnsScopes`
|
|
60
|
+
- VPN, RADIUS, and remote ingress services when their config blocks are enabled
|
|
61
|
+
- OpsServer and the dashboard, which start on every boot
|
|
128
62
|
|
|
129
|
-
|
|
63
|
+
## Important Runtime Behavior
|
|
130
64
|
|
|
131
|
-
|
|
65
|
+
- The DB is enabled by default and uses an embedded local database when no external MongoDB URL is provided.
|
|
66
|
+
- System routes from config, email, and DNS are persisted with stable ownership and are toggle-only.
|
|
67
|
+
- API-created routes are the only routes intended for full CRUD from the dashboard or client SDK.
|
|
68
|
+
- Qualifying HTTPS forward routes on port `443` get HTTP/3 augmentation by default.
|
|
69
|
+
- `runCli()` is the supported code-level bootstrap entrypoint; the package does not expose a separate npm `bin` command.
|
|
132
70
|
|
|
133
|
-
|
|
71
|
+
## Use Another Module When...
|
|
134
72
|
|
|
135
|
-
|
|
73
|
+
| Need | Module |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| A higher-level client SDK for a running router | `@serve.zone/dcrouter-apiclient` or `@serve.zone/dcrouter/apiclient` |
|
|
76
|
+
| Raw TypedRequest request/data contracts | `@serve.zone/dcrouter-interfaces` or `@serve.zone/dcrouter/interfaces` |
|
|
77
|
+
| The standalone migration runner | `@serve.zone/dcrouter-migrations` |
|
|
78
|
+
| The browser dashboard module boundary | `@serve.zone/dcrouter-web` |
|
|
136
79
|
|
|
137
80
|
## License and Legal Information
|
|
138
81
|
|
|
139
|
-
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [
|
|
82
|
+
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](../license) file.
|
|
140
83
|
|
|
141
84
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
142
85
|
|
|
@@ -148,7 +91,7 @@ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark G
|
|
|
148
91
|
|
|
149
92
|
### Company Information
|
|
150
93
|
|
|
151
|
-
Task Venture Capital GmbH
|
|
94
|
+
Task Venture Capital GmbH
|
|
152
95
|
Registered at District Court Bremen HRB 35230 HB, Germany
|
|
153
96
|
|
|
154
97
|
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
|
@@ -112,14 +112,11 @@ export class VpnManager {
|
|
|
112
112
|
const subnet = this.getSubnet();
|
|
113
113
|
const wgListenPort = this.config.wgListenPort ?? 51820;
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
let configuredMode = this.forwardingModeOverride ?? this.config.forwardingMode ?? 'socket';
|
|
118
|
-
if (anyClientUsesHostIp && configuredMode === 'socket') {
|
|
119
|
-
configuredMode = 'hybrid';
|
|
115
|
+
const desiredForwardingMode = this.getDesiredForwardingMode(anyClientUsesHostIp);
|
|
116
|
+
if (anyClientUsesHostIp && desiredForwardingMode === 'hybrid') {
|
|
120
117
|
logger.log('info', 'VPN: Auto-upgrading forwarding mode to hybrid (client with useHostIp detected)');
|
|
121
118
|
}
|
|
122
|
-
const forwardingMode =
|
|
119
|
+
const forwardingMode = desiredForwardingMode;
|
|
123
120
|
const isBridge = forwardingMode === 'bridge';
|
|
124
121
|
this.resolvedForwardingMode = forwardingMode;
|
|
125
122
|
this.forwardingModeOverride = undefined;
|
|
@@ -218,7 +215,7 @@ export class VpnManager {
|
|
|
218
215
|
throw new Error('VPN server not running');
|
|
219
216
|
}
|
|
220
217
|
|
|
221
|
-
await this.
|
|
218
|
+
await this.ensureForwardingModeForNextClient(opts.useHostIp === true);
|
|
222
219
|
|
|
223
220
|
const doc = new VpnClientDoc();
|
|
224
221
|
doc.clientId = opts.clientId;
|
|
@@ -298,6 +295,7 @@ export class VpnManager {
|
|
|
298
295
|
if (doc) {
|
|
299
296
|
await doc.delete();
|
|
300
297
|
}
|
|
298
|
+
await this.reconcileForwardingMode();
|
|
301
299
|
this.config.onClientChanged?.();
|
|
302
300
|
}
|
|
303
301
|
|
|
@@ -368,8 +366,10 @@ export class VpnManager {
|
|
|
368
366
|
await this.persistClient(client);
|
|
369
367
|
|
|
370
368
|
if (this.vpnServer) {
|
|
371
|
-
await this.
|
|
372
|
-
|
|
369
|
+
const restarted = await this.reconcileForwardingMode();
|
|
370
|
+
if (!restarted) {
|
|
371
|
+
await this.vpnServer.updateClient(clientId, this.buildClientRuntimeUpdate(client));
|
|
372
|
+
}
|
|
373
373
|
}
|
|
374
374
|
|
|
375
375
|
this.config.onClientChanged?.();
|
|
@@ -563,6 +563,28 @@ export class VpnManager {
|
|
|
563
563
|
?? 'socket';
|
|
564
564
|
}
|
|
565
565
|
|
|
566
|
+
private hasHostIpClients(extraHostIpClient = false): boolean {
|
|
567
|
+
if (extraHostIpClient) {
|
|
568
|
+
return true;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
for (const client of this.clients.values()) {
|
|
572
|
+
if (client.useHostIp) {
|
|
573
|
+
return true;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
private getDesiredForwardingMode(hasHostIpClients = this.hasHostIpClients()): 'socket' | 'bridge' | 'hybrid' {
|
|
581
|
+
const configuredMode = this.forwardingModeOverride ?? this.config.forwardingMode ?? 'socket';
|
|
582
|
+
if (configuredMode !== 'socket') {
|
|
583
|
+
return configuredMode;
|
|
584
|
+
}
|
|
585
|
+
return hasHostIpClients ? 'hybrid' : 'socket';
|
|
586
|
+
}
|
|
587
|
+
|
|
566
588
|
private getDefaultDestinationPolicy(
|
|
567
589
|
forwardingMode: 'socket' | 'bridge' | 'hybrid',
|
|
568
590
|
useHostIp = false,
|
|
@@ -633,16 +655,45 @@ export class VpnManager {
|
|
|
633
655
|
};
|
|
634
656
|
}
|
|
635
657
|
|
|
636
|
-
private async
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
logger.log('info',
|
|
641
|
-
this.forwardingModeOverride =
|
|
658
|
+
private async restartWithForwardingMode(
|
|
659
|
+
forwardingMode: 'socket' | 'bridge' | 'hybrid',
|
|
660
|
+
reason: string,
|
|
661
|
+
): Promise<void> {
|
|
662
|
+
logger.log('info', `VPN: Restarting server in ${forwardingMode} mode ${reason}`);
|
|
663
|
+
this.forwardingModeOverride = forwardingMode;
|
|
642
664
|
await this.stop();
|
|
643
665
|
await this.start();
|
|
644
666
|
}
|
|
645
667
|
|
|
668
|
+
private async ensureForwardingModeForNextClient(useHostIp: boolean): Promise<void> {
|
|
669
|
+
if (!this.vpnServer) return;
|
|
670
|
+
|
|
671
|
+
const desiredForwardingMode = this.getDesiredForwardingMode(this.hasHostIpClients(useHostIp));
|
|
672
|
+
if (desiredForwardingMode === this.getResolvedForwardingMode()) {
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
await this.restartWithForwardingMode(desiredForwardingMode, 'to support a host-IP client');
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
private async reconcileForwardingMode(): Promise<boolean> {
|
|
680
|
+
if (!this.vpnServer) {
|
|
681
|
+
return false;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
const desiredForwardingMode = this.getDesiredForwardingMode();
|
|
685
|
+
const currentForwardingMode = this.getResolvedForwardingMode();
|
|
686
|
+
if (desiredForwardingMode === currentForwardingMode) {
|
|
687
|
+
return false;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
const reason = desiredForwardingMode === 'socket'
|
|
691
|
+
? 'because no host-IP clients remain'
|
|
692
|
+
: 'to support host-IP clients';
|
|
693
|
+
await this.restartWithForwardingMode(desiredForwardingMode, reason);
|
|
694
|
+
return true;
|
|
695
|
+
}
|
|
696
|
+
|
|
646
697
|
private async persistClient(client: VpnClientDoc): Promise<void> {
|
|
647
698
|
await client.save();
|
|
648
699
|
}
|
package/ts_apiclient/readme.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# @serve.zone/dcrouter-apiclient
|
|
2
2
|
|
|
3
|
-
Typed, object-oriented
|
|
4
|
-
|
|
5
|
-
Use this package when you want a clean TypeScript client instead of manually firing TypedRequest calls. It wraps the OpsServer API in resource managers and resource classes such as routes, certificates, tokens, edges, emails, stats, logs, config, and RADIUS.
|
|
3
|
+
Typed, object-oriented client for operating a running dcrouter instance. It wraps the OpsServer `/typedrequest` API in managers and resource classes so your scripts can work with routes, certificates, tokens, remote ingress edges, emails, stats, config, logs, and RADIUS without hand-rolling requests.
|
|
6
4
|
|
|
7
5
|
## Issue Reporting and Security
|
|
8
6
|
|
|
@@ -14,7 +12,7 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
14
12
|
pnpm add @serve.zone/dcrouter-apiclient
|
|
15
13
|
```
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
You can also import the same client through the main package subpath:
|
|
18
16
|
|
|
19
17
|
```typescript
|
|
20
18
|
import { DcRouterApiClient } from '@serve.zone/dcrouter/apiclient';
|
|
@@ -29,24 +27,40 @@ const client = new DcRouterApiClient({
|
|
|
29
27
|
baseUrl: 'https://dcrouter.example.com',
|
|
30
28
|
});
|
|
31
29
|
|
|
32
|
-
await client.login('admin', '
|
|
30
|
+
await client.login('admin', 'admin');
|
|
33
31
|
|
|
34
|
-
const { routes } = await client.routes.list();
|
|
35
|
-
console.log(routes.
|
|
32
|
+
const { routes, warnings } = await client.routes.list();
|
|
33
|
+
console.log('route count', routes.length, 'warnings', warnings.length);
|
|
36
34
|
|
|
37
|
-
await client.routes.build()
|
|
35
|
+
const route = await client.routes.build()
|
|
38
36
|
.setName('api-gateway')
|
|
39
37
|
.setMatch({ ports: 443, domains: ['api.example.com'] })
|
|
40
38
|
.setAction({ type: 'forward', targets: [{ host: '127.0.0.1', port: 8080 }] })
|
|
41
39
|
.save();
|
|
40
|
+
|
|
41
|
+
await route.toggle(false);
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
## What the Client Gives You
|
|
45
|
+
|
|
46
|
+
| Manager | Purpose |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `client.routes` | List merged routes, create API routes, toggle routes |
|
|
49
|
+
| `client.certificates` | Inspect certificates and run certificate operations |
|
|
50
|
+
| `client.apiTokens` | Create, list, toggle, roll, and revoke API tokens |
|
|
51
|
+
| `client.remoteIngress` | Manage edge registrations, statuses, and connection tokens |
|
|
52
|
+
| `client.emails` | Inspect email items and trigger resend flows |
|
|
53
|
+
| `client.stats` | Health, statistics, and operational summaries |
|
|
54
|
+
| `client.config` | Read the current configuration view |
|
|
55
|
+
| `client.logs` | Read recent logs and log-related data |
|
|
56
|
+
| `client.radius` | Manage RADIUS clients, VLANs, and sessions |
|
|
57
|
+
|
|
44
58
|
## Authentication Modes
|
|
45
59
|
|
|
46
60
|
| Mode | How it works |
|
|
47
61
|
| --- | --- |
|
|
48
|
-
| Admin login | Call `login(username, password)` and the
|
|
49
|
-
| API token | Pass `apiToken`
|
|
62
|
+
| Admin login | Call `login(username, password)` and the returned identity is stored on the client |
|
|
63
|
+
| API token | Pass `apiToken` in the constructor and it is injected into requests automatically |
|
|
50
64
|
|
|
51
65
|
```typescript
|
|
52
66
|
const client = new DcRouterApiClient({
|
|
@@ -55,52 +69,19 @@ const client = new DcRouterApiClient({
|
|
|
55
69
|
});
|
|
56
70
|
```
|
|
57
71
|
|
|
58
|
-
## Main Managers
|
|
59
|
-
|
|
60
|
-
| Manager | Purpose |
|
|
61
|
-
| --- | --- |
|
|
62
|
-
| `client.routes` | List routes and create API-managed routes |
|
|
63
|
-
| `client.certificates` | Inspect and operate on certificate records |
|
|
64
|
-
| `client.apiTokens` | Create, list, toggle, roll, revoke API tokens |
|
|
65
|
-
| `client.remoteIngress` | Manage registered remote ingress edges |
|
|
66
|
-
| `client.stats` | Read operational metrics and health data |
|
|
67
|
-
| `client.config` | Read current configuration view |
|
|
68
|
-
| `client.logs` | Read recent logs or stream them |
|
|
69
|
-
| `client.emails` | List emails and trigger resend flows |
|
|
70
|
-
| `client.radius` | Operate on RADIUS clients, VLANs, sessions, and accounting |
|
|
71
|
-
|
|
72
|
-
## Route Behavior
|
|
73
|
-
|
|
74
|
-
Routes are returned as `Route` instances with:
|
|
75
|
-
|
|
76
|
-
- `id`
|
|
77
|
-
- `name`
|
|
78
|
-
- `enabled`
|
|
79
|
-
- `origin`
|
|
80
|
-
|
|
81
72
|
Important behavior:
|
|
82
73
|
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
const { routes } = await client.routes.list();
|
|
74
|
+
- `baseUrl` is normalized, and the client automatically calls `${baseUrl}/typedrequest`
|
|
75
|
+
- `buildRequestPayload()` injects the current identity and optional API token for you
|
|
76
|
+
- system routes can be toggled, but only API routes are meant for edit and delete flows
|
|
89
77
|
|
|
90
|
-
|
|
91
|
-
if (route.origin !== 'api') {
|
|
92
|
-
await route.toggle(false);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Builder Example
|
|
78
|
+
## Route Builder Example
|
|
98
79
|
|
|
99
80
|
```typescript
|
|
100
|
-
const
|
|
81
|
+
const newRoute = await client.routes.build()
|
|
101
82
|
.setName('internal-app')
|
|
102
83
|
.setMatch({
|
|
103
|
-
ports:
|
|
84
|
+
ports: 443,
|
|
104
85
|
domains: ['internal.example.com'],
|
|
105
86
|
})
|
|
106
87
|
.setAction({
|
|
@@ -110,30 +91,47 @@ const route = await client.routes.build()
|
|
|
110
91
|
.setEnabled(true)
|
|
111
92
|
.save();
|
|
112
93
|
|
|
113
|
-
await
|
|
94
|
+
await newRoute.update({
|
|
95
|
+
action: {
|
|
96
|
+
type: 'forward',
|
|
97
|
+
targets: [{ host: '127.0.0.1', port: 3001 }],
|
|
98
|
+
},
|
|
99
|
+
});
|
|
114
100
|
```
|
|
115
101
|
|
|
116
|
-
##
|
|
102
|
+
## Token and Remote Ingress Example
|
|
117
103
|
|
|
118
104
|
```typescript
|
|
119
|
-
const
|
|
120
|
-
|
|
105
|
+
const token = await client.apiTokens.build()
|
|
106
|
+
.setName('ci-token')
|
|
107
|
+
.setScopes(['routes:read', 'routes:write'])
|
|
108
|
+
.setExpiresInDays(30)
|
|
109
|
+
.save();
|
|
110
|
+
|
|
111
|
+
console.log('copy this once:', token.tokenValue);
|
|
112
|
+
|
|
113
|
+
const edge = await client.remoteIngress.build()
|
|
114
|
+
.setName('edge-eu-1')
|
|
115
|
+
.setListenPorts([80, 443])
|
|
116
|
+
.setAutoDerivePorts(true)
|
|
117
|
+
.setTags(['production', 'eu'])
|
|
118
|
+
.save();
|
|
121
119
|
|
|
122
|
-
const
|
|
123
|
-
|
|
120
|
+
const connectionToken = await edge.getConnectionToken();
|
|
121
|
+
console.log(connectionToken);
|
|
124
122
|
```
|
|
125
123
|
|
|
126
124
|
## What This Package Does Not Do
|
|
127
125
|
|
|
128
126
|
- It does not start dcrouter.
|
|
129
|
-
- It does not
|
|
130
|
-
- It does not replace the
|
|
127
|
+
- It does not bundle the dashboard.
|
|
128
|
+
- It does not replace the raw interfaces package when you want low-level TypedRequest contracts.
|
|
131
129
|
|
|
132
|
-
Use `@serve.zone/dcrouter` to run the server
|
|
130
|
+
Use `@serve.zone/dcrouter` to run the server and `@serve.zone/dcrouter-interfaces` for the shared request/data types.
|
|
133
131
|
|
|
134
132
|
## License and Legal Information
|
|
135
133
|
|
|
136
|
-
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [
|
|
134
|
+
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](../license) file.
|
|
137
135
|
|
|
138
136
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
139
137
|
|