@serve.zone/dcrouter 13.20.0 → 13.21.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 (34) hide show
  1. package/dist_serve/bundle.js +519 -519
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/classes.dcrouter.d.ts +5 -0
  4. package/dist_ts/classes.dcrouter.js +34 -10
  5. package/dist_ts/config/classes.route-config-manager.d.ts +1 -0
  6. package/dist_ts/config/classes.route-config-manager.js +4 -1
  7. package/dist_ts/monitoring/classes.metricsmanager.d.ts +6 -2
  8. package/dist_ts/monitoring/classes.metricsmanager.js +67 -41
  9. package/dist_ts/opsserver/handlers/security.handler.js +11 -5
  10. package/dist_ts/opsserver/handlers/stats.handler.js +2 -1
  11. package/dist_ts/vpn/classes.vpn-manager.d.ts +5 -1
  12. package/dist_ts/vpn/classes.vpn-manager.js +55 -17
  13. package/dist_ts_interfaces/data/stats.d.ts +10 -0
  14. package/dist_ts_web/00_commitinfo_data.js +1 -1
  15. package/dist_ts_web/appstate.js +23 -16
  16. package/dist_ts_web/elements/network/ops-view-network-activity.js +7 -3
  17. package/dist_ts_web/elements/network/ops-view-vpn.d.ts +3 -0
  18. package/dist_ts_web/elements/network/ops-view-vpn.js +44 -16
  19. package/package.json +3 -3
  20. package/readme.md +123 -155
  21. package/ts/00_commitinfo_data.ts +1 -1
  22. package/ts/classes.dcrouter.ts +51 -14
  23. package/ts/config/classes.route-config-manager.ts +6 -0
  24. package/ts/monitoring/classes.metricsmanager.ts +71 -40
  25. package/ts/opsserver/handlers/security.handler.ts +11 -5
  26. package/ts/opsserver/handlers/stats.handler.ts +1 -0
  27. package/ts/readme.md +46 -103
  28. package/ts/vpn/classes.vpn-manager.ts +66 -15
  29. package/ts_apiclient/readme.md +57 -59
  30. package/ts_web/00_commitinfo_data.ts +1 -1
  31. package/ts_web/appstate.ts +23 -18
  32. package/ts_web/elements/network/ops-view-network-activity.ts +6 -2
  33. package/ts_web/elements/network/ops-view-vpn.ts +50 -14
  34. package/ts_web/readme.md +27 -47
package/readme.md CHANGED
@@ -2,33 +2,31 @@
2
2
 
