From dce1de8c4bf55be964ab929fd192d6e1ad897d0e Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Wed, 18 Feb 2026 18:47:18 +0000 Subject: [PATCH] feat(remote-ingress): add Remote Ingress hub integration, OpsServer UI, APIs, and docs --- changelog.md | 12 ++ package.json | 2 +- pnpm-lock.yaml | 10 +- readme.md | 173 +++++++++++++++++++++- ts/00_commitinfo_data.ts | 2 +- ts/readme.md | 146 ++++++++++++++++++ ts_interfaces/readme.md | 49 ++++-- ts_web/00_commitinfo_data.ts | 2 +- ts_web/appstate.ts | 15 +- ts_web/elements/ops-view-certificates.ts | 2 +- ts_web/elements/ops-view-network.ts | 4 +- ts_web/elements/ops-view-remoteingress.ts | 52 ++++++- ts_web/readme.md | 30 ++++ 13 files changed, 456 insertions(+), 43 deletions(-) create mode 100644 ts/readme.md diff --git a/changelog.md b/changelog.md index 55fde43..ddd18c8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,17 @@ # Changelog +## 2026-02-18 - 6.12.0 - feat(remote-ingress) +add Remote Ingress hub integration, OpsServer UI, APIs, and docs + +- Integrates RemoteIngress (hub/tunnel) into DcRouter: runtime manager, tunnel manager and Rust data plane references added +- Bumps dependency @serve.zone/remoteingress to ^3.3.0 +- Adds configuration defaults and IDcRouterOptions.remoteIngressConfig with tunnelPort/hubDomain/tls fields +- Introduces OpsServer API endpoints and TypedRequest methods for remote ingress: getRemoteIngresses, createRemoteIngress, updateRemoteIngress, deleteRemoteIngress, regenerateRemoteIngressSecret, getRemoteIngressStatus, getRemoteIngressConnectionToken +- UI updates: new Remote Ingress dashboard view, connection token generation & copy (clipboard API + fallback), auto-derived ports display, and toast notifications +- State/API rename: newEdgeSecret -> newEdgeId and clearNewEdgeIdAction; appstate fetchConnectionToken usage +- Documentation: README, ts/ and ts_web readmes, and ts_interfaces updated with interfaces and examples for Remote Ingress +- Minor UI icon updates (search -> fa:magnifyingGlass, clipboard icon casing) and other doc/README improvements + ## 2026-02-18 - 6.11.0 - feat(remoteingress) add ability to generate remote ingress connection tokens and UI copy action; add hubDomain config option; update remoteingress dependency to ^3.1.1 diff --git a/package.json b/package.json index 0f28f6e..8c1afac 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@push.rocks/smartstate": "^2.0.30", "@push.rocks/smartunique": "^3.0.9", "@serve.zone/interfaces": "^5.3.0", - "@serve.zone/remoteingress": "^3.1.1", + "@serve.zone/remoteingress": "^3.3.0", "@tsclass/tsclass": "^9.3.0", "lru-cache": "^11.2.6", "uuid": "^13.0.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d5748ec..66f72ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -96,8 +96,8 @@ importers: specifier: ^5.3.0 version: 5.3.0 '@serve.zone/remoteingress': - specifier: ^3.1.1 - version: 3.1.1 + specifier: ^3.3.0 + version: 3.3.0 '@tsclass/tsclass': specifier: ^9.3.0 version: 9.3.0 @@ -1340,8 +1340,8 @@ packages: '@serve.zone/interfaces@5.3.0': resolution: {integrity: sha512-venO7wtDR9ixzD9NhdERBGjNKbFA5LL0yHw4eqGh0UpmvtXVc3SFG0uuHDilOKMZqZ8bttV88qVsFy1aSTJrtA==} - '@serve.zone/remoteingress@3.1.1': - resolution: {integrity: sha512-tTN3hkLmfL8KeIEu7a685xNlESEZ548aFzKn+44yeUwABuQV5w3P39Pk2U3KAGB0K2prnpuzBGuoMaEIicE9Ew==} + '@serve.zone/remoteingress@3.3.0': + resolution: {integrity: sha512-nmw0F+Otrg78Xai9G3qLcP3NP4VkGPGm/6IGJmrXEgx3Z+ewh5Rhs1/rtN0mJFNXP77LZz1HuEBgR8aWbSHFQw==} '@sindresorhus/is@5.6.0': resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} @@ -6830,7 +6830,7 @@ snapshots: '@push.rocks/smartlog-interfaces': 3.0.2 '@tsclass/tsclass': 9.3.0 - '@serve.zone/remoteingress@3.1.1': + '@serve.zone/remoteingress@3.3.0': dependencies: '@push.rocks/qenv': 6.1.3 '@push.rocks/smartrust': 1.2.1 diff --git a/readme.md b/readme.md index 2d2875e..faf1886 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ **dcrouter: The all-in-one gateway for your datacenter.** 🚀 -A comprehensive traffic routing solution that provides unified gateway capabilities for HTTP/HTTPS, TCP/SNI, email (SMTP), DNS, and RADIUS protocols. Designed for enterprises requiring robust traffic management, automatic TLS certificate provisioning, and enterprise-grade email infrastructure — all from a single process. +A comprehensive traffic routing solution that provides unified gateway capabilities for HTTP/HTTPS, TCP/SNI, email (SMTP), DNS, RADIUS, and remote edge ingress — all from a single process. Designed for enterprises requiring robust traffic management, automatic TLS certificate provisioning, distributed edge networking, and enterprise-grade email infrastructure. ## Issue Reporting and Security @@ -21,6 +21,7 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community - [Email System](#email-system) - [DNS Server](#dns-server) - [RADIUS Server](#radius-server) +- [Remote Ingress](#remote-ingress) - [Certificate Management](#certificate-management) - [Storage & Caching](#storage--caching) - [Security Features](#security-features) @@ -60,6 +61,14 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community - **RADIUS accounting** for session tracking, traffic metering, and billing - **Real-time management** via OpsServer API +### 🌍 Remote Ingress (powered by [remoteingress](https://code.foss.global/serve.zone/remoteingress)) +- **Distributed edge networking** — accept traffic at remote edge nodes and tunnel it to the hub +- **Edge registration CRUD** with secret-based authentication +- **Auto-derived ports** — edges automatically pick up ports from routes tagged with `remoteIngress.enabled` +- **Connection tokens** — generate a single opaque base64url token containing hubHost, hubPort, edgeId, and secret for easy edge provisioning +- **Real-time status monitoring** — connected/disconnected state, public IP, active tunnels, heartbeat tracking +- **OpsServer dashboard** with enable/disable, edit, secret regeneration, token copy, and delete actions + ### ⚡ High Performance - **Rust-powered proxy engine** via SmartProxy for maximum throughput - **Rust-powered MTA engine** via smartmta (TypeScript + Rust hybrid) for reliable email delivery @@ -76,8 +85,9 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community ### 🖥️ OpsServer Dashboard - **Web-based management interface** with real-time monitoring - **JWT authentication** with session persistence -- **Live views** for connections, email queues, DNS queries, RADIUS sessions, certificates, and security events +- **Live views** for connections, email queues, DNS queries, RADIUS sessions, certificates, remote ingress edges, and security events - **Domain-centric certificate overview** with backoff status and one-click reprovisioning +- **Remote ingress management** with connection token generation and one-click copy - **Read-only configuration display** — DcRouter is configured through code ## Installation @@ -219,6 +229,13 @@ const router = new DcRouter({ accounting: { enabled: true, retentionDays: 30 } }, + // Remote Ingress — edge nodes tunnel traffic to this hub + remoteIngressConfig: { + enabled: true, + tunnelPort: 8443, + hubDomain: 'hub.example.com', + }, + // Persistent storage storage: { fsPath: '/var/lib/dcrouter/data' }, @@ -246,6 +263,7 @@ graph TB TCP[TCP Clients] DNS[DNS Queries] RAD[RADIUS Clients] + EDGE[Edge Nodes] end subgraph "DcRouter Core" @@ -254,6 +272,7 @@ graph TB ES[smartmta Email Server
TypeScript + Rust] DS[SmartDNS Server
Rust-powered] RS[SmartRadius Server] + RI[RemoteIngress Hub
Rust data plane] CM[Certificate Manager
smartacme v9] OS[OpsServer Dashboard] MM[Metrics Manager] @@ -273,11 +292,13 @@ graph TB SMTP --> ES DNS --> DS RAD --> RS + EDGE --> RI DC --> SP DC --> ES DC --> DS DC --> RS + DC --> RI DC --> CM DC --> OS DC --> MM @@ -288,6 +309,7 @@ graph TB SP --> API ES --> MAIL ES --> DB + RI --> SP CM -.-> SP CM -.-> ES @@ -303,6 +325,7 @@ graph TB | **DNS Server** | `@push.rocks/smartdns` | Authoritative DNS with dynamic records and DKIM TXT auto-generation (Rust engine) | | **SmartAcme** | `@push.rocks/smartacme` | ACME certificate management with per-domain dedup, concurrency control, and rate limiting | | **RADIUS Server** | `@push.rocks/smartradius` | Network authentication with MAB, VLAN assignment, and accounting | +| **RemoteIngress** | `@serve.zone/remoteingress` | Distributed edge tunneling with Rust data plane and TS management | | **OpsServer** | `@api.global/typedserver` | Web dashboard + TypedRequest API for monitoring and management | | **MetricsManager** | `@push.rocks/smartmetrics` | Real-time metrics collection (CPU, memory, email, DNS, security) | | **StorageManager** | built-in | Pluggable key-value storage (filesystem, custom, or in-memory) | @@ -312,19 +335,20 @@ graph TB DcRouter acts purely as an **orchestrator** — it doesn't implement protocols itself. Instead, it wires together best-in-class packages for each protocol: -1. **On `start()`**: DcRouter initializes OpsServer (port 3000), then spins up SmartProxy, smartmta, SmartDNS, and SmartRadius based on which configs are provided. -2. **During operation**: Each service handles its own protocol independently. SmartProxy uses a Rust-powered engine for maximum throughput. smartmta uses a hybrid TypeScript + Rust architecture for reliable email delivery. SmartAcme v9 handles all certificate operations with built-in concurrency control and rate limiting. +1. **On `start()`**: DcRouter initializes OpsServer (port 3000), then spins up SmartProxy, smartmta, SmartDNS, SmartRadius, and RemoteIngress based on which configs are provided. +2. **During operation**: Each service handles its own protocol independently. SmartProxy uses a Rust-powered engine for maximum throughput. smartmta uses a hybrid TypeScript + Rust architecture for reliable email delivery. RemoteIngress runs a Rust data plane for edge tunnel networking. SmartAcme v9 handles all certificate operations with built-in concurrency control and rate limiting. 3. **On `stop()`**: All services are gracefully shut down in parallel, including cleanup of HTTP agents and DNS clients. ### Rust-Powered Architecture -DcRouter itself is a pure TypeScript orchestrator, but three of its core sub-components ship with **compiled Rust binaries** for performance-critical paths. At runtime each package detects the platform, unpacks the correct binary, and communicates with TypeScript over IPC/FFI — so you get the ergonomics of TypeScript with the throughput of native code. +DcRouter itself is a pure TypeScript orchestrator, but several of its core sub-components ship with **compiled Rust binaries** for performance-critical paths. At runtime each package detects the platform, unpacks the correct binary, and communicates with TypeScript over IPC/FFI — so you get the ergonomics of TypeScript with the throughput of native code. | Component | Rust Binary | What It Handles | |-----------|-------------|-----------------| | **SmartProxy** | `smartproxy-bin` | All TCP/TLS/HTTP proxy networking, NFTables integration, connection metrics | | **smartmta** | `mailer-bin` | SMTP server + client, DKIM/SPF/DMARC, content scanning, IP reputation | | **SmartDNS** | `smartdns-bin` | DNS server (UDP + DNS-over-HTTPS), DNSSEC, DNS client resolution | +| **RemoteIngress** | `remoteingress-bin` | Edge tunnel data plane, multiplexed streams, heartbeat management | | **SmartRadius** | — | Pure TypeScript (no Rust component) | ## Configuration Reference @@ -333,6 +357,10 @@ DcRouter itself is a pure TypeScript orchestrator, but three of its core sub-com ```typescript interface IDcRouterOptions { + // ── Base ─────────────────────────────────────────────────────── + /** Base directory for all dcrouter data. Defaults to ~/.serve.zone/dcrouter */ + baseDir?: string; + // ── Traffic Routing ──────────────────────────────────────────── /** SmartProxy config for HTTP/HTTPS and TCP/SNI routing */ smartProxyConfig?: ISmartProxyOptions; @@ -376,6 +404,18 @@ interface IDcRouterOptions { accounting?: { enabled: boolean; retentionDays?: number }; }; + // ── Remote Ingress ───────────────────────────────────────────── + /** Remote Ingress hub for edge tunnel connections */ + remoteIngressConfig?: { + enabled?: boolean; // default: false + tunnelPort?: number; // default: 8443 + hubDomain?: string; // External hostname for connection tokens + tls?: { + certPath?: string; + keyPath?: string; + }; + }; + // ── TLS & Certificates ──────────────────────────────────────── tls?: { contactEmail: string; @@ -701,6 +741,107 @@ RADIUS is fully manageable at runtime via the OpsServer API: - Session monitoring and forced disconnects - Accounting summaries and statistics +## Remote Ingress + +DcRouter can act as a **hub** for distributed edge nodes using [`@serve.zone/remoteingress`](https://code.foss.global/serve.zone/remoteingress). Edge nodes accept incoming traffic at remote locations and tunnel it back to the hub over a single multiplexed connection. This is ideal for scenarios where you need to accept traffic at multiple geographic locations but process it centrally. + +### Enabling Remote Ingress + +```typescript +const router = new DcRouter({ + remoteIngressConfig: { + enabled: true, + tunnelPort: 8443, + hubDomain: 'hub.example.com', // Embedded in connection tokens + }, + // Routes tagged with remoteIngress are auto-derived to edge listen ports + smartProxyConfig: { + routes: [ + { + name: 'web-via-edge', + match: { domains: ['app.example.com'], ports: [443] }, + action: { + type: 'forward', + targets: [{ host: '192.168.1.10', port: 8080 }], + tls: { mode: 'terminate', certificate: 'auto' } + }, + remoteIngress: { enabled: true } // Edges will listen on port 443 + } + ] + } +}); + +await router.start(); +``` + +### Edge Registration + +Edges are registered via the OpsServer API (or dashboard UI). Each edge gets a unique ID and secret: + +```typescript +// Via TypedRequest API +const createReq = new TypedRequest( + 'https://hub:3000/typedrequest', 'createRemoteIngress' +); +const { edge } = await createReq.fire({ + identity, + name: 'edge-nyc-01', + autoDerivePorts: true, + tags: ['us-east'], +}); +// edge.secret is returned only on creation — save it! +``` + +### Connection Tokens 🔑 + +Instead of configuring edges with four separate values (hubHost, hubPort, edgeId, secret), DcRouter can generate a single **connection token** — an opaque base64url string that encodes everything: + +```typescript +// Via TypedRequest API +const tokenReq = new TypedRequest( + 'https://hub:3000/typedrequest', 'getRemoteIngressConnectionToken' +); +const { token } = await tokenReq.fire({ identity, edgeId: 'edge-uuid' }); +// token = "eyJoIjoiaHViLmV4YW1wbGUuY29tIiwicCI6ODQ0MywiZSI6I..." + +// On the edge side, just pass the token: +const edge = new RemoteIngressEdge({ token }); +await edge.start(); +``` + +The token is generated using `remoteingress.encodeConnectionToken()` and contains `{ hubHost, hubPort, edgeId, secret }`. The `hubHost` comes from `remoteIngressConfig.hubDomain` (or can be overridden per-request). + +In the OpsServer dashboard, click **"Copy Token"** on any edge row to copy the connection token to your clipboard. + +### Auto-Derived Ports + +When routes have `remoteIngress: { enabled: true }`, edges with `autoDerivePorts: true` (default) automatically pick up those routes' ports. You can also use `edgeFilter` to restrict which edges get which ports: + +```typescript +{ + name: 'web-route', + match: { ports: [443] }, + action: { /* ... */ }, + remoteIngress: { + enabled: true, + edgeFilter: ['us-east', 'edge-uuid-123'] // Only edges with matching id or tags + } +} +``` + +### Dashboard Actions + +The OpsServer Remote Ingress view provides: + +| Action | Description | +|--------|-------------| +| **Create Edge Node** | Register a new edge with name, ports, tags | +| **Enable / Disable** | Toggle an edge on or off | +| **Edit** | Modify name, manual ports, auto-derive setting, tags | +| **Regenerate Secret** | Issue a new secret (invalidates the old one) | +| **Copy Token** | Generate and copy a base64url connection token to clipboard | +| **Delete** | Remove the edge registration | + ## Certificate Management DcRouter uses [`@push.rocks/smartacme`](https://code.foss.global/push.rocks/smartacme) v9 for ACME certificate provisioning. smartacme v9 brings significant improvements over previous versions: @@ -767,6 +908,7 @@ The OpsServer includes a **Certificates** view showing: - Expiry dates and issuer information - Backoff status for failed domains - One-click reprovisioning per domain +- Certificate import and export ## Storage & Caching @@ -788,7 +930,7 @@ storage: { // Simply omit the storage config ``` -Used for: TLS certificates, DKIM keys, email routes, bounce/suppression lists, IP reputation data, domain configs, cert backoff state. +Used for: TLS certificates, DKIM keys, email routes, bounce/suppression lists, IP reputation data, domain configs, cert backoff state, remote ingress edge registrations. ### Cache Database @@ -874,7 +1016,8 @@ The OpsServer provides a web-based management interface served on port 3000. It' | 📊 **Overview** | Real-time server stats, CPU/memory, connection counts, email throughput | | 🌐 **Network** | Active connections, top IPs, throughput rates, SmartProxy metrics | | 📧 **Email** | Queue monitoring (queued/sent/failed), bounce records, security incidents | -| 🔐 **Certificates** | Domain-centric certificate overview, status, backoff info, reprovisioning | +| 🔐 **Certificates** | Domain-centric certificate overview, status, backoff info, reprovisioning, import/export | +| 🌍 **RemoteIngress** | Edge node management, connection status, token generation, enable/disable | | 📜 **Logs** | Real-time log viewer with level filtering and search | | ⚙️ **Configuration** | Read-only view of current system configuration | | 🛡️ **Security** | IP reputation, rate limit status, blocked connections | @@ -906,6 +1049,18 @@ All management is done via TypedRequest over HTTP POST to `/typedrequest`: 'getCertificateOverview' // Domain-centric certificate status 'reprovisionCertificate' // Reprovision by route name (legacy) 'reprovisionCertificateDomain' // Reprovision by domain (preferred) +'importCertificate' // Import a certificate +'exportCertificate' // Export a certificate +'deleteCertificate' // Delete a certificate + +// Remote Ingress +'getRemoteIngresses' // List all edge registrations +'createRemoteIngress' // Register a new edge +'updateRemoteIngress' // Update edge settings +'deleteRemoteIngress' // Remove an edge +'regenerateRemoteIngressSecret' // Issue a new secret +'getRemoteIngressStatus' // Runtime status of all edges +'getRemoteIngressConnectionToken' // Generate a connection token for an edge // Configuration (read-only) 'getConfiguration' // Current system config @@ -957,6 +1112,8 @@ const router = new DcRouter(options: IDcRouterOptions); | `emailServer` | `UnifiedEmailServer` | Email server instance (from smartmta) | | `dnsServer` | `DnsServer` | DNS server instance | | `radiusServer` | `RadiusServer` | RADIUS server instance | +| `remoteIngressManager` | `RemoteIngressManager` | Edge registration CRUD manager | +| `tunnelManager` | `TunnelManager` | Tunnel lifecycle and status manager | | `storageManager` | `StorageManager` | Storage backend | | `opsServer` | `OpsServer` | OpsServer/dashboard instance | | `metricsManager` | `MetricsManager` | Metrics collector | @@ -1000,7 +1157,7 @@ import { data, requests } from '@serve.zone/dcrouter/interfaces'; DcRouter includes a comprehensive test suite covering all system components: ```bash -# Run all tests (10 files, 73 tests) +# Run all tests pnpm test # Run a specific test file diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 7e2b39e..61d67d1 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/dcrouter', - version: '6.11.0', + version: '6.12.0', description: 'A multifaceted routing service handling mail and SMS delivery functions.' } diff --git a/ts/readme.md b/ts/readme.md new file mode 100644 index 0000000..9f62c4b --- /dev/null +++ b/ts/readme.md @@ -0,0 +1,146 @@ +# @serve.zone/dcrouter + +The core DcRouter package — a unified datacenter gateway orchestrator. 🚀 + +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. + +## Issue Reporting and Security + +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. + +## Installation + +```bash +pnpm add @serve.zone/dcrouter +``` + +## Usage + +```typescript +import { DcRouter } from '@serve.zone/dcrouter'; + +const router = new DcRouter({ + smartProxyConfig: { + routes: [ + { + name: 'web-app', + match: { domains: ['example.com'], ports: [443] }, + action: { + type: 'forward', + targets: [{ host: '192.168.1.10', port: 8080 }], + tls: { mode: 'terminate', certificate: 'auto' } + } + } + ], + acme: { email: 'admin@example.com', enabled: true, useProduction: true } + } +}); + +await router.start(); +// OpsServer dashboard at http://localhost:3000 + +// Graceful shutdown +await router.stop(); +``` + +## Module Structure + +``` +ts/ +├── index.ts # Main exports (DcRouter, re-exported smartmta types) +├── classes.dcrouter.ts # DcRouter orchestrator class + IDcRouterOptions +├── classes.cert-provision-scheduler.ts # Per-domain cert backoff scheduler +├── classes.storage-cert-manager.ts # SmartAcme cert manager backed by StorageManager +├── logger.ts # Structured logging utility +├── paths.ts # Centralized data directory paths +├── plugins.ts # All dependency imports +├── cache/ # Cache database (smartdata + LocalTsmDb) +│ ├── classes.cachedb.ts # CacheDb singleton +│ ├── classes.cachecleaner.ts # TTL-based cleanup +│ └── documents/ # Cached document models +├── config/ # Configuration utilities +├── errors/ # Error classes and retry logic +├── monitoring/ # MetricsManager (SmartMetrics integration) +├── opsserver/ # OpsServer dashboard + API handlers +│ ├── classes.opsserver.ts # HTTP server + TypedRouter setup +│ └── handlers/ # TypedRequest handlers by domain +│ ├── admin.handler.ts # Auth (login/logout/verify) +│ ├── stats.handler.ts # Statistics + health +│ ├── config.handler.ts # Configuration (read-only) +│ ├── logs.handler.ts # Log retrieval +│ ├── email.handler.ts # Email operations +│ ├── certificate.handler.ts # Certificate management +│ ├── radius.handler.ts # RADIUS management +│ └── remoteingress.handler.ts # Remote ingress edge + token management +├── radius/ # RADIUS server integration +├── remoteingress/ # Remote ingress hub integration +│ ├── classes.remoteingress-manager.ts # Edge CRUD + port derivation +│ └── classes.tunnel-manager.ts # Rust hub lifecycle + status tracking +├── security/ # Security utilities +├── sms/ # SMS integration +└── storage/ # StorageManager (filesystem/custom/memory) +``` + +## Exports + +```typescript +// Main class +export { DcRouter, IDcRouterOptions } from './classes.dcrouter.js'; + +// Re-exported from smartmta +export { UnifiedEmailServer } from '@push.rocks/smartmta'; +export type { IUnifiedEmailServerOptions, IEmailRoute, IEmailDomainConfig } from '@push.rocks/smartmta'; + +// RADIUS +export { RadiusServer, IRadiusServerConfig } from './radius/index.js'; + +// Remote Ingress +export { RemoteIngressManager, TunnelManager } from './remoteingress/index.js'; +``` + +## Key Classes + +### `DcRouter` + +The central orchestrator. Accepts `IDcRouterOptions` and manages the lifecycle of all sub-services: + +| Config Section | Service Started | Package | +|----------------|----------------|---------| +| `smartProxyConfig` | SmartProxy (HTTP/HTTPS/TCP/SNI) | `@push.rocks/smartproxy` | +| `emailConfig` | UnifiedEmailServer (SMTP) | `@push.rocks/smartmta` | +| `dnsNsDomains` + `dnsScopes` | DnsServer (UDP + DoH) | `@push.rocks/smartdns` | +| `radiusConfig` | RadiusServer (auth + accounting) | `@push.rocks/smartradius` | +| `remoteIngressConfig` | RemoteIngressManager + TunnelManager | `@serve.zone/remoteingress` | +| `tls` + `dnsChallenge` | SmartAcme (ACME cert provisioning) | `@push.rocks/smartacme` | +| `cacheConfig` | CacheDb (embedded MongoDB) | `@push.rocks/smartdata` | +| *(always)* | OpsServer (dashboard + API) | `@api.global/typedserver` | +| *(always)* | MetricsManager | `@push.rocks/smartmetrics` | + +### `RemoteIngressManager` + +Manages CRUD for remote ingress edge registrations. Persists edges via StorageManager. Provides port derivation from routes tagged with `remoteIngress.enabled`. + +### `TunnelManager` + +Manages the Rust-based RemoteIngressHub lifecycle. Syncs allowed edges, tracks connection status, and exposes edge statuses (connected, publicIp, activeTunnels, lastHeartbeat). + +## License and Legal Information + +This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](../LICENSE) file. + +**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. + +### Trademarks + +This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein. + +Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar. + +### Company Information + +Task Venture Capital GmbH +Registered at District Court Bremen HRB 35230 HB, Germany + +For any legal inquiries or further information, please contact us via email at hello@task.vc. + +By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works. diff --git a/ts_interfaces/readme.md b/ts_interfaces/readme.md index b9b36c9..46c75b7 100644 --- a/ts_interfaces/readme.md +++ b/ts_interfaces/readme.md @@ -82,6 +82,14 @@ interface IIdentity { | `INetworkMetrics` | Bandwidth, connection counts, top endpoints | | `ILogEntry` | Timestamp, level, category, message, metadata | +#### Remote Ingress Interfaces +| Interface | Description | +|-----------|-------------| +| `IRemoteIngress` | Edge registration: id, name, secret, listenPorts, enabled, autoDerivePorts, tags | +| `IRemoteIngressStatus` | Runtime status: connected, publicIp, activeTunnels, lastHeartbeat | +| `IRouteRemoteIngress` | Route-level config: enabled flag and optional edgeFilter | +| `IDcRouterRouteConfig` | Extended SmartProxy route config with optional `remoteIngress` property | + ### Request Interfaces (`requests`) TypedRequest interfaces for the OpsServer API, organized by domain: @@ -134,6 +142,9 @@ TypedRequest interfaces for the OpsServer API, organized by domain: | `IReq_GetCertificateOverview` | `getCertificateOverview` | Domain-centric certificate status | | `IReq_ReprovisionCertificate` | `reprovisionCertificate` | Reprovision by route name (legacy) | | `IReq_ReprovisionCertificateDomain` | `reprovisionCertificateDomain` | Reprovision by domain (preferred) | +| `IReq_ImportCertificate` | `importCertificate` | Import a certificate | +| `IReq_ExportCertificate` | `exportCertificate` | Export a certificate | +| `IReq_DeleteCertificate` | `deleteCertificate` | Delete a certificate | #### Certificate Types ```typescript @@ -159,6 +170,17 @@ interface ICertificateInfo { } ``` +#### 🌍 Remote Ingress +| Interface | Method | Description | +|-----------|--------|-------------| +| `IReq_CreateRemoteIngress` | `createRemoteIngress` | Register a new edge node | +| `IReq_DeleteRemoteIngress` | `deleteRemoteIngress` | Remove an edge registration | +| `IReq_UpdateRemoteIngress` | `updateRemoteIngress` | Update edge settings | +| `IReq_RegenerateRemoteIngressSecret` | `regenerateRemoteIngressSecret` | Issue a new secret | +| `IReq_GetRemoteIngresses` | `getRemoteIngresses` | List all edge registrations | +| `IReq_GetRemoteIngressStatus` | `getRemoteIngressStatus` | Runtime status of all edges | +| `IReq_GetRemoteIngressConnectionToken` | `getRemoteIngressConnectionToken` | Generate a connection token | + #### 📡 RADIUS | Interface | Method | Description | |-----------|--------|-------------| @@ -183,7 +205,7 @@ import { data, requests } from '@serve.zone/dcrouter-interfaces'; // 1. Login const loginClient = new typedrequest.TypedRequest( 'https://your-dcrouter:3000/typedrequest', - 'adminLogin' + 'adminLoginWithUsernameAndPassword' ); const loginResponse = await loginClient.fire({ @@ -199,10 +221,8 @@ const metricsClient = new typedrequest.TypedRequest( @@ -213,14 +233,23 @@ const certClient = new typedrequest.TypedRequest( +// 4. List remote ingress edges +const edgesClient = new typedrequest.TypedRequest( 'https://your-dcrouter:3000/typedrequest', - 'getQueuedEmails' + 'getRemoteIngresses' ); -const queued = await queueClient.fire({ identity }); -console.log('Queued emails:', queued.emails.length); +const edges = await edgesClient.fire({ identity }); +console.log('Registered edges:', edges.edges.length); + +// 5. Generate a connection token for an edge +const tokenClient = new typedrequest.TypedRequest( + 'https://your-dcrouter:3000/typedrequest', + 'getRemoteIngressConnectionToken' +); + +const tokenResponse = await tokenClient.fire({ identity, edgeId: edges.edges[0].id }); +console.log('Connection token:', tokenResponse.token); ``` ## License and Legal Information diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 7e2b39e..61d67d1 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/dcrouter', - version: '6.11.0', + version: '6.12.0', description: 'A multifaceted routing service handling mail and SMS delivery functions.' } diff --git a/ts_web/appstate.ts b/ts_web/appstate.ts index 115c25b..60ff2e2 100644 --- a/ts_web/appstate.ts +++ b/ts_web/appstate.ts @@ -200,7 +200,7 @@ export interface IRemoteIngressState { edges: interfaces.data.IRemoteIngress[]; statuses: interfaces.data.IRemoteIngressStatus[]; selectedEdgeId: string | null; - newEdgeSecret: string | null; + newEdgeId: string | null; isLoading: boolean; error: string | null; lastUpdated: number; @@ -212,7 +212,7 @@ export const remoteIngressStatePart = await appState.getStatePart { return { ...statePartArg.getState(), - newEdgeSecret: null, + newEdgeId: null, }; } ); diff --git a/ts_web/elements/ops-view-certificates.ts b/ts_web/elements/ops-view-certificates.ts index 2b67abf..b76d6fe 100644 --- a/ts_web/elements/ops-view-certificates.ts +++ b/ts_web/elements/ops-view-certificates.ts @@ -382,7 +382,7 @@ export class OpsViewCertificates extends DeesElement { }, { name: 'View Details', - iconName: 'lucide:Search', + iconName: 'fa:magnifyingGlass', type: ['doubleClick', 'contextmenu'], actionFunc: async (actionData: { item: interfaces.requests.ICertificateInfo }) => { const cert = actionData.item; diff --git a/ts_web/elements/ops-view-network.ts b/ts_web/elements/ops-view-network.ts index 59fdb19..28884b6 100644 --- a/ts_web/elements/ops-view-network.ts +++ b/ts_web/elements/ops-view-network.ts @@ -287,7 +287,7 @@ export class OpsViewNetwork extends DeesElement { .dataActions=${[ { name: 'View Details', - iconName: 'lucide:Search', + iconName: 'fa:magnifyingGlass', type: ['inRow', 'doubleClick', 'contextmenu'], actionFunc: async (actionData) => { await this.showRequestDetails(actionData.item); @@ -435,7 +435,7 @@ export class OpsViewNetwork extends DeesElement { actions: [ { name: 'View Details', - iconName: 'lucide:Search', + iconName: 'fa:magnifyingGlass', action: async () => { }, }, diff --git a/ts_web/elements/ops-view-remoteingress.ts b/ts_web/elements/ops-view-remoteingress.ts index ad3288e..95acce2 100644 --- a/ts_web/elements/ops-view-remoteingress.ts +++ b/ts_web/elements/ops-view-remoteingress.ts @@ -176,13 +176,39 @@ export class OpsViewRemoteIngress extends DeesElement { return html` Remote Ingress - ${this.riState.newEdgeSecret ? html` + ${this.riState.newEdgeId ? html`
- Edge Secret (copy now - shown only once): - ${this.riState.newEdgeSecret} -
This secret will not be shown again. Save it securely.
+ Edge created successfully! +
Copy the connection token now. Use it with edge.start({ token: '...' }).
appstate.remoteIngressStatePart.dispatchAction(appstate.clearNewEdgeSecretAction, null)} + @click=${async () => { + const { DeesToast } = await import('@design.estate/dees-catalog'); + try { + const response = await appstate.fetchConnectionToken(this.riState.newEdgeId); + if (response.success && response.token) { + if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') { + await navigator.clipboard.writeText(response.token); + } else { + const textarea = document.createElement('textarea'); + textarea.value = response.token; + textarea.style.position = 'fixed'; + textarea.style.opacity = '0'; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand('copy'); + document.body.removeChild(textarea); + } + DeesToast.show({ message: 'Connection token copied!', type: 'success', duration: 3000 }); + } else { + DeesToast.show({ message: response.message || 'Failed to get token', type: 'error', duration: 4000 }); + } + } catch (err) { + DeesToast.show({ message: `Failed: ${err.message}`, type: 'error', duration: 4000 }); + } + }} + >Copy Connection Token + appstate.remoteIngressStatePart.dispatchAction(appstate.clearNewEdgeIdAction, null)} >Dismiss
` : ''} @@ -348,7 +374,7 @@ export class OpsViewRemoteIngress extends DeesElement { }, { name: 'Copy Token', - iconName: 'lucide:clipboard-copy', + iconName: 'lucide:ClipboardCopy', type: ['inRow', 'contextmenu'] as any, actionFunc: async (actionData: any) => { const edge = actionData.item as interfaces.data.IRemoteIngress; @@ -356,7 +382,19 @@ export class OpsViewRemoteIngress extends DeesElement { try { const response = await appstate.fetchConnectionToken(edge.id); if (response.success && response.token) { - await navigator.clipboard.writeText(response.token); + // Use clipboard API with fallback for non-HTTPS contexts + if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') { + await navigator.clipboard.writeText(response.token); + } else { + const textarea = document.createElement('textarea'); + textarea.value = response.token; + textarea.style.position = 'fixed'; + textarea.style.opacity = '0'; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand('copy'); + document.body.removeChild(textarea); + } DeesToast.show({ message: `Connection token copied for ${edge.name}`, type: 'success', duration: 3000 }); } else { DeesToast.show({ message: response.message || 'Failed to get token', type: 'error', duration: 4000 }); diff --git a/ts_web/readme.md b/ts_web/readme.md index 6efeaa7..5468740 100644 --- a/ts_web/readme.md +++ b/ts_web/readme.md @@ -40,6 +40,15 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community - Expiry date monitoring and alerts - Per-domain backoff status for failed provisions - One-click reprovisioning per domain +- Certificate import, export, and deletion + +### 🌍 Remote Ingress Management +- Edge node registration with name, ports, and tags +- Real-time connection status (connected/disconnected/disabled) +- Public IP and active tunnel count per edge +- Auto-derived port display with manual/derived breakdown +- **Connection token generation** — one-click "Copy Token" for easy edge provisioning +- Enable/disable, edit, secret regeneration, and delete actions ### 📜 Log Viewer - Real-time log streaming @@ -85,6 +94,7 @@ ts_web/ ├── ops-view-network.ts # Network monitoring ├── ops-view-emails.ts # Email queue management ├── ops-view-certificates.ts # Certificate overview & reprovisioning + ├── ops-view-remoteingress.ts # Remote ingress edge management ├── ops-view-logs.ts # Log viewer ├── ops-view-config.ts # Configuration display ├── ops-view-security.ts # Security dashboard @@ -106,6 +116,8 @@ The app uses `@push.rocks/smartstate` with multiple state parts: | `logStatePart` | Soft | Recent logs, streaming status, filters | | `networkStatePart` | Soft | Connections, IPs, throughput rates | | `emailOpsStatePart` | Soft | Email queues, bounces, suppression list | +| `certificateStatePart` | Soft | Certificate list, summary, loading state | +| `remoteIngressStatePart` | Soft | Edge list, statuses, new edge secret | ### Actions @@ -128,6 +140,23 @@ fetchSecurityIncidentsAction() // Security events fetchBounceRecordsAction() // Bounce records resendEmailAction(emailId) // Re-queue failed email removeFromSuppressionAction(email) // Remove from suppression list + +// Certificates +fetchCertificateOverviewAction() // All certificates with summary +reprovisionCertificateAction(domain) // Reprovision a certificate +deleteCertificateAction(domain) // Delete a certificate +importCertificateAction(cert) // Import a certificate +fetchCertificateExport(domain) // Export (standalone function) + +// Remote Ingress +fetchRemoteIngressAction() // Edges + statuses +createRemoteIngressAction(data) // Create new edge +updateRemoteIngressAction(data) // Update edge settings +deleteRemoteIngressAction(id) // Remove edge +regenerateRemoteIngressSecretAction(id) // New secret +toggleRemoteIngressAction(id, enabled) // Enable/disable +clearNewEdgeSecretAction() // Dismiss secret banner +fetchConnectionToken(edgeId) // Get connection token (standalone function) ``` ### Client-Side Routing @@ -141,6 +170,7 @@ removeFromSuppressionAction(email) // Remove from suppression list /emails/failed → Failed emails /emails/security → Security incidents /certificates → Certificate management +/remoteingress → Remote ingress edge management /logs → Log viewer /configuration → System configuration /security → Security dashboard