feat(web): determine initial UI view from URL and wire selected view to appdash; add interface and web README files; bump various dependencies

This commit is contained in:
2026-02-02 22:21:55 +00:00
parent 5b473de354
commit ae34314f54
10 changed files with 790 additions and 338 deletions

View File

@@ -1,5 +1,14 @@
# Changelog # Changelog
## 2026-02-02 - 3.1.0 - feat(web)
determine initial UI view from URL and wire selected view to appdash; add interface and web README files; bump various dependencies
- UI: derive initial active view from window.location.pathname so the dashboard supports deep linking and bookmarks (ts_web/appstate.ts)
- UI: pass selectedView to dees-simple-appdash by adding a currentViewTab getter in ops-dashboard (ts_web/elements/ops-dashboard.ts)
- Docs: add TypeScript interfaces README for @serve.zone/dcrouter-interfaces (ts_interfaces/readme.md)
- Docs: add/update web module README detailing features, routing, and build instructions (ts_web/readme.md) and expand main project README
- Deps: bump multiple dependencies in package.json (notable bumps: @api.global/typedrequest -> ^3.2.5, @design.estate/dees-catalog -> ^3.42.0, @design.estate/dees-element -> ^2.1.6, @push.rocks/projectinfo -> ^5.0.2, @push.rocks/smartdata -> ^5.16.7, @push.rocks/smartpromise -> ^4.2.3, @push.rocks/smartradius -> ^1.1.0, @push.rocks/smartstate -> ^2.0.30, mailauth -> ^4.12.1)
## 2026-02-01 - 3.0.0 - BREAKING CHANGE(deps) ## 2026-02-01 - 3.0.0 - BREAKING CHANGE(deps)
upgrade major dependencies, migrate action.target to action.targets (array), adapt to SmartRequest API changes, and add RADIUS server support upgrade major dependencies, migrate action.target to action.targets (array), adapt to SmartRequest API changes, and add RADIUS server support

View File

@@ -26,17 +26,17 @@
"node-forge": "^1.3.3" "node-forge": "^1.3.3"
}, },
"dependencies": { "dependencies": {
"@api.global/typedrequest": "^3.0.19", "@api.global/typedrequest": "^3.2.5",
"@api.global/typedrequest-interfaces": "^3.0.19", "@api.global/typedrequest-interfaces": "^3.0.19",
"@api.global/typedserver": "^8.3.0", "@api.global/typedserver": "^8.3.0",
"@api.global/typedsocket": "^4.1.0", "@api.global/typedsocket": "^4.1.0",
"@apiclient.xyz/cloudflare": "^7.1.0", "@apiclient.xyz/cloudflare": "^7.1.0",
"@design.estate/dees-catalog": "^3.41.5", "@design.estate/dees-catalog": "^3.42.0",
"@design.estate/dees-element": "^2.0.45", "@design.estate/dees-element": "^2.1.6",
"@push.rocks/projectinfo": "^5.0.1", "@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/qenv": "^6.1.3", "@push.rocks/qenv": "^6.1.3",
"@push.rocks/smartacme": "^8.0.0", "@push.rocks/smartacme": "^8.0.0",
"@push.rocks/smartdata": "^5.15.1", "@push.rocks/smartdata": "^5.16.7",
"@push.rocks/smartdns": "^7.6.1", "@push.rocks/smartdns": "^7.6.1",
"@push.rocks/smartfile": "^13.1.2", "@push.rocks/smartfile": "^13.1.2",
"@push.rocks/smartguard": "^3.1.0", "@push.rocks/smartguard": "^3.1.0",
@@ -46,20 +46,20 @@
"@push.rocks/smartmetrics": "^2.0.10", "@push.rocks/smartmetrics": "^2.0.10",
"@push.rocks/smartnetwork": "^4.4.0", "@push.rocks/smartnetwork": "^4.4.0",
"@push.rocks/smartpath": "^6.0.0", "@push.rocks/smartpath": "^6.0.0",
"@push.rocks/smartpromise": "^4.0.3", "@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smartproxy": "^22.4.2", "@push.rocks/smartproxy": "^22.4.2",
"@push.rocks/smartradius": "^1.0.3", "@push.rocks/smartradius": "^1.1.0",
"@push.rocks/smartrequest": "^5.0.1", "@push.rocks/smartrequest": "^5.0.1",
"@push.rocks/smartrule": "^2.0.1", "@push.rocks/smartrule": "^2.0.1",
"@push.rocks/smartrx": "^3.0.10", "@push.rocks/smartrx": "^3.0.10",
"@push.rocks/smartstate": "^2.0.27", "@push.rocks/smartstate": "^2.0.30",
"@push.rocks/smartunique": "^3.0.9", "@push.rocks/smartunique": "^3.0.9",
"@serve.zone/interfaces": "^5.3.0", "@serve.zone/interfaces": "^5.3.0",
"@tsclass/tsclass": "^9.3.0", "@tsclass/tsclass": "^9.3.0",
"@types/mailparser": "^3.4.6", "@types/mailparser": "^3.4.6",
"ip": "^2.0.1", "ip": "^2.0.1",
"lru-cache": "^11.2.5", "lru-cache": "^11.2.5",
"mailauth": "^4.12.0", "mailauth": "^4.12.1",
"mailparser": "^3.9.3", "mailparser": "^3.9.3",
"uuid": "^13.0.0" "uuid": "^13.0.0"
}, },

92
pnpm-lock.yaml generated
View File