3
3
  ![dcrouter banner](https://code.foss.global/serve.zone/docs/raw/branch/main/dcrouter.png)
4
4
 
5
- `dcrouter` is a TypeScript control plane for running a serious multi-protocol edge or datacenter gateway from one process. It orchestrates HTTP/HTTPS and TCP routing through SmartProxy, email through smartmta, authoritative DNS and DNS-over-HTTPS, RADIUS, remote ingress tunnels, VPN access control, a typed Ops API, and a web dashboard.
5
+ `dcrouter` is a TypeScript control plane for running a serious multi-protocol edge or datacenter gateway from one process. It wires together SmartProxy for HTTP/HTTPS/TCP routing, smartmta for email, smartdns for authoritative DNS and DNS-over-HTTPS, smartradius, smartvpn, remote ingress tunnels, a TypedRequest API, and the Ops dashboard.
6
6
 
7
- It is built for operators who want one place to define routes, expose services, manage certificates, register domains and DNS providers, control VPN-only access, and inspect what is going on in production.
7
+ Use it when you want one place to define routes, manage domains and certificates, protect internal services, automate changes over an API, and operate the whole stack from a browser.
8
8
 
9
9
  ## Issue Reporting and Security
10
10
 
11
11
  For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
12
12
 
13
- ## Why dcrouter
13
+ ## Why It Works
14
14
 
15
- - 🌐 Run HTTP/HTTPS, TCP/SNI, email, DNS, RADIUS, VPN, and remote ingress from one orchestrated service.
16
- - 🔐 Keep certificates, routes, tokens, domains, and reusable route references in one management plane.
17
- - 🧠 Use system-managed routes for config-, email-, and DNS-derived traffic, plus API-managed routes for dynamic additions.
18
- - 📊 Get an Ops UI and TypedRequest API for monitoring, automation, and day-2 operations.
19
- - ⚡ Lean on Rust-backed data planes where it matters: proxying, DNS, email delivery, remote ingress, and VPN.
15
+ - 🌐 One runtime for HTTP/HTTPS/TCP, SMTP, authoritative DNS + DoH, RADIUS, VPN, and remote ingress.
16
+ - 🧠 Constructor config becomes system-managed routes, while API-created routes stay editable and clearly separated.
17
+ - 🔐 Certificates, DNS providers, domains, records, API tokens, access profiles, and protected routes live in one management plane.
18
+ - 🖥️ The OpsServer UI and TypedRequest API are first-class parts of the package, not an afterthought.
19
+ - ⚡ Qualifying HTTPS forward routes on port `443` get HTTP/3 augmentation by default unless you opt out.
20
20
 
21
- ## What It Covers
21
+ ## What You Get
22
22
 
23
23
  | Area | What dcrouter does |
24
24
  | --- | --- |
25
- | HTTP / HTTPS / TCP | SmartProxy-based routing, TLS termination or passthrough, path/domain matching, optional HTTP/3 augmentation |
26
- | Email | smartmta-based SMTP ingress and delivery, route-based email handling, DKIM-aware domain support |
27
- | DNS | Authoritative DNS, DNS-over-HTTPS bootstrap routes, provider-backed and dcrouter-hosted domains and records |
28
- | Certificates | ACME-aware certificate management with dashboard and API support |
29
- | Access control | Source profiles, network targets, VPN-gated routes, API tokens, admin auth |
30
- | Network edge | Remote ingress hub for edge nodes tunneling traffic into the router |
31
- | Operations | Web dashboard, TypedRequest API, logs, metrics, health, route and token management |
25
+ | HTTP / HTTPS / TCP | SmartProxy-based reverse proxying, TLS termination or passthrough, path/domain/port matching, TCP/SNI forwarding |
26
+ | Email | SMTP ingress and delivery via `UnifiedEmailServer`, route-based mail actions, email-domain management, queue and resend operations |
27
+ | DNS | Authoritative zones, nameserver bootstrap records, DNS-over-HTTPS routes on `/dns-query` and `/resolve`, provider-backed domain management |
28
+ | Access and Edge | VPN-gated routes, RADIUS auth/accounting, remote ingress edge registrations and tunnel hub support |
29
+ | Operations | Browser dashboard, TypedRequest API, route management, tokens, certificates, logs, metrics, and health views |
32
30
 
33
31
  ## Installation
34
32
 
@@ -38,7 +36,7 @@ pnpm add @serve.zone/dcrouter
38
36
 
39
37
  ## Quick Start
40
38
 
41
- This is the smallest realistic setup: one HTTP route, embedded database enabled, and the Ops dashboard on port `3000`.
39
+ This example stays on unprivileged ports so you can run it locally without root.
42
40
 
43
41
  ```typescript
44
42
  import { DcRouter } from '@serve.zone/dcrouter';
@@ -47,10 +45,10 @@ const router = new DcRouter({
47
45
  smartProxyConfig: {
48
46
  routes: [
49
47
  {
50
- name: 'app',
48
+ name: 'local-app',
51
49
  match: {
52
- domains: ['app.example.com'],
53
- ports: [80],
50
+ domains: ['localhost'],
51
+ ports: [18080],
54
52
  },
55
53
  action: {
56
54
  type: 'forward',
@@ -68,114 +66,61 @@ const router = new DcRouter({
68
66
  await router.start();
69
67
  ```
70
68
 
71
- Once the router is running, you can:
72
-
73
- - open the Ops dashboard on `http://localhost:3000`
74
- - inspect the route in the System Routes view
75
- - add API-managed routes through the dashboard or API client
76
- - enable DNS, email, VPN, remote ingress, or RADIUS by adding the corresponding config blocks
77
-
78
- ## Mental Model
69
+ After startup:
79
70
 
80
- `dcrouter` is not a toy reverse proxy with a few side features. It is an orchestrator that wires multiple specialized services into one management plane.
71
+ - open the dashboard at `http://localhost:3000`
72
+ - log in with the current built-in credentials `admin` / `admin`
73
+ - send proxied traffic to `http://localhost:18080`
74
+ - stop gracefully with `await router.stop()`
81
75
 
82
- | Layer | Responsibility |
83
- | --- | --- |
84
- | `DcRouter` | Startup order, shutdown, service wiring, configuration assembly, route hydration |
85
- | SmartProxy | HTTP/HTTPS, TCP/SNI, TLS, HTTP/3-capable route execution |
86
- | smartmta | SMTP ingress, queueing, DKIM-aware email processing and delivery |
87
- | SmartDNS | Authoritative DNS and DoH request handling |
88
- | smartradius | Network authentication, VLAN assignment, accounting |
89
- | remoteingress | Edge tunnel registrations and runtime forwarding into the hub |
90
- | smartvpn | VPN server and client access mediation for protected routes |
91
- | OpsServer + dashboard | Typed API and browser UI for operations |
92
- | smartdata-backed DB | Persistent routes, tokens, domains, records, profiles, cert metadata, caches |
93
-
94
- ## Route Model
76
+ ## Route Ownership Model
95
77
 
96
- Routes fall into two ownership classes:
78
+ dcrouter keeps route ownership explicit so automation does not accidentally stomp on system-generated traffic.
97
79
 
98
- | Route kind | Origin | Ownership | What users can do |
99
- | --- | --- | --- | --- |
100
- | System routes | `config`, `email`, `dns` | Derived from config or runtime-managed subsystems | View and toggle only |
101
- | API routes | `api` | Created through route-management API | Create, edit, delete, toggle |
80
+ | Route origin | Where it comes from | What you can do |
81
+ | --- | --- | --- |
82
+ | `config` | Constructor `smartProxyConfig.routes` and related seed config | View and toggle |
83
+ | `email` | Email listener and mail-routing derived routes | View and toggle |
84
+ | `dns` | Generated DoH and DNS-related routes | View and toggle |
85
+ | `api` | Created through the Ops UI or API client | Full CRUD |
102
86
 
103
87
  Important details:
104
88
 
105
- - system routes are persisted with a stable `systemKey`
106
- - config-, email-, and DNS-derived routes show up in the System Routes view
107
- - DoH routes are persisted as system-route templates and get their live socket handlers attached at apply time
108
- - system routes are managed by the system, not edited directly by operators
109
-
110
- ## Core Features
111
-
112
- ### Traffic Routing
113
-
114
- - Domain-, port-, and path-based SmartProxy routes
115
- - HTTP/HTTPS reverse proxying and generic TCP/SNI forwarding
116
- - Optional HTTP/3 augmentation for qualifying HTTPS routes
117
- - Reusable source profiles and network targets for route composition
118
- - Remote ingress aware routing for edge-delivered traffic
119
-
120
- ### Email
121
-
122
- - smartmta-based inbound email handling
123
- - Route-based mail actions such as forward, process, deliver, reject
124
- - DKIM-aware domain handling and DNS record generation support
125
- - Email-domain management through the Ops API and UI
126
- - Queue, resend, failure, and delivery inspection through the dashboard and API
127
-
128
- ### DNS
89
+ - system routes are persisted with stable `systemKey` values
90
+ - DNS-over-HTTPS routes are persisted and then hydrated with live socket handlers at runtime
91
+ - editing and deletion are reserved for `api` routes; system routes are toggle-only by design
129
92
 
130
- - Authoritative scopes via `dnsScopes`
131
- - Bootstrap nameserver domains via `dnsNsDomains`
132
- - DNS-over-HTTPS endpoints for `/dns-query` and `/resolve`
133
- - Managed domains, managed records, and provider-backed DNS integrations
134
- - Internal email DNS record generation for `internal-dns` email domains
93
+ ## Configuration Cheat Sheet
135
94
 
136
- ### Certificates and ACME
137
-
138
- - Certificate overview and operations through OpsServer
139
- - Import, export, delete, and reprovision flows
140
- - DB-backed ACME configuration management
141
- - Integration with managed DNS for certificate provisioning flows
142
- - Routes can declare `certificate: 'auto'`, but actual automated issuance depends on ACME being configured in the management plane
143
-
144
- ### VPN, RADIUS, and Remote Ingress
145
-
146
- - VPN-gated routes with target-profile-based access matching
147
- - WireGuard-oriented VPN management with dcrouter-side client lifecycle support
148
- - RADIUS MAB, VLAN assignment, and accounting
149
- - Remote ingress hub for edge nodes tunneling traffic into central routes
150
-
151
- ### Operations Plane
152
-
153
- - Web dashboard with overview, network, routes, access, security, domains, certificates, logs, and email views
154
- - TypedRequest API for automation and external control
155
- - API tokens with scoped access
156
- - Metrics, health, logs, and per-feature operational views
157
-
158
- ## Configuration Overview
159
-
160
- The main entry point is `IDcRouterOptions`.
95
+ The main entrypoint is `IDcRouterOptions`.
161
96
 
162
97
  | Option | Purpose |
163
98
  | --- | --- |
164
- | `smartProxyConfig` | Main HTTP/HTTPS and TCP/SNI routing configuration |
165
- | `emailConfig` | smartmta server config and email routes |
166
- | `emailPortConfig` | External-to-internal email port mapping and email storage path tuning |
167
- | `dnsNsDomains` | Nameserver hostnames used for NS bootstrap and DoH routes |
168
- | `dnsScopes` | Authoritative DNS zones managed by dcrouter |
169
- | `dnsRecords` | Static constructor-defined records |
170
- | `publicIp` / `proxyIps` | DNS A-record exposure strategy |
171
- | `dbConfig` | Embedded or external Mongo-backed persistence and seeding |
172
- | `radiusConfig` | RADIUS authentication, VLAN, and accounting setup |
173
- | `remoteIngressConfig` | Edge tunnel hub setup |
174
- | `vpnConfig` | VPN server and client access configuration |
175
- | `http3` | Global HTTP/3 behavior for qualifying routes |
176
- | `opsServerPort` | Dashboard and TypedRequest API port |
177
-
178
- ## Example: Enabling DNS, Email, and VPN
99
+ | `smartProxyConfig` | Main HTTP/HTTPS and TCP/SNI routing config |
100
+ | `emailConfig` | Email hostname, ports, domains, and mail routing rules |
101
+ | `emailPortConfig` | External-to-internal email port remapping and received-email storage path |
102
+ | `tls` | ACME contact and static certificate paths |
103
+ | `dnsNsDomains` | Nameserver hostnames used for NS bootstrap and DoH route generation |
104
+ | `dnsScopes` | Domains served authoritatively by the embedded DNS server |
105
+ | `dnsRecords` | Static constructor-defined DNS records |
106
+ | `publicIp` / `proxyIps` | How A records are exposed for nameserver and service records |
107
+ | `dbConfig` | Embedded LocalSmartDb or external MongoDB-backed persistence |
108
+ | `radiusConfig` | RADIUS auth, VLAN assignment, and accounting |
109
+ | `remoteIngressConfig` | Remote ingress hub and edge tunnel setup |
110
+ | `vpnConfig` | VPN server and client definitions for protected route access |
111
+ | `http3` | Global HTTP/3 behavior for qualifying HTTPS routes |
112
+ | `opsServerPort` | Ops dashboard and TypedRequest API port |
113
+
114
+ ## Important Behavior
115
+
116
+ - `dbConfig.enabled` defaults to `true`. If you do not provide `mongoDbUrl`, dcrouter starts an embedded local database automatically.
117
+ - If you disable the DB, constructor-driven traffic can still run, but DB-backed features such as persistent routes, tokens, ACME config, and managed domains do not start.
118
+ - Qualifying HTTPS forward routes on port `443` get HTTP/3 by default unless `http3.enabled === false` or the route opts out.
119
+ - DNS-over-HTTPS endpoints are generated on the first entry of `dnsNsDomains` at `/dns-query` and `/resolve`.
120
+ - Email listener ports are internally remapped by default, so common external ports such as `25`, `587`, and `465` end up on internal ports like `10025`, `10587`, and `10465`.
121
+ - Provider-backed domains can be managed in the Ops plane without being served by the embedded authoritative DNS server.
122
+
123
+ ## Bigger Example
179
124
 
180
125
  ```typescript
181
126
  import { DcRouter } from '@serve.zone/dcrouter';
@@ -195,6 +140,19 @@ const router = new DcRouter({
195
140
  tls: { mode: 'terminate', certificate: 'auto' },
196
141
  },
197
142
  },
143
+ {
144
+ name: 'internal-admin',
145
+ match: {
146
+ domains: ['internal.example.com'],
147
+ ports: [443],
148
+ },
149
+ action: {
150
+ type: 'forward',
151
+ targets: [{ host: '127.0.0.1', port: 9090 }],
152
+ tls: { mode: 'terminate', certificate: 'auto' },
153
+ },
154
+ vpnOnly: true,
155
+ },
198
156
  ],
199
157
  },
200
158
  emailConfig: {
@@ -233,93 +191,103 @@ const router = new DcRouter({
233
191
  dbConfig: {
234
192
  enabled: true,
235
193
  },
194
+ opsServerPort: 3000,
236
195
  });
237
196
 
238
197
  await router.start();
239
198
  ```
240
199
 
241
- ## Operations API and Dashboard
200
+ ## Automation
242
201
 
243
- With the database enabled, dcrouter exposes a management plane for:
202
+ dcrouter gives you three good integration layers:
244
203
 
245
- - routes and route toggles
246
- - API tokens
247
- - source profiles and network targets
248
- - DNS providers, domains, and records
249
- - ACME configuration and certificate lifecycle
250
- - email domains and email operations
251
- - VPN clients, remote ingress edges, and RADIUS data
204
+ - the browser dashboard served by `OpsServer`
205
+ - raw TypedRequest contracts via `@serve.zone/dcrouter/interfaces`
206
+ - a higher-level OO API client via `@serve.zone/dcrouter/apiclient` or `@serve.zone/dcrouter-apiclient`
252
207
 
253
- The browser dashboard is built from the `ts_web` package and is served by OpsServer. The same backend is accessible programmatically via TypedRequest or the dedicated API client package.
254
-
255
- ## Programmatic API Client
256
-
257
- Use the API client when you want automation or integration code instead of clicking through the dashboard.
208
+ ### OO API Client Example
258
209
 
259
210
  ```bash
260
211
  pnpm add @serve.zone/dcrouter-apiclient
261
212
  ```
262
213
 
263
214
  ```typescript
264
- import { DcRouterApiClient } from '@serve.zone/dcrouter/apiclient';
215
+ import { DcRouterApiClient } from '@serve.zone/dcrouter-apiclient';
265
216
 
266
217
  const client = new DcRouterApiClient({
267
218
  baseUrl: 'https://dcrouter.example.com',
268
219
  });
269
220
 
270
- await client.login('admin', 'password');
221
+ await client.login('admin', 'admin');
271
222
 
272
223
  const { routes } = await client.routes.list();
273
- const systemRoutes = routes.filter((route) => route.origin !== 'api');
274
-
275
- if (systemRoutes[0]) {
276
- await systemRoutes[0].toggle(false);
277
- }
278
224
 
279
225
  await client.routes.build()
280
226
  .setName('api-gateway')
281
227
  .setMatch({ ports: 443, domains: ['api.example.com'] })
282
228
  .setAction({ type: 'forward', targets: [{ host: '127.0.0.1', port: 8081 }] })
283
229
  .save();
230
+
231
+ if (routes[0] && routes[0].origin !== 'api') {
232
+ await routes[0].toggle(false);
233
+ }
284
234
  ```
285
235
 
286
- See `./ts_apiclient/readme.md` for the dedicated API-client package docs.
236
+ See `./ts_apiclient/readme.md` for the dedicated client package and `./ts_interfaces/readme.md` for the raw contracts.
237
+
238
+ ## OCI / Container Bootstrap
239
+
240
+ The package also includes an environment-driven bootstrap used by `runCli()` when `DCROUTER_MODE=OCI_CONTAINER`.
241
+
242
+ ```typescript
243
+ import { runCli } from '@serve.zone/dcrouter';
244
+
245
+ await runCli();
246
+ ```
247
+
248
+ Useful environment variables include:
249
+
250
+ - `DCROUTER_CONFIG_PATH`
251
+ - `DCROUTER_BASE_DIR`
252
+ - `DCROUTER_TLS_EMAIL`
253
+ - `DCROUTER_TLS_DOMAIN`
254
+ - `DCROUTER_PUBLIC_IP`
255
+ - `DCROUTER_PROXY_IPS`
256
+ - `DCROUTER_DNS_NS_DOMAINS`
257
+ - `DCROUTER_DNS_SCOPES`
258
+ - `DCROUTER_EMAIL_HOSTNAME`
259
+ - `DCROUTER_EMAIL_PORTS`
287
260
 
288
261
  ## Published Modules
289
262
 
290
- This repository publishes multiple modules from the same codebase.
263
+ This repository ships several module boundaries from one codebase.
291
264
 
292
265
  | Module | Purpose | Docs |
293
266
  | --- | --- | --- |
294
- | `@serve.zone/dcrouter` | Main orchestrator and server package | `./readme.md` |
295
- | `@serve.zone/dcrouter-interfaces` | Shared TypedRequest request and data interfaces | `./ts_interfaces/readme.md` |
296
- | `@serve.zone/dcrouter-migrations` | Startup migration runner for dcrouter data | `./ts_migrations/readme.md` |
297
- | `@serve.zone/dcrouter-web` | Web dashboard entry and UI components | `./ts_web/readme.md` |
298
- | `@serve.zone/dcrouter-apiclient` | Typed OO API client | `./ts_apiclient/readme.md` |
267
+ | `@serve.zone/dcrouter` | Main runtime and orchestrator | `./readme.md` |
268
+ | `@serve.zone/dcrouter/interfaces` | Shared request and data contracts as a subpath export | `./ts_interfaces/readme.md` |
269
+ | `@serve.zone/dcrouter/apiclient` | OO API client as a subpath export | `./ts_apiclient/readme.md` |
270
+ | `@serve.zone/dcrouter-interfaces` | Standalone interfaces package | `./ts_interfaces/readme.md` |
271
+ | `@serve.zone/dcrouter-apiclient` | Standalone OO API client package | `./ts_apiclient/readme.md` |
272
+ | `@serve.zone/dcrouter-migrations` | Standalone migration runner package | `./ts_migrations/readme.md` |
273
+ | `@serve.zone/dcrouter-web` | Standalone web dashboard package boundary | `./ts_web/readme.md` |
299
274
 
300
- ## Development and Testing
275
+ ## Development
301
276
 
302
277
  ```bash
303
278
  pnpm run build
304
279
  pnpm test
305
280
  ```
306
281
 
307
- Target a single test file while working on one area:
282
+ Target a single test while working on one area:
308
283
 
309
284
  ```bash
310
- tstest test/test.dns-runtime-routes.node.ts --verbose
285
+ tstest test/test.apiclient.ts --verbose
311
286
  ```
312
287
 
313
- ## Notes for Operators
314
-
315
- - Database-backed management features depend on `dbConfig.enabled !== false`.
316
- - If you disable the DB, constructor-configured services still run, but persistent management features are limited.
317
- - Nameserver domains are still required for DNS bootstrap and DoH route generation.
318
- - HTTP/3 is enabled by default for qualifying HTTPS routes unless disabled globally or per route.
319
-
320
288
  ## License and Legal Information
321
289
 
322
- This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](./license) file.
290
+ This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./license) file.
323
291
 
