feat(docs,ops-dashboard): document unified database and reusable security profile and network target management
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-04-02 - 12.3.0 - feat(docs,ops-dashboard)
|
||||||
|
document unified database and reusable security profile and network target management
|
||||||
|
|
||||||
|
- Update project and interface documentation to replace separate storage/cache configuration with a unified database model
|
||||||
|
- Document new security profile and network target APIs, data models, and dashboard capabilities
|
||||||
|
- Add a global dashboard warning when the database is disabled so unavailable management features are clearly indicated
|
||||||
|
- Bump @design.estate/dees-catalog and @serve.zone/catalog to support the updated dashboard experience
|
||||||
|
|
||||||
## 2026-04-02 - 12.2.6 - fix(ops-ui)
|
## 2026-04-02 - 12.2.6 - fix(ops-ui)
|
||||||
improve operations table actions and modal form handling for profiles and network targets
|
improve operations table actions and modal form handling for profiles and network targets
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
"@api.global/typedserver": "^8.4.6",
|
"@api.global/typedserver": "^8.4.6",
|
||||||
"@api.global/typedsocket": "^4.1.2",
|
"@api.global/typedsocket": "^4.1.2",
|
||||||
"@apiclient.xyz/cloudflare": "^7.1.0",
|
"@apiclient.xyz/cloudflare": "^7.1.0",
|
||||||
"@design.estate/dees-catalog": "^3.49.2",
|
"@design.estate/dees-catalog": "^3.50.2",
|
||||||
"@design.estate/dees-element": "^2.2.4",
|
"@design.estate/dees-element": "^2.2.4",
|
||||||
"@push.rocks/lik": "^6.4.0",
|
"@push.rocks/lik": "^6.4.0",
|
||||||
"@push.rocks/projectinfo": "^5.1.0",
|
"@push.rocks/projectinfo": "^5.1.0",
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
"@push.rocks/smartunique": "^3.0.9",
|
"@push.rocks/smartunique": "^3.0.9",
|
||||||
"@push.rocks/smartvpn": "1.19.1",
|
"@push.rocks/smartvpn": "1.19.1",
|
||||||
"@push.rocks/taskbuffer": "^8.0.2",
|
"@push.rocks/taskbuffer": "^8.0.2",
|
||||||
"@serve.zone/catalog": "^2.9.1",
|
"@serve.zone/catalog": "^2.10.0",
|
||||||
"@serve.zone/interfaces": "^5.3.0",
|
"@serve.zone/interfaces": "^5.3.0",
|
||||||
"@serve.zone/remoteingress": "^4.15.3",
|
"@serve.zone/remoteingress": "^4.15.3",
|
||||||
"@tsclass/tsclass": "^9.5.0",
|
"@tsclass/tsclass": "^9.5.0",
|
||||||
|
|||||||
28
pnpm-lock.yaml
generated
28
pnpm-lock.yaml
generated
@@ -24,8 +24,8 @@ importers:
|
|||||||
specifier: ^7.1.0
|
specifier: ^7.1.0
|
||||||
version: 7.1.0
|
version: 7.1.0
|
||||||
'@design.estate/dees-catalog':
|
'@design.estate/dees-catalog':
|
||||||
specifier: ^3.49.2
|
specifier: ^3.50.2
|
||||||
version: 3.49.2(@tiptap/pm@2.27.2)
|
version: 3.50.2(@tiptap/pm@2.27.2)
|
||||||
'@design.estate/dees-element':
|
'@design.estate/dees-element':
|
||||||
specifier: ^2.2.4
|
specifier: ^2.2.4
|
||||||
version: 2.2.4
|
version: 2.2.4
|
||||||
@@ -102,8 +102,8 @@ importers:
|
|||||||
specifier: ^8.0.2
|
specifier: ^8.0.2
|
||||||
version: 8.0.2
|
version: 8.0.2
|
||||||
'@serve.zone/catalog':
|
'@serve.zone/catalog':
|
||||||
specifier: ^2.9.1
|
specifier: ^2.10.0
|
||||||
version: 2.9.1(@tiptap/pm@2.27.2)
|
version: 2.10.0(@tiptap/pm@2.27.2)
|
||||||
'@serve.zone/interfaces':
|
'@serve.zone/interfaces':
|
||||||
specifier: ^5.3.0
|
specifier: ^5.3.0
|
||||||
version: 5.3.0
|
version: 5.3.0
|
||||||
@@ -350,8 +350,8 @@ packages:
|
|||||||
'@configvault.io/interfaces@1.0.17':
|
'@configvault.io/interfaces@1.0.17':
|
||||||
resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==}
|
resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==}
|
||||||
|
|
||||||
'@design.estate/dees-catalog@3.49.2':
|
'@design.estate/dees-catalog@3.50.2':
|
||||||
resolution: {integrity: sha512-ChVf5IW/w1WSsfuI3BA1SX2QJFjZljnAvnyPDXnbzTXuOdTgs054p66JwlDca9KM8yBlndwibgAYJfD6/4sONw==}
|
resolution: {integrity: sha512-oxB1kB3IxEwHgf+DjytTBilkDVVb8hryq465OhhzgBiJiHaNLPyBASAQaNTVp6eaORQGzyCmy/ac/GdQglZiIg==}
|
||||||
|
|
||||||
'@design.estate/dees-comms@1.0.30':
|
'@design.estate/dees-comms@1.0.30':
|
||||||
resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==}
|
resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==}
|
||||||
@@ -1583,8 +1583,8 @@ packages:
|
|||||||
'@selderee/plugin-htmlparser2@0.11.0':
|
'@selderee/plugin-htmlparser2@0.11.0':
|
||||||
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
|
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
|
||||||
|
|
||||||
'@serve.zone/catalog@2.9.1':
|
'@serve.zone/catalog@2.10.0':
|
||||||
resolution: {integrity: sha512-W+4x5O834DiEtcqfVNFrP6qYlj/6c9UTR9oEl2Wthf0R2SN0zC6Hbs16US2kP+mmQBKAIDMQYvTUI9oaXqvcog==}
|
resolution: {integrity: sha512-/y3gDrf3UHXaDhLJtqJTeHSXOCKGQ4ou6Dd80tMxQYm8/I/OJmifkgerLKP05WdbMyj0pLp33QhjLElJrpME8Q==}
|
||||||
|
|
||||||
'@serve.zone/interfaces@5.3.0':
|
'@serve.zone/interfaces@5.3.0':
|
||||||
resolution: {integrity: sha512-venO7wtDR9ixzD9NhdERBGjNKbFA5LL0yHw4eqGh0UpmvtXVc3SFG0uuHDilOKMZqZ8bttV88qVsFy1aSTJrtA==}
|
resolution: {integrity: sha512-venO7wtDR9ixzD9NhdERBGjNKbFA5LL0yHw4eqGh0UpmvtXVc3SFG0uuHDilOKMZqZ8bttV88qVsFy1aSTJrtA==}
|
||||||
@@ -4260,13 +4260,11 @@ packages:
|
|||||||
|
|
||||||
xterm-addon-fit@0.8.0:
|
xterm-addon-fit@0.8.0:
|
||||||
resolution: {integrity: sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==}
|
resolution: {integrity: sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==}
|
||||||
deprecated: This package is now deprecated. Move to @xterm/addon-fit instead.
|
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
xterm: ^5.0.0
|
xterm: ^5.0.0
|
||||||
|
|
||||||
xterm@5.3.0:
|
xterm@5.3.0:
|
||||||
resolution: {integrity: sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg==}
|
resolution: {integrity: sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg==}
|
||||||
deprecated: This package is now deprecated. Move to @xterm/xterm instead.
|
|
||||||
|
|
||||||
y18n@4.0.3:
|
y18n@4.0.3:
|
||||||
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||||
@@ -4341,7 +4339,7 @@ snapshots:
|
|||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@api.global/typedsocket': 4.1.2(@push.rocks/smartserve@2.0.3)
|
'@api.global/typedsocket': 4.1.2(@push.rocks/smartserve@2.0.3)
|
||||||
'@cloudflare/workers-types': 4.20260317.1
|
'@cloudflare/workers-types': 4.20260317.1
|
||||||
'@design.estate/dees-catalog': 3.49.2(@tiptap/pm@2.27.2)
|
'@design.estate/dees-catalog': 3.50.2(@tiptap/pm@2.27.2)
|
||||||
'@design.estate/dees-comms': 1.0.30
|
'@design.estate/dees-comms': 1.0.30
|
||||||
'@push.rocks/lik': 6.4.0
|
'@push.rocks/lik': 6.4.0
|
||||||
'@push.rocks/smartdelay': 3.0.5
|
'@push.rocks/smartdelay': 3.0.5
|
||||||
@@ -4870,7 +4868,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
|
|
||||||
'@design.estate/dees-catalog@3.49.2(@tiptap/pm@2.27.2)':
|
'@design.estate/dees-catalog@3.50.2(@tiptap/pm@2.27.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@design.estate/dees-domtools': 2.5.4
|
'@design.estate/dees-domtools': 2.5.4
|
||||||
'@design.estate/dees-element': 2.2.4
|
'@design.estate/dees-element': 2.2.4
|
||||||
@@ -4978,7 +4976,7 @@ snapshots:
|
|||||||
|
|
||||||
'@design.estate/dees-wcctools@3.8.0':
|
'@design.estate/dees-wcctools@3.8.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@design.estate/dees-domtools': 2.5.3
|
'@design.estate/dees-domtools': 2.5.4
|
||||||
'@design.estate/dees-element': 2.2.4
|
'@design.estate/dees-element': 2.2.4
|
||||||
'@push.rocks/smartdelay': 3.0.5
|
'@push.rocks/smartdelay': 3.0.5
|
||||||
lit: 3.3.2
|
lit: 3.3.2
|
||||||
@@ -6906,9 +6904,9 @@ snapshots:
|
|||||||
domhandler: 5.0.3
|
domhandler: 5.0.3
|
||||||
selderee: 0.11.0
|
selderee: 0.11.0
|
||||||
|
|
||||||
'@serve.zone/catalog@2.9.1(@tiptap/pm@2.27.2)':
|
'@serve.zone/catalog@2.10.0(@tiptap/pm@2.27.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@design.estate/dees-catalog': 3.49.2(@tiptap/pm@2.27.2)
|
'@design.estate/dees-catalog': 3.50.2(@tiptap/pm@2.27.2)
|
||||||
'@design.estate/dees-domtools': 2.5.4
|
'@design.estate/dees-domtools': 2.5.4
|
||||||
'@design.estate/dees-element': 2.2.4
|
'@design.estate/dees-element': 2.2.4
|
||||||
'@design.estate/dees-wcctools': 3.8.0
|
'@design.estate/dees-wcctools': 3.8.0
|
||||||
|
|||||||
140
readme.md
140
readme.md
@@ -93,10 +93,11 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|||||||
- **Socket-handler mode** — direct socket passing eliminates internal port hops
|
- **Socket-handler mode** — direct socket passing eliminates internal port hops
|
||||||
- **Real-time metrics** via SmartMetrics (CPU, memory, connections, throughput)
|
- **Real-time metrics** via SmartMetrics (CPU, memory, connections, throughput)
|
||||||
|
|
||||||
### 💾 Persistent Storage & Caching
|
### 💾 Unified Database
|
||||||
- **Multiple storage backends**: filesystem, custom functions, or in-memory
|
- **Two deployment modes**: embedded LocalSmartDb (zero-config) or external MongoDB
|
||||||
- **Embedded cache database** via smartdata + smartdb (MongoDB-compatible)
|
- **15 document classes** covering routes, certs, VPN, RADIUS, security profiles, network targets, and caches
|
||||||
- **Automatic TTL-based cleanup** for cached emails and IP reputation data
|
- **Automatic TTL-based cleanup** for cached emails and IP reputation data
|
||||||
|
- **Reusable references** — security profiles and network targets that propagate changes to all referencing routes
|
||||||
|
|
||||||
### 🖥️ OpsServer Dashboard
|
### 🖥️ OpsServer Dashboard
|
||||||
- **Web-based management interface** with real-time monitoring
|
- **Web-based management interface** with real-time monitoring
|
||||||
@@ -104,7 +105,9 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|||||||
- **Live views** for connections, email queues, DNS queries, RADIUS sessions, certificates, remote ingress edges, VPN clients, and security events
|
- **Live views** for connections, email queues, DNS queries, RADIUS sessions, certificates, remote ingress edges, VPN clients, and security events
|
||||||
- **Domain-centric certificate overview** with backoff status and one-click reprovisioning
|
- **Domain-centric certificate overview** with backoff status and one-click reprovisioning
|
||||||
- **Remote ingress management** with connection token generation and one-click copy
|
- **Remote ingress management** with connection token generation and one-click copy
|
||||||
- **Read-only configuration display** — DcRouter is configured through code
|
- **Security profiles & network targets** — reusable security configurations and host:port targets with propagation to referencing routes
|
||||||
|
- **Global warning banners** when database is disabled (management features unavailable)
|
||||||
|
- **Read-only configuration display** for system overview
|
||||||
- **Smart tab visibility handling** — auto-pauses all polling, WebSocket connections, and chart updates when the browser tab is hidden, preventing resource waste and tab freezing
|
- **Smart tab visibility handling** — auto-pauses all polling, WebSocket connections, and chart updates when the browser tab is hidden, preventing resource waste and tab freezing
|
||||||
|
|
||||||
### 🔧 Programmatic API Client
|
### 🔧 Programmatic API Client
|
||||||
@@ -269,11 +272,8 @@ const router = new DcRouter({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
// Persistent storage
|
// Unified database (embedded LocalSmartDb or external MongoDB)
|
||||||
storage: { fsPath: '/var/lib/dcrouter/data' },
|
dbConfig: { enabled: true },
|
||||||
|
|
||||||
// Cache database
|
|
||||||
cacheConfig: { enabled: true, storagePath: '~/.serve.zone/dcrouter/tsmdb' },
|
|
||||||
|
|
||||||
// TLS & ACME
|
// TLS & ACME
|
||||||
tls: { contactEmail: 'admin@example.com' },
|
tls: { contactEmail: 'admin@example.com' },
|
||||||
@@ -311,8 +311,7 @@ graph TB
|
|||||||
CM[Certificate Manager<br/><i>smartacme v9</i>]
|
CM[Certificate Manager<br/><i>smartacme v9</i>]
|
||||||
OS[OpsServer Dashboard]
|
OS[OpsServer Dashboard]
|
||||||
MM[Metrics Manager]
|
MM[Metrics Manager]
|
||||||
SM[Storage Manager]
|
DB2[DcRouterDb<br/><i>smartdata + smartdb</i>]
|
||||||
CD[Cache Database]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "Backend Services"
|
subgraph "Backend Services"
|
||||||
@@ -339,8 +338,7 @@ graph TB
|
|||||||
DC --> CM
|
DC --> CM
|
||||||
DC --> OS
|
DC --> OS
|
||||||
DC --> MM
|
DC --> MM
|
||||||
DC --> SM
|
DC --> DB2
|
||||||
DC --> CD
|
|
||||||
|
|
||||||
SP --> WEB
|
SP --> WEB
|
||||||
SP --> API
|
SP --> API
|
||||||
@@ -365,8 +363,7 @@ graph TB
|
|||||||
| **RemoteIngress** | `@serve.zone/remoteingress` | Distributed edge tunneling with Rust data plane and TS management |
|
| **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 |
|
| **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) |
|
| **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) |
|
| **DcRouterDb** | `@push.rocks/smartdata` + `@push.rocks/smartdb` | Unified database — embedded LocalSmartDb or external MongoDB for all persistence |
|
||||||
| **CacheDb** | `@push.rocks/smartdb` | Embedded MongoDB-compatible database (LocalSmartDb) for persistent caching |
|
|
||||||
|
|
||||||
### How It Works
|
### How It Works
|
||||||
|
|
||||||
@@ -509,24 +506,16 @@ interface IDcRouterOptions {
|
|||||||
};
|
};
|
||||||
dnsChallenge?: { cloudflareApiKey?: string };
|
dnsChallenge?: { cloudflareApiKey?: string };
|
||||||
|
|
||||||
// ── Storage & Caching ─────────────────────────────────────────
|
// ── Database ────────────────────────────────────────────────────
|
||||||
storage?: {
|
/** Unified database for all persistence (routes, certs, VPN, RADIUS, etc.) */
|
||||||
fsPath?: string;
|
dbConfig?: {
|
||||||
readFunction?: (key: string) => Promise<string>;
|
|
||||||
writeFunction?: (key: string, value: string) => Promise<void>;
|
|
||||||
};
|
|
||||||
cacheConfig?: {
|
|
||||||
enabled?: boolean; // default: true
|
enabled?: boolean; // default: true
|
||||||
|
mongoDbUrl?: string; // External MongoDB URL (omit for embedded LocalSmartDb)
|
||||||
storagePath?: string; // default: '~/.serve.zone/dcrouter/tsmdb'
|
storagePath?: string; // default: '~/.serve.zone/dcrouter/tsmdb'
|
||||||
dbName?: string; // default: 'dcrouter'
|
dbName?: string; // default: 'dcrouter'
|
||||||
cleanupIntervalHours?: number; // default: 1
|
cleanupIntervalHours?: number; // default: 1
|
||||||
ttlConfig?: {
|
seedOnEmpty?: boolean; // Seed default profiles/targets if DB is empty
|
||||||
emails?: number; // default: 30 days
|
seedData?: object; // Custom seed data
|
||||||
ipReputation?: number; // default: 1 day
|
|
||||||
bounces?: number; // default: 30 days
|
|
||||||
dkimKeys?: number; // default: 90 days
|
|
||||||
suppression?: number; // default: 30 days
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -1213,49 +1202,55 @@ The OpsServer includes a **Certificates** view showing:
|
|||||||
- One-click reprovisioning per domain
|
- One-click reprovisioning per domain
|
||||||
- Certificate import and export
|
- Certificate import and export
|
||||||
|
|
||||||
## Storage & Caching
|
## Storage & Database
|
||||||
|
|
||||||
### StorageManager
|
DcRouter uses a **unified database** (`DcRouterDb`) powered by [`@push.rocks/smartdata`](https://code.foss.global/push.rocks/smartdata) + [`@push.rocks/smartdb`](https://code.foss.global/push.rocks/smartdb) for all persistence. It supports two modes:
|
||||||
|
|
||||||
Provides a unified key-value interface with three backends:
|
### Embedded LocalSmartDb (Default)
|
||||||
|
|
||||||
|
Zero-config, file-based MongoDB-compatible database — no external services needed:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// Filesystem backend
|
dbConfig: { enabled: true }
|
||||||
storage: { fsPath: '/var/lib/dcrouter/data' }
|
// Data stored at ~/.serve.zone/dcrouter/tsmdb by default
|
||||||
|
|
||||||
// Custom backend (Redis, S3, etc.)
|
|
||||||
storage: {
|
|
||||||
readFunction: async (key) => await redis.get(key),
|
|
||||||
writeFunction: async (key, value) => await redis.set(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// In-memory (development only — data lost on restart)
|
|
||||||
// Simply omit the storage config
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Used for: TLS certificates, DKIM keys, email routes, bounce/suppression lists, IP reputation data, domain configs, cert backoff state, remote ingress edge registrations.
|
### External MongoDB
|
||||||
|
|
||||||
### Cache Database
|
Connect to an existing MongoDB instance:
|
||||||
|
|
||||||
An embedded MongoDB-compatible database (via smartdata + smartdb) for persistent caching with automatic TTL cleanup:
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
cacheConfig: {
|
dbConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
storagePath: '~/.serve.zone/dcrouter/tsmdb',
|
mongoDbUrl: 'mongodb://localhost:27017',
|
||||||
dbName: 'dcrouter',
|
dbName: 'dcrouter',
|
||||||
cleanupIntervalHours: 1,
|
|
||||||
ttlConfig: {
|
|
||||||
emails: 30, // days
|
|
||||||
ipReputation: 1, // days
|
|
||||||
bounces: 30, // days
|
|
||||||
dkimKeys: 90, // days
|
|
||||||
suppression: 30 // days
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Cached document types: `CachedEmail`, `CachedIPReputation`.
|
### Disabling the Database
|
||||||
|
|
||||||
|
For static, constructor-only deployments where no runtime management is needed:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
dbConfig: { enabled: false }
|
||||||
|
// Routes come exclusively from constructor config — no CRUD, no persistence
|
||||||
|
// OpsServer still runs but management features are disabled
|
||||||
|
```
|
||||||
|
|
||||||
|
### What's Stored
|
||||||
|
|
||||||
|
DcRouterDb persists all runtime state across 15 document classes:
|
||||||
|
|
||||||
|
| Category | Documents | Purpose |
|
||||||
|
|----------|-----------|---------|
|
||||||
|
| **Routes** | `StoredRouteDoc`, `RouteOverrideDoc` | Programmatic routes and hardcoded route overrides |
|
||||||
|
| **Certificates** | `ProxyCertDoc`, `AcmeCertDoc`, `CertBackoffDoc` | TLS certs, ACME state, per-domain backoff |
|
||||||
|
| **Auth** | `ApiTokenDoc` | API token storage |
|
||||||
|
| **Remote Ingress** | `RemoteIngressEdgeDoc` | Edge node registrations |
|
||||||
|
| **VPN** | `VpnServerKeysDoc`, `VpnClientDoc` | Server keys and client registrations |
|
||||||
|
| **RADIUS** | `VlanMappingsDoc`, `AccountingSessionDoc` | VLAN mappings and accounting sessions |
|
||||||
|
| **References** | `SecurityProfileDoc`, `NetworkTargetDoc` | Reusable security profiles and network targets |
|
||||||
|
| **Cache** | `CachedEmailDoc`, `CachedIpReputationDoc` | TTL-based caches with automatic cleanup |
|
||||||
|
|
||||||
## Security Features
|
## Security Features
|
||||||
|
|
||||||
@@ -1324,6 +1319,8 @@ The OpsServer provides a web-based management interface served on port 3000 by d
|
|||||||
| 🔐 **Certificates** | Domain-centric certificate overview, status, backoff info, reprovisioning, import/export |
|
| 🔐 **Certificates** | Domain-centric certificate overview, status, backoff info, reprovisioning, import/export |
|
||||||
| 🌍 **RemoteIngress** | Edge node management, connection status, token generation, enable/disable |
|
| 🌍 **RemoteIngress** | Edge node management, connection status, token generation, enable/disable |
|
||||||
| 🔐 **VPN** | VPN client management, server status, create/toggle/export/rotate/delete clients |
|
| 🔐 **VPN** | VPN client management, server status, create/toggle/export/rotate/delete clients |
|
||||||
|
| 🛡️ **Security Profiles** | Reusable security configurations (IP allow/block lists, rate limits) |
|
||||||
|
| 🎯 **Network Targets** | Reusable host:port destinations for route references |
|
||||||
| 📡 **RADIUS** | NAS client management, VLAN mappings, session monitoring, accounting |
|
| 📡 **RADIUS** | NAS client management, VLAN mappings, session monitoring, accounting |
|
||||||
| 📜 **Logs** | Real-time log viewer with level filtering and search |
|
| 📜 **Logs** | Real-time log viewer with level filtering and search |
|
||||||
| ⚙️ **Configuration** | Read-only view of current system configuration |
|
| ⚙️ **Configuration** | Read-only view of current system configuration |
|
||||||
@@ -1410,6 +1407,22 @@ All management is done via TypedRequest over HTTP POST to `/typedrequest`:
|
|||||||
'setVlanMapping' // Add/update VLAN mapping
|
'setVlanMapping' // Add/update VLAN mapping
|
||||||
'removeVlanMapping' // Remove VLAN mapping
|
'removeVlanMapping' // Remove VLAN mapping
|
||||||
'testVlanAssignment' // Test what VLAN a MAC gets
|
'testVlanAssignment' // Test what VLAN a MAC gets
|
||||||
|
|
||||||
|
// Security Profiles
|
||||||
|
'getSecurityProfiles' // List all security profiles
|
||||||
|
'getSecurityProfile' // Get a single profile by ID
|
||||||
|
'createSecurityProfile' // Create a reusable security profile
|
||||||
|
'updateSecurityProfile' // Update a profile (propagates to referencing routes)
|
||||||
|
'deleteSecurityProfile' // Delete a profile (with optional force)
|
||||||
|
'getSecurityProfileUsage' // Get routes referencing a profile
|
||||||
|
|
||||||
|
// Network Targets
|
||||||
|
'getNetworkTargets' // List all network targets
|
||||||
|
'getNetworkTarget' // Get a single target by ID
|
||||||
|
'createNetworkTarget' // Create a reusable host:port target
|
||||||
|
'updateNetworkTarget' // Update a target (propagates to referencing routes)
|
||||||
|
'deleteNetworkTarget' // Delete a target (with optional force)
|
||||||
|
'getNetworkTargetUsage' // Get routes referencing a target
|
||||||
```
|
```
|
||||||
|
|
||||||
## API Client
|
## API Client
|
||||||
@@ -1518,12 +1531,12 @@ const router = new DcRouter(options: IDcRouterOptions);
|
|||||||
| `remoteIngressManager` | `RemoteIngressManager` | Edge registration CRUD manager |
|
| `remoteIngressManager` | `RemoteIngressManager` | Edge registration CRUD manager |
|
||||||
| `tunnelManager` | `TunnelManager` | Tunnel lifecycle and status manager |
|
| `tunnelManager` | `TunnelManager` | Tunnel lifecycle and status manager |
|
||||||
| `vpnManager` | `VpnManager` | VPN server lifecycle and client CRUD manager |
|
| `vpnManager` | `VpnManager` | VPN server lifecycle and client CRUD manager |
|
||||||
| `storageManager` | `StorageManager` | Storage backend |
|
|
||||||
| `opsServer` | `OpsServer` | OpsServer/dashboard instance |
|
| `opsServer` | `OpsServer` | OpsServer/dashboard instance |
|
||||||
| `metricsManager` | `MetricsManager` | Metrics collector |
|
| `metricsManager` | `MetricsManager` | Metrics collector |
|
||||||
| `cacheDb` | `CacheDb` | Cache database instance |
|
| `dcRouterDb` | `DcRouterDb` | Unified database instance (smartdata + smartdb) |
|
||||||
| `certProvisionScheduler` | `CertProvisionScheduler` | Per-domain backoff scheduler for cert provisioning |
|
| `routeConfigManager` | `RouteConfigManager` | Programmatic route CRUD manager |
|
||||||
| `certificateStatusMap` | `Map<string, ...>` | Domain-keyed certificate status from SmartProxy events |
|
| `apiTokenManager` | `ApiTokenManager` | API token management |
|
||||||
|
| `referenceResolver` | `ReferenceResolver` | Security profile and network target resolver |
|
||||||
|
|
||||||
### Re-exported Types
|
### Re-exported Types
|
||||||
|
|
||||||
@@ -1589,7 +1602,8 @@ tstest test/test.opsserver-api.ts --verbose --timeout 60
|
|||||||
| `test.jwt-auth.ts` | JWT login, verification, logout, invalid credentials | 8 |
|
| `test.jwt-auth.ts` | JWT login, verification, logout, invalid credentials | 8 |
|
||||||
| `test.opsserver-api.ts` | Health, statistics, configuration, log APIs | 8 |
|
| `test.opsserver-api.ts` | Health, statistics, configuration, log APIs | 8 |
|
||||||
| `test.protected-endpoint.ts` | Admin auth, identity verification, public endpoints | 8 |
|
| `test.protected-endpoint.ts` | Admin auth, identity verification, public endpoints | 8 |
|
||||||
| `test.storagemanager.ts` | Memory, filesystem, custom backends, concurrency | 8 |
|
| `test.reference-resolver.ts` | Security profiles, network targets, route resolution | 20 |
|
||||||
|
| `test.security-profiles-api.ts` | Profile/target API endpoints, auth enforcement | 13 |
|
||||||
|
|
||||||
## Docker / OCI Container Deployment
|
## Docker / OCI Container Deployment
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/dcrouter',
|
name: '@serve.zone/dcrouter',
|
||||||
version: '12.2.6',
|
version: '12.3.0',
|
||||||
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,13 @@ interface IIdentity {
|
|||||||
| `IApiTokenInfo` | Token info: id, name, scopes, createdAt, expiresAt, enabled |
|
| `IApiTokenInfo` | Token info: id, name, scopes, createdAt, expiresAt, enabled |
|
||||||
| `TApiTokenScope` | Token scopes: `routes:read`, `routes:write`, `config:read`, `tokens:read`, `tokens:manage` |
|
| `TApiTokenScope` | Token scopes: `routes:read`, `routes:write`, `config:read`, `tokens:read`, `tokens:manage` |
|
||||||
|
|
||||||
|
#### Security & Reference Interfaces
|
||||||
|
| Interface | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| `ISecurityProfile` | Reusable security config: id, name, description, security (ipAllowList, ipBlockList, maxConnections, rateLimit, etc.), extendsProfiles |
|
||||||
|
| `INetworkTarget` | Reusable host:port destination: id, name, description, host (string or string[]), port |
|
||||||
|
| `IRouteMetadata` | Route-to-reference links: securityProfileRef, networkTargetRef, snapshot names, lastResolvedAt |
|
||||||
|
|
||||||
#### Remote Ingress Interfaces
|
#### Remote Ingress Interfaces
|
||||||
| Interface | Description |
|
| Interface | Description |
|
||||||
|-----------|-------------|
|
|-----------|-------------|
|
||||||
@@ -241,6 +248,26 @@ interface ICertificateInfo {
|
|||||||
| `IReq_GetRadiusStatistics` | `getRadiusStatistics` | RADIUS stats |
|
| `IReq_GetRadiusStatistics` | `getRadiusStatistics` | RADIUS stats |
|
||||||
| `IReq_GetRadiusAccountingSummary` | `getRadiusAccountingSummary` | Accounting summary |
|
| `IReq_GetRadiusAccountingSummary` | `getRadiusAccountingSummary` | Accounting summary |
|
||||||
|
|
||||||
|
#### 🛡️ Security Profiles
|
||||||
|
| Interface | Method | Description |
|
||||||
|
|-----------|--------|-------------|
|
||||||
|
| `IReq_GetSecurityProfiles` | `getSecurityProfiles` | List all security profiles |
|
||||||
|
| `IReq_GetSecurityProfile` | `getSecurityProfile` | Get a single profile by ID |
|
||||||
|
| `IReq_CreateSecurityProfile` | `createSecurityProfile` | Create a reusable security profile |
|
||||||
|
| `IReq_UpdateSecurityProfile` | `updateSecurityProfile` | Update a profile (propagates to routes) |
|
||||||
|
| `IReq_DeleteSecurityProfile` | `deleteSecurityProfile` | Delete a profile (with optional force) |
|
||||||
|
| `IReq_GetSecurityProfileUsage` | `getSecurityProfileUsage` | Get routes referencing a profile |
|
||||||
|
|
||||||
|
#### 🎯 Network Targets
|
||||||
|
| Interface | Method | Description |
|
||||||
|
|-----------|--------|-------------|
|
||||||
|
| `IReq_GetNetworkTargets` | `getNetworkTargets` | List all network targets |
|
||||||
|
| `IReq_GetNetworkTarget` | `getNetworkTarget` | Get a single target by ID |
|
||||||
|
| `IReq_CreateNetworkTarget` | `createNetworkTarget` | Create a reusable host:port target |
|
||||||
|
| `IReq_UpdateNetworkTarget` | `updateNetworkTarget` | Update a target (propagates to routes) |
|
||||||
|
| `IReq_DeleteNetworkTarget` | `deleteNetworkTarget` | Delete a target (with optional force) |
|
||||||
|
| `IReq_GetNetworkTargetUsage` | `getNetworkTargetUsage` | Get routes referencing a target |
|
||||||
|
|
||||||
## Example: Full API Integration
|
## Example: Full API Integration
|
||||||
|
|
||||||
> 💡 **Tip:** For a higher-level, object-oriented API, use [`@serve.zone/dcrouter-apiclient`](https://www.npmjs.com/package/@serve.zone/dcrouter-apiclient) which wraps these interfaces with resource classes and builder patterns.
|
> 💡 **Tip:** For a higher-level, object-oriented API, use [`@serve.zone/dcrouter-apiclient`](https://www.npmjs.com/package/@serve.zone/dcrouter-apiclient) which wraps these interfaces with resource classes and builder patterns.
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/dcrouter',
|
name: '@serve.zone/dcrouter',
|
||||||
version: '12.2.6',
|
version: '12.3.0',
|
||||||
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import * as plugins from '../plugins.js';
|
|||||||
import * as appstate from '../appstate.js';
|
import * as appstate from '../appstate.js';
|
||||||
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
||||||
import { appRouter } from '../router.js';
|
import { appRouter } from '../router.js';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DeesElement,
|
DeesElement,
|
||||||
css,
|
css,
|
||||||
@@ -43,6 +42,12 @@ export class OpsDashboard extends DeesElement {
|
|||||||
theme: 'light',
|
theme: 'light',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@state() accessor configState: appstate.IConfigState = {
|
||||||
|
config: null,
|
||||||
|
isLoading: false,
|
||||||
|
error: null,
|
||||||
|
};
|
||||||
|
|
||||||
// Store viewTabs as a property to maintain object references
|
// Store viewTabs as a property to maintain object references
|
||||||
private viewTabs = [
|
private viewTabs = [
|
||||||
{
|
{
|
||||||
@@ -112,6 +117,20 @@ export class OpsDashboard extends DeesElement {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private get globalMessages() {
|
||||||
|
const messages: Array<{ id: string; type: string; message: string; dismissible?: boolean }> = [];
|
||||||
|
const config = this.configState.config;
|
||||||
|
if (config && !config.cache.enabled) {
|
||||||
|
messages.push({
|
||||||
|
id: 'db-disabled',
|
||||||
|
type: 'warning',
|
||||||
|
message: 'Database is disabled. Creating and editing routes, profiles, targets, and API tokens is not available.',
|
||||||
|
dismissible: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current view tab based on the UI state's activeView.
|
* Get the current view tab based on the UI state's activeView.
|
||||||
* Used to pass the correct selectedView to dees-simple-appdash on initial render.
|
* Used to pass the correct selectedView to dees-simple-appdash on initial render.
|
||||||
@@ -137,6 +156,14 @@ export class OpsDashboard extends DeesElement {
|
|||||||
});
|
});
|
||||||
this.rxSubscriptions.push(loginSubscription);
|
this.rxSubscriptions.push(loginSubscription);
|
||||||
|
|
||||||
|
// Subscribe to config state (for global warnings)
|
||||||
|
const configSubscription = appstate.configStatePart
|
||||||
|
.select((stateArg) => stateArg)
|
||||||
|
.subscribe((configState) => {
|
||||||
|
this.configState = configState;
|
||||||
|
});
|
||||||
|
this.rxSubscriptions.push(configSubscription);
|
||||||
|
|
||||||
// Subscribe to UI state
|
// Subscribe to UI state
|
||||||
const uiSubscription = appstate.uiStatePart
|
const uiSubscription = appstate.uiStatePart
|
||||||
.select((stateArg) => stateArg)
|
.select((stateArg) => stateArg)
|
||||||
@@ -205,6 +232,7 @@ export class OpsDashboard extends DeesElement {
|
|||||||
name="DCRouter OpsServer"
|
name="DCRouter OpsServer"
|
||||||
.viewTabs=${this.viewTabs}
|
.viewTabs=${this.viewTabs}
|
||||||
.selectedView=${this.currentViewTab}
|
.selectedView=${this.currentViewTab}
|
||||||
|
.globalMessages=${this.globalMessages}
|
||||||
>
|
>
|
||||||
</dees-simple-appdash>
|
</dees-simple-appdash>
|
||||||
</dees-simple-login>
|
</dees-simple-login>
|
||||||
|
|||||||
@@ -68,6 +68,12 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|||||||
- API token creation, revocation, and scope management
|
- API token creation, revocation, and scope management
|
||||||
- Routes tab and API Tokens tab in unified view
|
- Routes tab and API Tokens tab in unified view
|
||||||
|
|
||||||
|
### 🛡️ Security Profiles & Network Targets
|
||||||
|
- Create, edit, and delete reusable security profiles (IP allow/block lists, rate limits, max connections)
|
||||||
|
- Create, edit, and delete reusable network targets (host:port destinations)
|
||||||
|
- In-row and context menu actions for quick editing
|
||||||
|
- Changes propagate automatically to all referencing routes
|
||||||
|
|
||||||
### ⚙️ Configuration
|
### ⚙️ Configuration
|
||||||
- Read-only display of current system configuration
|
- Read-only display of current system configuration
|
||||||
- Status badges for boolean values (enabled/disabled)
|
- Status badges for boolean values (enabled/disabled)
|
||||||
|
|||||||
Reference in New Issue
Block a user