@@ -9,7 +9,7 @@ importers:
.: .:
dependencies: dependencies:
'@api.global/typedrequest': '@api.global/typedrequest':
specifier: ^3.0.19 specifier: ^3.2.5
version: 3.2.5 version: 3.2.5
'@api.global/typedrequest-interfaces': '@api.global/typedrequest-interfaces':
specifier: ^3.0.19 specifier: ^3.0.19
@@ -24,13 +24,13 @@ 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.41.5 specifier: ^3.42.0
version: 3.41.5(@tiptap/pm@2.27.2) version: 3.42.0(@tiptap/pm@2.27.2)
'@design.estate/dees-element': '@design.estate/dees-element':
specifier: ^2.0.45 specifier: ^2.1.6
version: 2.1.6 version: 2.1.6
'@push.rocks/projectinfo': '@push.rocks/projectinfo':
specifier: ^5.0.1 specifier: ^5.0.2
version: 5.0.2 version: 5.0.2
'@push.rocks/qenv': '@push.rocks/qenv':
specifier: ^6.1.3 specifier: ^6.1.3
@@ -39,7 +39,7 @@ importers:
specifier: ^8.0.0 specifier: ^8.0.0
version: 8.0.0(socks@2.8.7) version: 8.0.0(socks@2.8.7)
'@push.rocks/smartdata': '@push.rocks/smartdata':
specifier: ^5.15.1 specifier: ^5.16.7
version: 5.16.7(socks@2.8.7) version: 5.16.7(socks@2.8.7)
'@push.rocks/smartdns': '@push.rocks/smartdns':
specifier: ^7.6.1 specifier: ^7.6.1
@@ -69,13 +69,13 @@ importers:
specifier: ^6.0.0 specifier: ^6.0.0
version: 6.0.0 version: 6.0.0
'@push.rocks/smartpromise': '@push.rocks/smartpromise':
specifier: ^4.0.3 specifier: ^4.2.3
version: 4.2.3 version: 4.2.3
'@push.rocks/smartproxy': '@push.rocks/smartproxy':
specifier: ^22.4.2 specifier: ^22.4.2
version: 22.4.2(socks@2.8.7) version: 22.4.2(socks@2.8.7)
'@push.rocks/smartradius': '@push.rocks/smartradius':
specifier: ^1.0.3 specifier: ^1.1.0
version: 1.1.0 version: 1.1.0
'@push.rocks/smartrequest': '@push.rocks/smartrequest':
specifier: ^5.0.1 specifier: ^5.0.1
@@ -87,8 +87,8 @@ importers:
specifier: ^3.0.10 specifier: ^3.0.10
version: 3.0.10 version: 3.0.10
'@push.rocks/smartstate': '@push.rocks/smartstate':
specifier: ^2.0.27 specifier: ^2.0.30
version: 2.0.27 version: 2.0.30
'@push.rocks/smartunique': '@push.rocks/smartunique':
specifier: ^3.0.9 specifier: ^3.0.9
version: 3.0.9 version: 3.0.9
@@ -108,8 +108,8 @@ importers:
specifier: ^11.2.5 specifier: ^11.2.5
version: 11.2.5 version: 11.2.5
mailauth: mailauth:
specifier: ^4.12.0 specifier: ^4.12.1
version: 4.12.0 version: 4.12.1
mailparser: mailparser:
specifier: ^3.9.3 specifier: ^3.9.3
version: 3.9.3 version: 3.9.3
@@ -362,8 +362,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.41.5': '@design.estate/dees-catalog@3.42.0':
resolution: {integrity: sha512-2LOUh92h2ndzlEKOyDqGE2Mdjhmxt6ZeAqHt5KKslNHzmNhdWFKUe6C1Vm2nU6vRvFLXXC/ex56KSP3XcCPD8g==} resolution: {integrity: sha512-pArkafnrhRsHsSxKUMUM2YP5ei/AbcchPEKZY2PyHHAdXcNxyT3pE2Oh1FPcs1pqF2LpEgJRq8KFQbFhvhp8Nw==}
'@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==}
@@ -991,6 +991,9 @@ packages:
'@push.rocks/smartjson@5.2.0': '@push.rocks/smartjson@5.2.0':
resolution: {integrity: sha512-710e8UwovRfPgUtaBHcd6unaODUjV5fjxtGcGCqtaTcmvOV6VpasdVfT66xMDzQmWH2E9ZfHDJeso9HdDQzNQA==} resolution: {integrity: sha512-710e8UwovRfPgUtaBHcd6unaODUjV5fjxtGcGCqtaTcmvOV6VpasdVfT66xMDzQmWH2E9ZfHDJeso9HdDQzNQA==}
'@push.rocks/smartjson@6.0.0':
resolution: {integrity: sha512-FYfJnmukt66WePn6xrVZ3BLmRQl9W82LcsICK3VU9sGW7kasig090jKXPm+yX8ibQcZAO/KyR/Q8tMIYZNxGew==}
'@push.rocks/smartjwt@2.2.1': '@push.rocks/smartjwt@2.2.1':
resolution: {integrity: sha512-Xwau9o8u7kLfSGi5v+kiyGB/hiDPclZjVEuj69J0LszO9nOh4OexYizKIOgOzKQMqnYQ03Dy35KqP9pdEjccbQ==} resolution: {integrity: sha512-Xwau9o8u7kLfSGi5v+kiyGB/hiDPclZjVEuj69J0LszO9nOh4OexYizKIOgOzKQMqnYQ03Dy35KqP9pdEjccbQ==}
@@ -1108,8 +1111,8 @@ packages:
'@push.rocks/smartspawn@3.0.3': '@push.rocks/smartspawn@3.0.3':
resolution: {integrity: sha512-DyrGPV69wwOiJgKkyruk5hS3UEGZ99xFAqBE9O2nM8VXCRLbbty3xt1Ug5Z092ZZmJYaaGMSnMw3ijyZJFCT0Q==} resolution: {integrity: sha512-DyrGPV69wwOiJgKkyruk5hS3UEGZ99xFAqBE9O2nM8VXCRLbbty3xt1Ug5Z092ZZmJYaaGMSnMw3ijyZJFCT0Q==}
'@push.rocks/smartstate@2.0.27': '@push.rocks/smartstate@2.0.30':
resolution: {integrity: sha512-q4UKir7GV3hakJWXQR4DoA4tUVwT5GRkJ/MtanHYF0wZLHfS19+nGmyO9y974zk3eT9hmy3+Lq5cKtU2W6+Y3w==} resolution: {integrity: sha512-IuNW8XtSumXIr7g7MIFyWg5PBwLF2mwsymTJbSEycK2Pa9ZLk4yjRHnR907xCilxgiMU9ixQZyNdpa5MMF999A==}
'@push.rocks/smartstream@2.0.8': '@push.rocks/smartstream@2.0.8':
resolution: {integrity: sha512-GlF/9cCkvBHwKa3DK4DO5wjfSgqkj6gAS4TrY9uD5NMHu9RQv4WiNrElTYj7iCEpnZgUnLO3tzw1JA3NRIMnnA==} resolution: {integrity: sha512-GlF/9cCkvBHwKa3DK4DO5wjfSgqkj6gAS4TrY9uD5NMHu9RQv4WiNrElTYj7iCEpnZgUnLO3tzw1JA3NRIMnnA==}
@@ -2570,10 +2573,6 @@ packages:
fast-json-stable-stringify@2.1.0: fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
fast-xml-parser@4.5.2:
resolution: {integrity: sha512-xmnYV9o0StIz/0ArdzmWTxn9oDy0lH8Z80/8X/TD2EUQKXY4DHxoT9mYBqgGIG17DgddCJtH1M6DriMbalNsAA==}
hasBin: true
fast-xml-parser@4.5.3: fast-xml-parser@4.5.3:
resolution: {integrity: sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==} resolution: {integrity: sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==}
hasBin: true hasBin: true
@@ -3098,8 +3097,8 @@ packages:
lucide@0.563.0: lucide@0.563.0:
resolution: {integrity: sha512-2zBzDJ5n2Plj3d0ksj6h9TWPOSiKu9gtxJxnBAye11X/8gfWied6IYJn6ADYBp1NPoJmgpyOYP3wMrVx69+2AA==} resolution: {integrity: sha512-2zBzDJ5n2Plj3d0ksj6h9TWPOSiKu9gtxJxnBAye11X/8gfWied6IYJn6ADYBp1NPoJmgpyOYP3wMrVx69+2AA==}
mailauth@4.12.0: mailauth@4.12.1:
resolution: {integrity: sha512-2fMtvJBbXV32NlD6f6BSRTLNPsC1UgA+oj4mtAIUzzZlTQF2oNUgWmRQFKf1Ui9ad6KcadF9oqYrl7sCTHBNag==} resolution: {integrity: sha512-mSbMST+YUKj4WAfVvVszw/lnqxYA9AsYX6jYdl9vQdgz1vP5gIMwK6/RcqY+CkMkfkhFzea5+72asj620eAHmQ==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
hasBin: true hasBin: true
@@ -3430,10 +3429,6 @@ packages:
resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==}
engines: {node: '>= 6.13.0'} engines: {node: '>= 6.13.0'}
nodemailer@7.0.11:
resolution: {integrity: sha512-gnXhNRE0FNhD7wPSCGhdNh46Hs6nm+uTyg+Kq0cZukNQiYdnCsoQjodNP9BQVG9XrcK/v6/MgpAPBUFyzh9pvw==}
engines: {node: '>=6.0.0'}
nodemailer@7.0.13: nodemailer@7.0.13:
resolution: {integrity: sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==} resolution: {integrity: sha512-PNDFSJdP+KFgdsG3ZzMXCgquO7I6McjY2vlqILjtJd0hy8wEvtugS9xKRF2NWlPNGxvLCXlTNIae4serI7dinw==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
@@ -4056,8 +4051,8 @@ packages:
tldts-core@7.0.21: tldts-core@7.0.21:
resolution: {integrity: sha512-oVOMdHvgjqyzUZH1rOESgJP1uNe2bVrfK0jUHHmiM2rpEiRbf3j4BrsIc6JigJRbHGanQwuZv/R+LTcHsw+bLA==} resolution: {integrity: sha512-oVOMdHvgjqyzUZH1rOESgJP1uNe2bVrfK0jUHHmiM2rpEiRbf3j4BrsIc6JigJRbHGanQwuZv/R+LTcHsw+bLA==}
tldts@7.0.19: tldts@7.0.21:
resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==} resolution: {integrity: sha512-Plu6V8fF/XU6d2k8jPtlQf5F4Xx2hAin4r2C2ca7wR8NK5MbRTo9huLUWRe28f3Uk8bYZfg74tit/dSjc18xnw==}
hasBin: true hasBin: true
tmp@0.0.33: tmp@0.0.33:
@@ -4155,8 +4150,8 @@ packages:
undici-types@7.16.0: undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
undici@7.16.0: undici@7.19.2:
resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} resolution: {integrity: sha512-4VQSpGEGsWzk0VYxyB/wVX/Q7qf9t5znLRgs0dzszr9w9Fej/8RVNQ+S20vdXSAyra/bJ7ZQfGv6ZMj7UEbzSg==}
engines: {node: '>=20.18.1'} engines: {node: '>=20.18.1'}
unified@11.0.5: unified@11.0.5:
@@ -4430,7 +4425,7 @@ snapshots:
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@api.global/typedsocket': 4.1.0(@push.rocks/smartserve@2.0.1) '@api.global/typedsocket': 4.1.0(@push.rocks/smartserve@2.0.1)
'@cloudflare/workers-types': 4.20260131.0 '@cloudflare/workers-types': 4.20260131.0
'@design.estate/dees-catalog': 3.41.5(@tiptap/pm@2.27.2) '@design.estate/dees-catalog': 3.42.0(@tiptap/pm@2.27.2)
'@design.estate/dees-comms': 1.0.30 '@design.estate/dees-comms': 1.0.30
'@push.rocks/lik': 6.2.2 '@push.rocks/lik': 6.2.2
'@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartdelay': 3.0.5
@@ -5032,7 +5027,7 @@ snapshots:
dependencies: dependencies:
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@design.estate/dees-catalog@3.41.5(@tiptap/pm@2.27.2)': '@design.estate/dees-catalog@3.42.0(@tiptap/pm@2.27.2)':
dependencies: dependencies:
'@design.estate/dees-domtools': 2.3.8 '@design.estate/dees-domtools': 2.3.8
'@design.estate/dees-element': 2.1.6 '@design.estate/dees-element': 2.1.6
@@ -5085,7 +5080,7 @@ snapshots:
'@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpromise': 4.2.3
'@push.rocks/smartrouter': 1.3.3 '@push.rocks/smartrouter': 1.3.3
'@push.rocks/smartrx': 3.0.10 '@push.rocks/smartrx': 3.0.10
'@push.rocks/smartstate': 2.0.27 '@push.rocks/smartstate': 2.0.30
'@push.rocks/smartstring': 4.1.0 '@push.rocks/smartstring': 4.1.0
'@push.rocks/smarturl': 3.1.0 '@push.rocks/smarturl': 3.1.0
'@push.rocks/webrequest': 3.0.37 '@push.rocks/webrequest': 3.0.37
@@ -6203,6 +6198,13 @@ snapshots:
fast-json-stable-stringify: 2.1.0 fast-json-stable-stringify: 2.1.0
lodash.clonedeep: 4.5.0 lodash.clonedeep: 4.5.0
'@push.rocks/smartjson@6.0.0':
dependencies:
'@push.rocks/smartenv': 6.0.0
'@push.rocks/smartstring': 4.1.0
fast-json-stable-stringify: 2.1.0
lodash.clonedeep: 4.5.0
'@push.rocks/smartjwt@2.2.1': '@push.rocks/smartjwt@2.2.1':
dependencies: dependencies:
'@push.rocks/smartcrypto': 2.0.4 '@push.rocks/smartcrypto': 2.0.4
@@ -6580,11 +6582,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@push.rocks/smartstate@2.0.27': '@push.rocks/smartstate@2.0.30':
dependencies: dependencies:
'@push.rocks/lik': 6.2.2 '@push.rocks/lik': 6.2.2
'@push.rocks/smarthash': 3.2.6 '@push.rocks/smarthash': 3.2.6
'@push.rocks/smartjson': 5.2.0 '@push.rocks/smartjson': 6.0.0
'@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpromise': 4.2.3
'@push.rocks/smartrx': 3.0.10 '@push.rocks/smartrx': 3.0.10
'@push.rocks/webstore': 2.0.20 '@push.rocks/webstore': 2.0.20
@@ -8267,10 +8269,6 @@ snapshots:
fast-json-stable-stringify@2.1.0: {} fast-json-stable-stringify@2.1.0: {}
fast-xml-parser@4.5.2:
dependencies:
strnum: 1.1.2
fast-xml-parser@4.5.3: fast-xml-parser@4.5.3:
dependencies: dependencies:
strnum: 1.1.2 strnum: 1.1.2
@@ -8875,17 +8873,17 @@ snapshots:
lucide@0.563.0: {} lucide@0.563.0: {}
mailauth@4.12.0: mailauth@4.12.1:
dependencies: dependencies:
'@postalsys/vmc': 1.1.2 '@postalsys/vmc': 1.1.2
fast-xml-parser: 4.5.2 fast-xml-parser: 5.3.4
ipaddr.js: 2.3.0 ipaddr.js: 2.3.0
joi: 18.0.2 joi: 18.0.2
libmime: 5.3.7 libmime: 5.3.7
nodemailer: 7.0.11 nodemailer: 7.0.13
punycode.js: 2.3.1 punycode.js: 2.3.1
tldts: 7.0.19 tldts: 7.0.21
undici: 7.16.0 undici: 7.19.2
yargs: 17.7.2 yargs: 17.7.2
mailparser@3.9.3: mailparser@3.9.3:
@@ -9397,8 +9395,6 @@ snapshots:
node-forge@1.3.3: {} node-forge@1.3.3: {}
nodemailer@7.0.11: {}
nodemailer@7.0.13: {} nodemailer@7.0.13: {}
normalize-newline@4.1.0: normalize-newline@4.1.0:
@@ -10196,7 +10192,7 @@ snapshots:
tldts-core@7.0.21: {} tldts-core@7.0.21: {}
tldts@7.0.19: tldts@7.0.21:
dependencies: dependencies:
tldts-core: 7.0.21 tldts-core: 7.0.21
@@ -10273,7 +10269,7 @@ snapshots:
undici-types@7.16.0: {} undici-types@7.16.0: {}
undici@7.16.0: {} undici@7.19.2: {}
unified@11.0.5: unified@11.0.5:
dependencies: dependencies:

575
readme.md
View File

@@ -1,10 +1,14 @@
# dcrouter # @serve.zone/dcrouter
![](https://code.foss.global/serve.zone/docs/raw/branch/main/dcrouter.png) ![](https://code.foss.global/serve.zone/docs/raw/branch/main/dcrouter.png)
**dcrouter: a traffic router intended to be gating your datacenter.** **dcrouter: A powerful traffic router designed to be the gateway for your datacenter.** 🚀
A comprehensive traffic routing solution that provides unified gateway capabilities for HTTP/HTTPS, TCP/SNI, email (SMTP), and DNS protocols. Designed for enterprises requiring robust traffic management, automatic certificate provisioning, and enterprise-grade email infrastructure. A comprehensive traffic routing solution that provides unified gateway capabilities for HTTP/HTTPS, TCP/SNI, email (SMTP), DNS protocols, and RADIUS authentication. Designed for enterprises requiring robust traffic management, automatic certificate provisioning, and enterprise-grade email infrastructure.
## 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.
## Table of Contents ## Table of Contents
@@ -13,11 +17,16 @@ A comprehensive traffic routing solution that provides unified gateway capabilit
- [Quick Start](#quick-start) - [Quick Start](#quick-start)
- [Architecture](#architecture) - [Architecture](#architecture)
- [Configuration](#configuration) - [Configuration](#configuration)
- [Socket-Handler Mode](#socket-handler-mode)
- [Email System](#email-system) - [Email System](#email-system)
- [SmartProxy Routing](#smartproxy-routing) - [SmartProxy Routing](#smartproxy-routing)
- [RADIUS Server](#radius-server)
- [Storage System](#storage-system)
- [Security Features](#security-features) - [Security Features](#security-features)
- [OpsServer Dashboard](#opsserver-dashboard)
- [API Reference](#api-reference) - [API Reference](#api-reference)
- [Examples](#examples) - [Examples](#examples)
- [Testing](#testing)
- [Troubleshooting](#troubleshooting) - [Troubleshooting](#troubleshooting)
## Features ## Features
@@ -36,14 +45,16 @@ A comprehensive traffic routing solution that provides unified gateway capabilit
### 📧 **Complete Email Infrastructure** ### 📧 **Complete Email Infrastructure**
- **Multi-domain SMTP server** on standard ports (25, 587, 465) - **Multi-domain SMTP server** on standard ports (25, 587, 465)
- **Pattern-based email routing** with three processing modes - **Pattern-based email routing** with four processing modes (forward, process, deliver, reject)
- **DKIM, SPF, DMARC** authentication and verification - **DKIM, SPF, DMARC** authentication and verification
- **Enterprise deliverability** with IP warmup and reputation management - **Enterprise deliverability** with IP warmup and reputation management
- **Bounce handling** with suppression lists
### 📡 **RADIUS Server** ### 📡 **RADIUS Server**
- **MAC Authentication Bypass (MAB)** for network device authentication - **MAC Authentication Bypass (MAB)** for network device authentication
- **VLAN assignment** based on MAC address or OUI patterns - **VLAN assignment** based on MAC address or OUI patterns
- **RADIUS accounting** for session tracking and billing - **RADIUS accounting** for session tracking and billing
- **OpsServer API integration** for real-time management
### ⚡ **High Performance** ### ⚡ **High Performance**
- **Connection pooling** and efficient resource management - **Connection pooling** and efficient resource management
@@ -57,10 +68,18 @@ A comprehensive traffic routing solution that provides unified gateway capabilit
- **Automatic data migration** between backends - **Automatic data migration** between backends
- **Persistent configuration** for domains, routes, and security data - **Persistent configuration** for domains, routes, and security data
### 🖥️ **OpsServer Dashboard**
- **Web-based management interface** for real-time monitoring
- **JWT authentication** with secure admin access
- **Live statistics** for connections, email, DNS, and RADIUS
- **Configuration management** via TypedRequest API
## Installation ## Installation
```bash ```bash
npm install @serve.zone/dcrouter --save npm install @serve.zone/dcrouter --save
# or
pnpm add @serve.zone/dcrouter
``` ```
### Prerequisites ### Prerequisites
@@ -134,6 +153,30 @@ const router = new DcRouter({
await router.start(); await router.start();
``` ```
### With OpsServer Dashboard
```typescript
import { DcRouter } from '@serve.zone/dcrouter';
const router = new DcRouter({
// Enable OpsServer for web dashboard
opsServerConfig: {
port: 3000,
admin: {
username: 'admin',
password: 'your-secure-password'
}
},
// Your routing configuration...
smartProxyConfig: { /* ... */ },
emailConfig: { /* ... */ }
});
await router.start();
// Dashboard available at http://localhost:3000
```
## Architecture ## Architecture
### System Overview ### System Overview
@@ -145,38 +188,44 @@ graph TB
SMTP[SMTP Clients] SMTP[SMTP Clients]
TCP[TCP Clients] TCP[TCP Clients]
DNS[DNS Queries] DNS[DNS Queries]
RADIUS[RADIUS Clients]
end end
subgraph "DcRouter Core" subgraph "DcRouter Core"
DcRouter[DcRouter Orchestrator] DcRouter[DcRouter Orchestrator]
SmartProxy[SmartProxy Engine] SmartProxy[SmartProxy Engine]
EmailServer[Unified Email Server] EmailServer[Unified Email Server]
DnsServer[DNS Server] DnsServer[DNS Server]
RadiusServer[RADIUS Server]
CertManager[Certificate Manager] CertManager[Certificate Manager]
OpsServer[OpsServer Dashboard]
end end
subgraph "Backend Services" subgraph "Backend Services"
WebServices[Web Services] WebServices[Web Services]
MailServers[Mail Servers] MailServers[Mail Servers]
Databases[Databases] Databases[Databases]
APIs[Internal APIs] APIs[Internal APIs]
end end
HTTP --> SmartProxy HTTP --> SmartProxy
TCP --> SmartProxy TCP --> SmartProxy
SMTP --> EmailServer SMTP --> EmailServer
DNS --> DnsServer DNS --> DnsServer
RADIUS --> RadiusServer
DcRouter --> SmartProxy DcRouter --> SmartProxy
DcRouter --> EmailServer DcRouter --> EmailServer
DcRouter --> DnsServer DcRouter --> DnsServer
DcRouter --> RadiusServer
DcRouter --> CertManager DcRouter --> CertManager
DcRouter --> OpsServer
SmartProxy --> WebServices SmartProxy --> WebServices
SmartProxy --> APIs SmartProxy --> APIs
EmailServer --> MailServers EmailServer --> MailServers
EmailServer --> Databases EmailServer --> Databases
CertManager -.-> SmartProxy CertManager -.-> SmartProxy
CertManager -.-> EmailServer CertManager -.-> EmailServer
``` ```
@@ -197,12 +246,30 @@ High-performance HTTP/HTTPS and TCP/SNI proxy with:
Enterprise-grade SMTP server with: Enterprise-grade SMTP server with:
- Multi-domain support - Multi-domain support
- Pattern-based routing - Pattern-based routing
- Three processing modes - Four processing modes (forward, process, deliver, reject)
- Complete authentication stack - Complete authentication stack (DKIM, SPF, DMARC)
#### **DNS Server**
Authoritative DNS server with:
- Dynamic record management
- DNS-over-HTTPS (DoH) support
- ACME DNS-01 challenge handling
#### **RADIUS Server**
Network authentication server with:
- MAC Authentication Bypass (MAB)
- VLAN assignment
- Accounting support
#### **Certificate Manager** #### **Certificate Manager**
Automatic TLS certificate provisioning via ACME with DNS-01 challenges. Automatic TLS certificate provisioning via ACME with DNS-01 challenges.
#### **OpsServer Dashboard**
Web-based management interface with:
- JWT-secured API
- Real-time statistics
- Configuration management
## Configuration ## Configuration
### Complete Configuration Interface ### Complete Configuration Interface
@@ -215,46 +282,67 @@ interface IDcRouterOptions {
acme?: IAcmeConfig; acme?: IAcmeConfig;
allowSessionTicket?: boolean; allowSessionTicket?: boolean;
}; };
// Email system configuration // Email system configuration
emailConfig?: { emailConfig?: {
ports: number[]; ports: number[];
hostname: string; hostname: string;
domains?: IEmailDomainConfig[]; // Domain infrastructure setup domains?: IEmailDomainConfig[]; // Domain infrastructure setup
routes: IEmailRoute[]; // Route-based email handling routes: IEmailRoute[]; // Route-based email handling
auth?: IAuthConfig; auth?: IAuthConfig;
tls?: ITlsConfig; tls?: ITlsConfig;
maxMessageSize?: number; maxMessageSize?: number;
rateLimits?: IRateLimitConfig; rateLimits?: IRateLimitConfig;
useSocketHandler?: boolean; // Enable socket-handler mode (no port binding) useSocketHandler?: boolean; // Enable socket-handler mode (no port binding)
defaults?: { // Global defaults for all domains defaults?: { // Global defaults for all domains
dnsMode?: 'forward' | 'internal-dns' | 'external-dns'; dnsMode?: 'forward' | 'internal-dns' | 'external-dns';
dkim?: IDkimConfig; dkim?: IDkimConfig;
rateLimits?: IRateLimitConfig; rateLimits?: IRateLimitConfig;
}; };
}; };
// DNS server configuration // DNS server configuration
dnsServerConfig?: { dnsServerConfig?: {
port?: number; port?: number;
authoritative?: boolean; authoritative?: boolean;
records?: IDnsRecord[]; records?: IDnsRecord[];
}; };
// DNS domain for automatic DNS-over-HTTPS setup // DNS domain for automatic DNS-over-HTTPS setup
dnsDomain?: string; // e.g., 'dns.example.com' dnsDomain?: string; // e.g., 'dns.example.com'
// DNS nameserver domains (enables authoritative DNS)
dnsNsDomains?: string[]; // e.g., ['ns1.example.com', 'ns2.example.com']
// RADIUS server configuration
radiusConfig?: {
port?: number;
secret: string;
clients?: IRadiusClient[];
macAuth?: IMacAuthConfig;
vlanAssignment?: IVlanAssignment[];
};
// OpsServer configuration
opsServerConfig?: {
port?: number;
admin: {
username: string;
password: string;
};
};
// TLS and certificate configuration // TLS and certificate configuration
tls?: { tls?: {
contactEmail: string; contactEmail: string;
domain: string; domain: string;
}; };
// DNS challenge configuration // DNS challenge configuration
dnsChallenge?: { dnsChallenge?: {
cloudflareApiKey: string; cloudflareApiKey: string;
}; };
// Storage configuration // Storage configuration
storage?: { storage?: {
fsPath?: string; // Filesystem storage path fsPath?: string; // Filesystem storage path
@@ -489,7 +577,7 @@ Reject emails with custom SMTP responses.
```typescript ```typescript
{ {
name: 'reject-spam', name: 'reject-spam',
match: { match: {
senders: '*@spam-domain.com', senders: '*@spam-domain.com',
sizeRange: { min: 1000000 } // > 1MB sizeRange: { min: 1000000 } // > 1MB
}, },
@@ -526,7 +614,7 @@ Route different domains to different servers:
name: 'partner-domain', name: 'partner-domain',
match: { recipients: '*@partner.com' }, match: { recipients: '*@partner.com' },
action: { action: {
type: 'forward', type: 'forward',
forward: { host: 'partner-mail.com', port: 587 } forward: { host: 'partner-mail.com', port: 587 }
} }
} }
@@ -553,30 +641,6 @@ Different handling for authenticated vs unauthenticated senders:
} }
``` ```
#### **Content-Based Filtering**
Filter based on size, subject, or headers:
```typescript
{
name: 'large-email-reject',
match: { sizeRange: { min: 25000000 } }, // > 25MB
action: {
type: 'reject',
reject: { code: 552, message: 'Message too large' }
}
},
{
name: 'priority-emails',
match: {
headers: { 'X-Priority': 'high' },
subject: /urgent|emergency/i
},
action: {
type: 'process',
process: { queue: 'priority' }
}
}
```
### Email Security Features ### Email Security Features
#### **Route Matching Patterns** #### **Route Matching Patterns**
@@ -593,7 +657,7 @@ match: { clientIp: '192.168.0.0/16' } // Private subnet
match: { clientIp: ['10.0.0.0/8', '172.16.0.0/12'] } // Multiple ranges match: { clientIp: ['10.0.0.0/8', '172.16.0.0/12'] } // Multiple ranges
// Header matching // Header matching
match: { match: {
headers: { headers: {
'X-Priority': 'high', 'X-Priority': 'high',
'Subject': /urgent|emergency/i 'Subject': /urgent|emergency/i
@@ -652,7 +716,7 @@ const routes = [
} }
} }
}, },
// Static file serving // Static file serving
{ {
name: 'static-assets', name: 'static-assets',
@@ -690,7 +754,7 @@ const tcpRoutes = [
} }
} }
}, },
// SNI-based routing for TLS services // SNI-based routing for TLS services
{ {
name: 'secure-service', name: 'secure-service',
@@ -709,6 +773,72 @@ const tcpRoutes = [
]; ];
``` ```
## RADIUS Server
DcRouter includes a RADIUS server for network access control:
### Basic RADIUS Configuration
```typescript
const router = new DcRouter({
radiusConfig: {
port: 1812,
secret: 'your-radius-secret',
clients: [
{
name: 'switch-1',
ip: '192.168.1.1',
secret: 'client-secret'
}
]
}
});
```
### MAC Authentication Bypass (MAB)
```typescript
const router = new DcRouter({
radiusConfig: {
port: 1812,
secret: 'radius-secret',
macAuth: {
enabled: true,
allowedMacs: [
'aa:bb:cc:dd:ee:ff',
'aa:bb:cc:*' // Wildcard for OUI matching
],
defaultVlan: 100,
guestVlan: 999
}
}
});
```
### VLAN Assignment
```typescript
const router = new DcRouter({
radiusConfig: {
secret: 'radius-secret',
vlanAssignment: [
{
match: { mac: 'aa:bb:cc:*' }, // Vendor OUI match
vlan: 100
},
{
match: { mac: 'dd:ee:ff:*' },
vlan: 200
},
{
match: { default: true },
vlan: 999 // Guest VLAN
}
]
}
});
```
## Storage System ## Storage System
### StorageManager ### StorageManager
@@ -756,31 +886,6 @@ The storage system is used for:
- **IP Reputation**: `/security/ip-reputation/{ip}.json` - **IP Reputation**: `/security/ip-reputation/{ip}.json`
- **Domain Configs**: `/email/domains/{domain}.json` - **Domain Configs**: `/email/domains/{domain}.json`
### Data Migration
Migrate data between storage backends:
```typescript
import { StorageManager } from '@serve.zone/dcrouter';
// Export from filesystem
const fsStorage = new StorageManager({ fsPath: './data' });
const keys = await fsStorage.list('/');
const data = {};
for (const key of keys) {
data[key] = await fsStorage.get(key);
}
// Import to cloud storage
const cloudStorage = new StorageManager({
readFunction: cloudRead,
writeFunction: cloudWrite
});
for (const [key, value] of Object.entries(data)) {
await cloudStorage.set(key, value);
}
```
## Security Features ## Security Features
### IP Reputation Checking ### IP Reputation Checking
@@ -801,21 +906,58 @@ if (result.isBlocked) {
} }
``` ```
### Content Security Scanner ### Rate Limiting
```typescript ```typescript
import { ContentScanner } from '@serve.zone/dcrouter'; const router = new DcRouter({
emailConfig: {
const scanner = new ContentScanner({ rateLimits: {
spamThreshold: 5.0, inbound: {
virusScanning: true, messagesPerMinute: 100,
attachmentFiltering: { connectionsPerIp: 10,
maxSize: 25 * 1024 * 1024, recipientsPerMessage: 50
blockedTypes: ['.exe', '.bat', '.scr'] },
outbound: {
messagesPerHour: 1000,
messagesPerDay: 10000
}
}
} }
}); });
```
const scanResult = await scanner.scanEmail(email); ## OpsServer Dashboard
The OpsServer provides a web-based management interface:
### Features
- **Real-time Statistics**: View connections, email throughput, DNS queries, RADIUS sessions
- **Configuration Management**: Update routes and settings via API
- **Log Viewer**: Access system logs with filtering
- **Security Dashboard**: Monitor threats and blocked connections
### API Endpoints
The OpsServer exposes TypedRequest endpoints:
```typescript
// Health check
POST /typedrequest { method: 'getHealthStatus' }
// Server statistics
POST /typedrequest { method: 'getServerStatistics' }
// Configuration
POST /typedrequest { method: 'getConfiguration' }
POST /typedrequest { method: 'updateConfiguration', data: { ... } }
// Logs
POST /typedrequest { method: 'getLogs', data: { level: 'info', limit: 100 } }
// RADIUS
POST /typedrequest { method: 'getRadiusSessions' }
POST /typedrequest { method: 'getRadiusClients' }
``` ```
## API Reference ## API Reference
@@ -830,7 +972,7 @@ constructor(options: IDcRouterOptions)
#### Methods #### Methods
##### `start(): Promise<void>` ##### `start(): Promise<void>`
Starts all configured services (SmartProxy, email server, DNS server). Starts all configured services (SmartProxy, email server, DNS server, RADIUS server, OpsServer).
##### `stop(): Promise<void>` ##### `stop(): Promise<void>`
Gracefully stops all services. Gracefully stops all services.
@@ -863,9 +1005,6 @@ const status = router.emailService.getEmailStatus(emailId);
console.log(status.status); // 'pending', 'sent', 'delivered', 'bounced' console.log(status.status); // 'pending', 'sent', 'delivered', 'bounced'
``` ```
#### `getDeliveryReport(emailId: string): IDeliveryReport`
Detailed delivery information including bounce reasons and tracking data.
## Examples ## Examples
### Complete Enterprise Setup ### Complete Enterprise Setup
@@ -874,6 +1013,15 @@ Detailed delivery information including bounce reasons and tracking data.
import { DcRouter } from '@serve.zone/dcrouter'; import { DcRouter } from '@serve.zone/dcrouter';
const router = new DcRouter({ const router = new DcRouter({
// OpsServer dashboard
opsServerConfig: {
port: 3000,
admin: {
username: 'admin',
password: process.env.ADMIN_PASSWORD
}
},
// HTTP/HTTPS routing // HTTP/HTTPS routing
smartProxyConfig: { smartProxyConfig: {
routes: [ routes: [
@@ -888,7 +1036,7 @@ const router = new DcRouter({
tls: { mode: 'terminate', certificate: 'auto' } tls: { mode: 'terminate', certificate: 'auto' }
} }
}, },
// API services // API services
{ {
name: 'api', name: 'api',
@@ -899,20 +1047,9 @@ const router = new DcRouter({
targets: [{ host: '192.168.1.20', port: 8080 }], targets: [{ host: '192.168.1.20', port: 8080 }],
tls: { mode: 'terminate', certificate: 'auto' } tls: { mode: 'terminate', certificate: 'auto' }
} }
},
// Internal services
{
name: 'internal',
match: { ports: [{ from: 8000, to: 8999 }] },
action: {
type: 'forward',
targets: [{ host: '192.168.1.30', port: 'preserve' }],
security: { ipAllowList: ['192.168.0.0/16'] }
}
} }
], ],
// ACME certificate automation // ACME certificate automation
acme: { acme: {
email: 'ssl@example.com', email: 'ssl@example.com',
@@ -921,12 +1058,12 @@ const router = new DcRouter({
autoRenew: true autoRenew: true
} }
}, },
// Enterprise email system // Enterprise email system
emailConfig: { emailConfig: {
ports: [25, 587, 465], ports: [25, 587, 465],
hostname: 'mail.example.com', hostname: 'mail.example.com',
// Domain configuration // Domain configuration
domains: [ domains: [
{ {
@@ -936,28 +1073,9 @@ const router = new DcRouter({
selector: 'mail', selector: 'mail',
rotateKeys: true rotateKeys: true
} }
},
{
domain: 'notifications.example.com',
dnsMode: 'internal-dns',
rateLimits: {
outbound: { messagesPerHour: 10000 }
}
} }
], ],
// Authentication configuration
auth: {
required: true,
methods: ['PLAIN', 'LOGIN']
},
// TLS configuration
tls: {
keyPath: './certs/mail-key.pem',
certPath: './certs/mail-cert.pem'
},
// Email routing rules // Email routing rules
routes: [ routes: [
// Relay from office network // Relay from office network
@@ -967,68 +1085,55 @@ const router = new DcRouter({
match: { clientIp: '192.168.0.0/16' }, match: { clientIp: '192.168.0.0/16' },
action: { action: {
type: 'forward', type: 'forward',
forward: { forward: { host: 'internal-mail.example.com', port: 25 }
host: 'internal-mail.example.com',
port: 25
}
} }
}, },
// Transactional emails via processing // Process transactional emails
{ {
name: 'notifications', name: 'notifications',
priority: 50, priority: 50,
match: { recipients: '*@notifications.example.com' }, match: { recipients: '*@notifications.example.com' },
action: { action: {
type: 'process', type: 'process',
process: { process: { scan: true, dkim: true, queue: 'priority' }
scan: true,
dkim: true,
queue: 'priority'
}
} }
}, },
// Internal emails forwarded to Exchange
{
name: 'internal-mail',
priority: 25,
match: { recipients: '*@example.com' },
action: {
type: 'forward',
forward: {
host: 'exchange.internal.example.com',
port: 25
}
}
},
// Default reject // Default reject
{ {
name: 'default-reject', name: 'default-reject',
match: { recipients: '*' }, match: { recipients: '*' },
action: { action: {
type: 'reject', type: 'reject',
reject: { reject: { code: 550, message: 'Relay denied' }
code: 550,
message: 'Relay denied'
}
} }
} }
] ]
}, },
// RADIUS for network devices
radiusConfig: {
port: 1812,
secret: process.env.RADIUS_SECRET,
macAuth: {
enabled: true,
defaultVlan: 100,
guestVlan: 999
}
},
// DNS server for ACME challenges // DNS server for ACME challenges
dnsServerConfig: { dnsServerConfig: {
port: 53, port: 53,
authoritative: true authoritative: true
}, },
// Cloudflare DNS challenges // Cloudflare DNS challenges
dnsChallenge: { dnsChallenge: {
cloudflareApiKey: process.env.CLOUDFLARE_API_KEY cloudflareApiKey: process.env.CLOUDFLARE_API_KEY
}, },
// Persistent storage // Persistent storage
storage: { storage: {
fsPath: '/var/lib/dcrouter/data' fsPath: '/var/lib/dcrouter/data'
@@ -1047,33 +1152,33 @@ setInterval(() => {
}, 60000); }, 60000);
``` ```
### Email Template System ## Testing
```typescript ### Comprehensive Test Suite
import { EmailService, TemplateManager } from '@serve.zone/dcrouter';
// Setup email templates DcRouter includes a comprehensive test suite with 195 test files covering all aspects of the system:
const templateManager = new TemplateManager();
templateManager.addTemplate('welcome', {
subject: 'Welcome to {{company}}!',
html: `
<h1>Welcome {{name}}!</h1>
<p>Thank you for joining {{company}}.</p>
<p>Your account: {{email}}</p>
`,
text: 'Welcome {{name}}! Thank you for joining {{company}}.'
});
// Send templated email #### SMTP Protocol Tests
const emailService = new EmailService(router); - **Commands**: EHLO, HELO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT, VRFY, EXPN, HELP
await emailService.sendTemplatedEmail('welcome', { - **Extensions**: SIZE, PIPELINING, STARTTLS
to: 'user@example.com', - **Connection Management**: TLS/plain connections, timeouts, limits, rejection handling
templateData: { - **Error Handling**: Syntax errors, invalid sequences, temporary/permanent failures
name: 'John Doe', - **Email Processing**: Basic sending, multiple recipients, large emails, invalid addresses
company: 'Example Corp', - **Security**: Authentication, rate limiting
email: 'user@example.com' - **Performance**: Throughput testing
} - **Edge Cases**: Very large emails, special characters
});
#### Running Tests
```bash
# Run all tests
pnpm test
# Run specific test categories
tsx test/suite/smtpserver_commands/test.cmd-01.ehlo-command.ts
# Run with verbose output
tstest test/test.integration.ts --verbose
``` ```
## Troubleshooting ## Troubleshooting
@@ -1109,25 +1214,6 @@ dig TXT your-domain.com
- Test CIDR notation: `192.168.0.0/16` includes all 192.168.x.x addresses - Test CIDR notation: `192.168.0.0/16` includes all 192.168.x.x addresses
- Confirm authentication state matches your expectations - Confirm authentication state matches your expectations
**Common Route Patterns**
```typescript
// Debug route to log all traffic
{
name: 'debug-all',
priority: 1000,
match: { recipients: '*' },
action: { type: 'process', process: { scan: false } }
}
// Catch-all reject (should be lowest priority)
{
name: 'default-reject',
priority: 0,
match: { recipients: '*' },
action: { type: 'reject', reject: { code: 550, message: 'No route' } }
}
```
#### DNS Issues #### DNS Issues
```bash ```bash
# Test DNS server # Test DNS server
@@ -1137,32 +1223,6 @@ dig @your-server.com your-domain.com
dig your-domain.com @8.8.8.8 dig your-domain.com @8.8.8.8
``` ```
### Logging and Monitoring
```typescript
import { SmartLog } from '@push.rocks/smartlog';
// Configure logging
const logger = new SmartLog({
level: 'info',
transport: 'console'
});
// Monitor email events
router.emailServer.on('emailReceived', (email) => {
logger.log('info', `Email received: ${email.from} -> ${email.to}`);
});
router.emailServer.on('emailSent', (result) => {
logger.log('info', `Email sent: ${result.messageId} (${result.status})`);
});
// Monitor proxy events
router.smartProxy.on('connectionEstablished', (connection) => {
logger.log('info', `Connection: ${connection.clientIp} -> ${connection.target}`);
});
```
### Performance Tuning ### Performance Tuning
```typescript ```typescript
@@ -1170,14 +1230,14 @@ const performanceConfig = {
// Connection limits // Connection limits
maxConnections: 1000, maxConnections: 1000,
connectionTimeout: 30000, connectionTimeout: 30000,
// Email queue settings // Email queue settings
emailQueue: { emailQueue: {
concurrency: 10, concurrency: 10,
maxRetries: 3, maxRetries: 3,
retryDelay: 300000 retryDelay: 300000
}, },
// Cache settings // Cache settings
cache: { cache: {
ipReputation: { ttl: 3600000 }, // 1 hour ipReputation: { ttl: 3600000 }, // 1 hour
@@ -1187,60 +1247,23 @@ const performanceConfig = {
}; };
``` ```
## License ## License and Legal Information
MIT License - see LICENSE file for details. This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
## Testing **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.
### Comprehensive Test Suite ### Trademarks
DcRouter includes a comprehensive test suite covering all aspects of the system: 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.
#### SMTP Protocol Tests 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.
- **Commands**: EHLO, HELO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT, VRFY, EXPN, HELP
- **Extensions**: SIZE, PIPELINING, STARTTLS
- **Connection Management**: TLS/plain connections, timeouts, limits, rejection handling
- **Error Handling**: Syntax errors, invalid sequences, temporary/permanent failures
- **Email Processing**: Basic sending, multiple recipients, large emails, invalid addresses
- **Security**: Authentication, rate limiting
- **Performance**: Throughput testing
- **Edge Cases**: Very large emails, special characters
#### Storage and Configuration Tests ### Company Information
- **Storage Manager**: All backend types (filesystem, custom, memory)
- **Integration**: Component storage usage and persistence
- **DNS Validation**: All DNS modes (forward, internal, external)
- **DNS Mode Switching**: Dynamic configuration changes
- **Data Migration**: Moving data between storage backends
#### Running Tests Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
```bash For any legal inquiries or further information, please contact us via email at hello@task.vc.
# Run all tests
pnpm test
# Run specific test categories 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.
tsx test/suite/commands/test.ehlo-command.ts
tsx test/suite/connection/test.tls-connection.ts
tsx test/suite/email-processing/test.basic-email.ts
# Run with verbose output
tstest test/suite/security/test.authentication.ts --verbose
```
### Test Infrastructure
The test suite uses a self-contained pattern where each test:
1. Starts its own SMTP server instance
2. Runs comprehensive test scenarios
3. Cleans up all resources
4. Provides detailed logging for debugging
This ensures tests are isolated, reliable, and can run in parallel.
## Support
- Documentation: [https://docs.serve.zone/dcrouter](https://docs.serve.zone/dcrouter)
- Issues: [https://github.com/serve-zone/dcrouter/issues](https://github.com/serve-zone/dcrouter/issues)
- Community: [https://community.serve.zone](https://community.serve.zone)

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/dcrouter', name: '@serve.zone/dcrouter',
version: '3.0.0', version: '3.1.0',
description: 'A multifaceted routing service handling mail and SMS delivery functions.' description: 'A multifaceted routing service handling mail and SMS delivery functions.'
} }

175
ts_interfaces/readme.md Normal file
View File

@@ -0,0 +1,175 @@
# @serve.zone/dcrouter-interfaces
TypeScript interfaces and type definitions for the DCRouter OpsServer API. 📡
This module provides strongly-typed interfaces for communicating with the DCRouter OpsServer via TypedRequest. Use these interfaces for type-safe API interactions in your frontend applications or integration code.
## 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
npm install @serve.zone/dcrouter-interfaces --save
# or
pnpm add @serve.zone/dcrouter-interfaces
```
## Usage
```typescript
import { data, requests } from '@serve.zone/dcrouter-interfaces';
// Use data interfaces for type definitions
const identity: data.IIdentity = {
jwt: 'your-jwt-token',
userId: 'user-123',
name: 'Admin User',
expiresAt: Date.now() + 3600000,
role: 'admin'
};
// Use request interfaces for API calls
const statsRequest: requests.IReq_GetServerStatistics = {
method: 'getServerStatistics',
request: {
identity,
includeHistory: true,
timeRange: '24h'
},
response: null // Will be populated by the response
};
```
## Module Structure
### Data Interfaces (`data`)
Core data types used throughout the DCRouter system:
#### `IIdentity`
Authentication identity for API requests:
```typescript
interface IIdentity {
jwt: string; // JWT token for authentication
userId: string; // Unique user identifier
name: string; // Display name
expiresAt: number; // Token expiration timestamp
role?: string; // User role (e.g., 'admin')
type?: string; // Identity type
}
```
#### Statistics Interfaces
- `IServerStats` - Overall server statistics
- `IEmailStats` - Email throughput and delivery metrics
- `IDnsStats` - DNS query statistics
- `IRateLimitInfo` - Rate limiting status
- `ISecurityMetrics` - Security event metrics
- `IConnectionInfo` - Active connection details
- `IQueueStatus` - Email queue status
- `IHealthStatus` - System health information
### Request Interfaces (`requests`)
TypedRequest interfaces for the OpsServer API:
#### Statistics Requests
| Interface | Method | Description |
|-----------|--------|-------------|
| `IReq_GetServerStatistics` | `getServerStatistics` | Get overall server stats |
| `IReq_GetEmailStatistics` | `getEmailStatistics` | Get email throughput stats |
| `IReq_GetDnsStatistics` | `getDnsStatistics` | Get DNS query stats |
| `IReq_GetRateLimitStatus` | `getRateLimitStatus` | Check rate limit status |
| `IReq_GetSecurityMetrics` | `getSecurityMetrics` | Get security event metrics |
| `IReq_GetActiveConnections` | `getActiveConnections` | List active connections |
| `IReq_GetQueueStatus` | `getQueueStatus` | Get email queue status |
| `IReq_GetHealthStatus` | `getHealthStatus` | System health check |
#### Admin Requests
| Interface | Method | Description |
|-----------|--------|-------------|
| `IReq_AdminLogin` | `adminLogin` | Authenticate as admin |
| `IReq_AdminLogout` | `adminLogout` | End admin session |
| `IReq_VerifyIdentity` | `verifyIdentity` | Verify JWT token |
#### Configuration Requests
| Interface | Method | Description |
|-----------|--------|-------------|
| `IReq_GetConfiguration` | `getConfiguration` | Get current config |
| `IReq_UpdateConfiguration` | `updateConfiguration` | Update system config |
#### Log Requests
| Interface | Method | Description |
|-----------|--------|-------------|
| `IReq_GetLogs` | `getLogs` | Retrieve system logs |
#### RADIUS Requests
| Interface | Method | Description |
|-----------|--------|-------------|
| `IReq_GetRadiusSessions` | `getRadiusSessions` | List RADIUS sessions |
| `IReq_GetRadiusClients` | `getRadiusClients` | List RADIUS clients |
#### Email Operations
| Interface | Method | Description |
|-----------|--------|-------------|
| `IReq_GetEmailQueues` | `getEmailQueues` | Get email queue details |
| `IReq_RetryEmail` | `retryEmail` | Retry failed email |
## Example: Complete API Integration
```typescript
import * as typedrequest from '@api.global/typedrequest';
import { data, requests } from '@serve.zone/dcrouter-interfaces';
// Create typed request client
const client = new typedrequest.TypedRequest<requests.IReq_AdminLogin>(
'https://your-dcrouter:3000/typedrequest',
'adminLogin'
);
// Login to get identity
const loginResponse = await client.fire({
username: 'admin',
password: 'your-password'
});
const identity = loginResponse.identity;
// Now use identity for authenticated requests
const statsClient = new typedrequest.TypedRequest<requests.IReq_GetServerStatistics>(
'https://your-dcrouter:3000/typedrequest',
'getServerStatistics'
);
const stats = await statsClient.fire({
identity,
includeHistory: true,
timeRange: '24h'
});
console.log('Server stats:', stats.stats);
console.log('History:', stats.history);
```
## 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.

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/dcrouter', name: '@serve.zone/dcrouter',
version: '3.0.0', version: '3.1.0',
description: 'A multifaceted routing service handling mail and SMS delivery functions.' description: 'A multifaceted routing service handling mail and SMS delivery functions.'
} }

View File

@@ -100,10 +100,19 @@ export const configStatePart = await appState.getStatePart<IConfigState>(
} }
); );
// Determine initial view from URL path
const getInitialView = (): string => {
const path = typeof window !== 'undefined' ? window.location.pathname : '/';
const validViews = ['overview', 'network', 'emails', 'logs', 'configuration', 'security'];
const segments = path.split('/').filter(Boolean);
const view = segments[0];
return validViews.includes(view) ? view : 'overview';
};
export const uiStatePart = await appState.getStatePart<IUiState>( export const uiStatePart = await appState.getStatePart<IUiState>(
'ui', 'ui',
{ {
activeView: 'overview', activeView: getInitialView(),
sidebarCollapsed: false, sidebarCollapsed: false,
autoRefresh: true, autoRefresh: true,
refreshInterval: 1000, // 1 second refreshInterval: 1000, // 1 second

View File

@@ -63,6 +63,14 @@ export class OpsDashboard extends DeesElement {
}, },
]; ];
/**
* 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.
*/
private get currentViewTab() {
return this.viewTabs.find(t => t.name.toLowerCase() === this.uiState.activeView) || this.viewTabs[0];
}
constructor() { constructor() {
super(); super();
document.title = 'DCRouter OpsServer'; document.title = 'DCRouter OpsServer';
@@ -141,12 +149,13 @@ export class OpsDashboard extends DeesElement {
public render(): TemplateResult { public render(): TemplateResult {
return html` return html`
<div class="maincontainer"> <div class="maincontainer">
<dees-simple-login <dees-simple-login
name="DCRouter OpsServer" name="DCRouter OpsServer"
> >
<dees-simple-appdash <dees-simple-appdash
name="DCRouter OpsServer" name="DCRouter OpsServer"
.viewTabs=${this.viewTabs} .viewTabs=${this.viewTabs}
.selectedView=${this.currentViewTab}
> >
</dees-simple-appdash> </dees-simple-appdash>
</dees-simple-login> </dees-simple-login>

231
ts_web/readme.md Normal file
View File

@@ -0,0 +1,231 @@
# @serve.zone/dcrouter-web
Web-based Operations Dashboard for DCRouter. 🖥️
This module provides the frontend web application for the DCRouter OpsServer, built with modern web components using the `@design.estate/dees-element` library. It offers a comprehensive dashboard for monitoring and managing your DCRouter instance in real-time.
## 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.
## Features
### 🔐 **Secure Authentication**
- JWT-based authentication flow
- Automatic session management
- Secure login with username/password
### 📊 **Overview Dashboard**
- Real-time server statistics
- Connection monitoring
- Email throughput visualization
- DNS query metrics
- RADIUS session tracking
### 🌐 **Network View**
- Active connection monitoring
- SmartProxy route visualization
- TCP/HTTP connection details
- TLS certificate status
### 📧 **Email Management**
- Email queue monitoring
- Delivery status tracking
- Bounce management
- DKIM key status
- Domain configuration overview
### 📜 **Log Viewer**
- Real-time log streaming
- Log level filtering (error, warning, info, debug)
- Search and filter capabilities
- Time-range selection
### ⚙️ **Configuration**
- View current system configuration
- Update settings via TypedRequest API
- Route management
- Domain management
### 🛡️ **Security Dashboard**
- IP reputation monitoring
- Rate limit status
- Blocked connections
- Security event tracking
## Architecture
The web application is built using:
- **@design.estate/dees-element** - Modern web component framework with lit-element
- **@design.estate/dees-catalog** - Pre-built UI components (appdash, login, forms)
- **@push.rocks/smartstate** - Reactive state management
- **@api.global/typedrequest** - Type-safe API communication
### Component Structure
```
ts_web/
├── index.ts # Application entry point
├── plugins.ts # External dependency imports
├── router.ts # Client-side routing
├── appstate.ts # State management
└── elements/
├── index.ts # Component barrel export
├── ops-dashboard.ts # Main dashboard container
├── ops-view-overview.ts # Overview statistics
├── ops-view-network.ts # Network monitoring
├── ops-view-emails.ts # Email management
├── ops-view-logs.ts # Log viewer
├── ops-view-config.ts # Configuration
├── ops-view-security.ts # Security dashboard
└── shared/
├── index.ts # Shared component exports
├── css.ts # Shared styles
└── ops-sectionheading.ts # Section heading component
```
## State Management
The application uses `@push.rocks/smartstate` for reactive state management:
### State Parts
```typescript
// Login state
interface ILoginState {
identity: IIdentity | null;
isLoggedIn: boolean;
}
// UI state
interface IUiState {
activeView: string;
sidebarCollapsed: boolean;
autoRefresh: boolean;
refreshInterval: number;
theme: 'light' | 'dark';
}
// Statistics state
interface IStatsState {
server: IServerStats;
email: IEmailStats;
dns: IDnsStats;
connections: IConnectionInfo[];
health: IHealthStatus;
}
// Configuration state
interface IConfigState {
configuration: IDcRouterConfig;
loading: boolean;
}
```
### Actions
- `loginAction` - Authenticate user
- `logoutAction` - End session
- `fetchAllStatsAction` - Refresh all statistics
- `fetchConfigurationAction` - Load configuration
- `updateConfigurationAction` - Save configuration changes
## Client-Side Routing
The application includes client-side routing for deep linking:
```typescript
// Routes
/overview Overview dashboard
/network Network monitoring
/emails Email management
/logs Log viewer
/configuration System configuration
/security Security dashboard
```
URL state is synchronized with the UI, allowing bookmarking and sharing of specific views.
## Building
The web application is built using `@git.zone/tsbundle`:
```bash
# Build the bundle
pnpm run bundle
# Watch for development
pnpm run watch
```
The bundle is output to `./dist_serve/bundle.js` and served by the OpsServer.
## Development
### Local Development
```typescript
// Start DCRouter with OpsServer enabled
import { DcRouter } from '@serve.zone/dcrouter';
const router = new DcRouter({
opsServerConfig: {
port: 3000,
admin: {
username: 'admin',
password: 'dev-password'
}
}
});
await router.start();
// Dashboard at http://localhost:3000
```
### Adding New Views
1. Create a new view component in `elements/`:
```typescript
import { DeesElement, customElement, html } from '@design.estate/dees-element';
@customElement('ops-view-myview')
export class OpsViewMyView extends DeesElement {
public render() {
return html`<div>My custom view</div>`;
}
}
```
2. Import and add to `ops-dashboard.ts`:
```typescript
import { OpsViewMyView } from './ops-view-myview.js';
private viewTabs = [
// ... existing tabs
{ name: 'MyView', element: OpsViewMyView }
];
```
3. Add route in `router.ts` if needed.
## 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.