324
292
  **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.
325
293
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '13.20.0',
6
+ version: '13.21.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  }
@@ -26,6 +26,7 @@ import { RadiusServer, type IRadiusServerConfig } from './radius/index.js';
26
26
  import { RemoteIngressManager, TunnelManager } from './remoteingress/index.js';
27
27
  import { VpnManager, type IVpnManagerConfig } from './vpn/index.js';
28
28
  import { RouteConfigManager, ApiTokenManager, ReferenceResolver, DbSeeder, TargetProfileManager } from './config/index.js';
29
+ import type { TIpAllowEntry } from './config/classes.route-config-manager.js';
29
30
  import { SecurityLogger, ContentScanner, IPReputationChecker } from './security/index.js';
30
31
  import { type IHttp3Config, augmentRoutesWithHttp3 } from './http3/index.js';
31
32
  import { DnsManager } from './dns/manager.dns.js';
@@ -565,20 +566,7 @@ export class DcRouter {
565
566
  this.routeConfigManager = new RouteConfigManager(
566
567
  () => this.smartProxy,
567
568
  () => this.options.http3,
568
- this.options.vpnConfig?.enabled
569
- ? (route: import('../ts_interfaces/data/remoteingress.js').IDcRouterRouteConfig, routeId?: string) => {
570
- if (!this.vpnManager || !this.targetProfileManager) {
571
- // VPN not ready yet — deny all until re-apply after VPN starts
572
- return [];
573
- }
574
- return this.targetProfileManager.getMatchingClientIps(
575
- route,
576
- routeId,
577
- this.vpnManager.listClients(),
578
- this.routeConfigManager?.getRoutes() || new Map(),
579
- );
580
- }
581
- : undefined,
569
+ this.createVpnRouteAllowListResolver(),
582
570
  this.referenceResolver,
583
571
  // Sync routes to RemoteIngressManager whenever routes change,
584
572
  // then push updated derived ports to the Rust hub binary
@@ -2292,6 +2280,32 @@ export class DcRouter {
2292
2280
  /**
2293
2281
  * Set up VPN server for VPN-based route access control.
2294
2282
  */
2283
+ private createVpnRouteAllowListResolver(): ((
2284
+ route: import('../ts_interfaces/data/remoteingress.js').IDcRouterRouteConfig,
2285
+ routeId?: string,
2286
+ ) => TIpAllowEntry[]) | undefined {
2287
+ if (!this.options.vpnConfig?.enabled) {
2288
+ return undefined;
2289
+ }
2290
+
2291
+ return (
2292
+ route: import('../ts_interfaces/data/remoteingress.js').IDcRouterRouteConfig,
2293
+ routeId?: string,
2294
+ ) => {
2295
+ if (!this.vpnManager || !this.targetProfileManager) {
2296
+ // VPN not ready yet — deny all until re-apply after VPN starts.
2297
+ return [];
2298
+ }
2299
+
2300
+ return this.targetProfileManager.getMatchingClientIps(
2301
+ route,
2302
+ routeId,
2303
+ this.vpnManager.listClients(),
2304
+ this.routeConfigManager?.getRoutes() || new Map(),
2305
+ );
2306
+ };
2307
+ }
2308
+
2295
2309
  private async setupVpnServer(): Promise<void> {
2296
2310
  if (!this.options.vpnConfig?.enabled) {
2297
2311
  return;
@@ -2441,6 +2455,29 @@ export class DcRouter {
2441
2455
 
2442
2456
  logger.log('info', 'RADIUS configuration updated');
2443
2457
  }
2458
+
2459
+ /**
2460
+ * Update VPN configuration at runtime.
2461
+ */
2462
+ public async updateVpnConfig(config: IDcRouterOptions['vpnConfig']): Promise<void> {
2463
+ if (this.vpnManager) {
2464
+ await this.vpnManager.stop();
2465
+ this.vpnManager = undefined;
2466
+ }
2467
+
2468
+ this.options.vpnConfig = config;
2469
+ this.vpnDomainIpCache.clear();
2470
+ this.warnedWildcardVpnDomains.clear();
2471
+ this.routeConfigManager?.setVpnClientIpsResolver(this.createVpnRouteAllowListResolver());
2472
+
2473
+ if (this.options.vpnConfig?.enabled) {
2474
+ await this.setupVpnServer();
2475
+ } else {
2476
+ await this.routeConfigManager?.applyRoutes();
2477
+ }
2478
+
2479
+ logger.log('info', 'VPN configuration updated');
2480
+ }
2444
2481
  }
2445
2482
 
2446
2483
  // Re-export email server types for convenience
@@ -73,6 +73,12 @@ export class RouteConfigManager {
73
73
  return this.routes.get(id);
74
74
  }
75
75
 
76
+ public setVpnClientIpsResolver(
77
+ resolver?: (route: IDcRouterRouteConfig, routeId?: string) => TIpAllowEntry[],
78
+ ): void {
79
+ this.getVpnClientIpsForRoute = resolver;
80
+ }
81
+
76
82
  /**
77
83
  * Load persisted routes, seed serializable config/email/dns routes,
78
84
  * compute warnings, and apply the combined DB-backed + runtime route set to SmartProxy.