Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 89b9d01628 | |||
| ed3964e892 | |||
| baab152fd3 | |||
| 9baf09ff61 | |||
| 71f23302d3 | |||
| ecbaab3000 | |||
| 8cb1f3c12d | |||
| c7d7f92759 | |||
| 02e1b9231f | |||
| 4ec4dd2bdb |
6
.playwright-mcp/console-2026-03-02T19-29-32-708Z.log
Normal file
6
.playwright-mcp/console-2026-03-02T19-29-32-708Z.log
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[ 95ms] TypeError: Cannot read properties of null (reading 'appendChild')
|
||||||
|
at TypedserverStatusPill.show (http://localhost:3000/typedserver/devtools:17607:21)
|
||||||
|
at TypedserverStatusPill.updateStatus (http://localhost:3000/typedserver/devtools:17567:10)
|
||||||
|
at ReloadChecker.checkReload (http://localhost:3000/typedserver/devtools:18137:23)
|
||||||
|
at async ReloadChecker.start (http://localhost:3000/typedserver/devtools:18224:9)
|
||||||
|
[ 992ms] [ERROR] Error while trying to use the following icon from the Manifest: http://localhost:3000/assetbroker/manifest/icon-144x144.png (Download error or resource isn't a valid image) @ http://localhost:3000/overview:0
|
||||||
5
.playwright-mcp/console-2026-03-02T19-30-09-759Z.log
Normal file
5
.playwright-mcp/console-2026-03-02T19-30-09-759Z.log
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[ 329ms] [ERROR] method: >>getMergedRoutes<< got an ERROR: "unauthorized" with data undefined @ http://localhost:3000/bundle.js:13
|
||||||
|
[ 727ms] [ERROR] Error while trying to use the following icon from the Manifest: http://localhost:3000/assetbroker/manifest/icon-144x144.png (Download error or resource isn't a valid image) @ http://localhost:3000/routes:0
|
||||||
|
[ 260513ms] [ERROR] method: >>adminLoginWithUsernameAndPassword<< got an ERROR: "login failed" with data undefined @ http://localhost:3000/bundle.js:13
|
||||||
|
[ 260514ms] [ERROR] Login failed: Ns @ http://localhost:3000/bundle.js:38066
|
||||||
|
[ 260518ms] [WARNING] FontAwesome icon not found: circle-xmark @ http://localhost:3000/bundle.js:1203
|
||||||
3
.playwright-mcp/console-2026-03-02T19-34-55-496Z.log
Normal file
3
.playwright-mcp/console-2026-03-02T19-34-55-496Z.log
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[ 397ms] [ERROR] method: >>getMergedRoutes<< got an ERROR: "unauthorized" with data undefined @ http://localhost:3000/bundle.js:13
|
||||||
|
[ 657ms] [ERROR] Error while trying to use the following icon from the Manifest: http://localhost:3000/assetbroker/manifest/icon-144x144.png (Download error or resource isn't a valid image) @ http://localhost:3000/routes:0
|
||||||
|
[ 24180ms] [WARNING] FontAwesome icon not found: circle-check @ http://localhost:3000/bundle.js:1203
|
||||||
BIN
.playwright-mcp/page-2026-03-02T19-32-32-890Z.png
Normal file
BIN
.playwright-mcp/page-2026-03-02T19-32-32-890Z.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
.playwright-mcp/page-2026-03-02T19-33-32-637Z.png
Normal file
BIN
.playwright-mcp/page-2026-03-02T19-33-32-637Z.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
38
changelog.md
38
changelog.md
@@ -1,5 +1,43 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-03-03 - 11.0.0 - BREAKING CHANGE(opsserver)
|
||||||
|
Require authentication for OpsServer endpoints, split handlers into authenticated view/admin routers, and make identity required on many TypedRequest interfaces
|
||||||
|
|
||||||
|
- Added viewRouter and adminRouter to OpsServer and wired middleware to enforce identity/admin checks (requireValidIdentity, requireAdminIdentity).
|
||||||
|
- Moved handlers to appropriate routers (viewRouter for read endpoints, adminRouter for write/admin endpoints) instead of registering on the unauthenticated main typedrouter.
|
||||||
|
- Made identity a required field on numerous ts_interfaces request types (breaking change to request typings).
|
||||||
|
- Refactored ApiTokenHandler to register directly on adminRouter and use dataArg.identity.userId (no per-handler admin checks needed thanks to middleware).
|
||||||
|
- Updated tests: added admin login to obtain identity, adjusted protected endpoint tests to expect rejection when unauthenticated, and adapted other tests to pass identity where required.
|
||||||
|
- Added IReq_GetNetworkStats request/response typings to ts_interfaces/requests/stats.ts.
|
||||||
|
- Bumped dependencies: @api.global/typedrequest ^3.3.0 and @api.global/typedserver ^8.4.2.
|
||||||
|
|
||||||
|
## 2026-03-03 - 10.1.9 - fix(deps)
|
||||||
|
bump @push.rocks/smartproxy to ^25.9.1
|
||||||
|
|
||||||
|
- Updated package.json dependency @push.rocks/smartproxy from ^25.9.0 to ^25.9.1
|
||||||
|
- No other code changes; current package version is 10.1.8, recommend a patch release
|
||||||
|
|
||||||
|
## 2026-03-03 - 10.1.8 - fix(deps)
|
||||||
|
bump dependencies: @push.rocks/smartmetrics to ^3.0.2, @push.rocks/smartproxy to ^25.9.0, @serve.zone/remoteingress to ^4.4.0
|
||||||
|
|
||||||
|
- @push.rocks/smartmetrics: 3.0.1 -> 3.0.2 (patch)
|
||||||
|
- @push.rocks/smartproxy: 25.8.5 -> 25.9.0 (minor)
|
||||||
|
- @serve.zone/remoteingress: 4.3.0 -> 4.4.0 (minor)
|
||||||
|
|
||||||
|
## 2026-03-03 - 10.1.7 - fix(ops-view-apitokens)
|
||||||
|
use correct lucide icon name for roll/rotate actions in API tokens view
|
||||||
|
|
||||||
|
- Updated iconName from 'lucide:rotate-cw' to 'lucide:rotateCw' in ts_web/elements/ops-view-apitokens.ts (two occurrences) to match lucide icon naming and ensure icons render correctly
|
||||||
|
- Non-functional UI fix; no API or behavior changes
|
||||||
|
|
||||||
|
## 2026-03-02 - 10.1.6 - fix(ts_web)
|
||||||
|
use actionContext for dispatches in web state actions and bump @push.rocks/smartstate to ^2.2.0
|
||||||
|
|
||||||
|
- Action handlers in ts_web/appstate.ts now accept an actionContext parameter and call await actionContext.dispatch(...) instead of using statePartArg.dispatchAction(...).
|
||||||
|
- Handlers return the awaited dispatch result (ensuring callers receive refreshed state) instead of returning the previous statePartArg.getState().
|
||||||
|
- Dependency bumped in package.json: @push.rocks/smartstate from ^2.1.1 to ^2.2.0.
|
||||||
|
- Playwright artifacts (logs and page screenshots) were added under .playwright-mcp.
|
||||||
|
|
||||||
## 2026-03-02 - 10.1.5 - fix(monitoring)
|
## 2026-03-02 - 10.1.5 - fix(monitoring)
|
||||||
use a per-second ring buffer for DNS query metrics, improve DNS logging rate limiting and security event aggregation, and bump smartmta dependency
|
use a per-second ring buffer for DNS query metrics, improve DNS logging rate limiting and security event aggregation, and bump smartmta dependency
|
||||||
|
|
||||||
|
|||||||
14
package.json
14
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@serve.zone/dcrouter",
|
"name": "@serve.zone/dcrouter",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "10.1.5",
|
"version": "11.0.0",
|
||||||
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
|
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
@@ -27,9 +27,9 @@
|
|||||||
"@types/node": "^25.3.3"
|
"@types/node": "^25.3.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@api.global/typedrequest": "^3.2.7",
|
"@api.global/typedrequest": "^3.3.0",
|
||||||
"@api.global/typedrequest-interfaces": "^3.0.19",
|
"@api.global/typedrequest-interfaces": "^3.0.19",
|
||||||
"@api.global/typedserver": "^8.4.0",
|
"@api.global/typedserver": "^8.4.2",
|
||||||
"@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.43.3",
|
"@design.estate/dees-catalog": "^3.43.3",
|
||||||
@@ -43,21 +43,21 @@
|
|||||||
"@push.rocks/smartguard": "^3.1.0",
|
"@push.rocks/smartguard": "^3.1.0",
|
||||||
"@push.rocks/smartjwt": "^2.2.1",
|
"@push.rocks/smartjwt": "^2.2.1",
|
||||||
"@push.rocks/smartlog": "^3.2.1",
|
"@push.rocks/smartlog": "^3.2.1",
|
||||||
"@push.rocks/smartmetrics": "^3.0.1",
|
"@push.rocks/smartmetrics": "^3.0.2",
|
||||||
"@push.rocks/smartmongo": "^5.1.0",
|
"@push.rocks/smartmongo": "^5.1.0",
|
||||||
"@push.rocks/smartmta": "^5.3.1",
|
"@push.rocks/smartmta": "^5.3.1",
|
||||||
"@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.2.3",
|
"@push.rocks/smartpromise": "^4.2.3",
|
||||||
"@push.rocks/smartproxy": "^25.8.5",
|
"@push.rocks/smartproxy": "^25.9.1",
|
||||||
"@push.rocks/smartradius": "^1.1.1",
|
"@push.rocks/smartradius": "^1.1.1",
|
||||||
"@push.rocks/smartrequest": "^5.0.1",
|
"@push.rocks/smartrequest": "^5.0.1",
|
||||||
"@push.rocks/smartrx": "^3.0.10",
|
"@push.rocks/smartrx": "^3.0.10",
|
||||||
"@push.rocks/smartstate": "^2.1.1",
|
"@push.rocks/smartstate": "^2.2.0",
|
||||||
"@push.rocks/smartunique": "^3.0.9",
|
"@push.rocks/smartunique": "^3.0.9",
|
||||||
"@serve.zone/catalog": "^2.5.0",
|
"@serve.zone/catalog": "^2.5.0",
|
||||||
"@serve.zone/interfaces": "^5.3.0",
|
"@serve.zone/interfaces": "^5.3.0",
|
||||||
"@serve.zone/remoteingress": "^4.3.0",
|
"@serve.zone/remoteingress": "^4.4.0",
|
||||||
"@tsclass/tsclass": "^9.3.0",
|
"@tsclass/tsclass": "^9.3.0",
|
||||||
"lru-cache": "^11.2.6",
|
"lru-cache": "^11.2.6",
|
||||||
"uuid": "^13.0.0"
|
"uuid": "^13.0.0"
|
||||||
|
|||||||
109
pnpm-lock.yaml
generated
109
pnpm-lock.yaml
generated
@@ -9,14 +9,14 @@ importers:
|
|||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest':
|
'@api.global/typedrequest':
|
||||||
specifier: ^3.2.7
|
specifier: ^3.3.0
|
||||||
version: 3.2.7
|
version: 3.3.0
|
||||||
'@api.global/typedrequest-interfaces':
|
'@api.global/typedrequest-interfaces':
|
||||||
specifier: ^3.0.19
|
specifier: ^3.0.19
|
||||||
version: 3.0.19
|
version: 3.0.19
|
||||||
'@api.global/typedserver':
|
'@api.global/typedserver':
|
||||||
specifier: ^8.4.0
|
specifier: ^8.4.2
|
||||||
version: 8.4.0(@tiptap/pm@2.27.2)
|
version: 8.4.2(@tiptap/pm@2.27.2)
|
||||||
'@api.global/typedsocket':
|
'@api.global/typedsocket':
|
||||||
specifier: ^4.1.2
|
specifier: ^4.1.2
|
||||||
version: 4.1.2(@push.rocks/smartserve@2.0.1)
|
version: 4.1.2(@push.rocks/smartserve@2.0.1)
|
||||||
@@ -57,8 +57,8 @@ importers:
|
|||||||
specifier: ^3.2.1
|
specifier: ^3.2.1
|
||||||
version: 3.2.1
|
version: 3.2.1
|
||||||
'@push.rocks/smartmetrics':
|
'@push.rocks/smartmetrics':
|
||||||
specifier: ^3.0.1
|
specifier: ^3.0.2
|
||||||
version: 3.0.1
|
version: 3.0.2
|
||||||
'@push.rocks/smartmongo':
|
'@push.rocks/smartmongo':
|
||||||
specifier: ^5.1.0
|
specifier: ^5.1.0
|
||||||
version: 5.1.0(socks@2.8.7)
|
version: 5.1.0(socks@2.8.7)
|
||||||
@@ -75,8 +75,8 @@ importers:
|
|||||||
specifier: ^4.2.3
|
specifier: ^4.2.3
|
||||||
version: 4.2.3
|
version: 4.2.3
|
||||||
'@push.rocks/smartproxy':
|
'@push.rocks/smartproxy':
|
||||||
specifier: ^25.8.5
|
specifier: ^25.9.1
|
||||||
version: 25.8.5
|
version: 25.9.1
|
||||||
'@push.rocks/smartradius':
|
'@push.rocks/smartradius':
|
||||||
specifier: ^1.1.1
|
specifier: ^1.1.1
|
||||||
version: 1.1.1
|
version: 1.1.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.1.1
|
specifier: ^2.2.0
|
||||||
version: 2.1.1
|
version: 2.2.0
|
||||||
'@push.rocks/smartunique':
|
'@push.rocks/smartunique':
|
||||||
specifier: ^3.0.9
|
specifier: ^3.0.9
|
||||||
version: 3.0.9
|
version: 3.0.9
|
||||||
@@ -99,8 +99,8 @@ importers:
|
|||||||
specifier: ^5.3.0
|
specifier: ^5.3.0
|
||||||
version: 5.3.0
|
version: 5.3.0
|
||||||
'@serve.zone/remoteingress':
|
'@serve.zone/remoteingress':
|
||||||
specifier: ^4.3.0
|
specifier: ^4.4.0
|
||||||
version: 4.3.0
|
version: 4.4.0
|
||||||
'@tsclass/tsclass':
|
'@tsclass/tsclass':
|
||||||
specifier: ^9.3.0
|
specifier: ^9.3.0
|
||||||
version: 9.3.0
|
version: 9.3.0
|
||||||
@@ -138,14 +138,14 @@ packages:
|
|||||||
'@api.global/typedrequest-interfaces@3.0.19':
|
'@api.global/typedrequest-interfaces@3.0.19':
|
||||||
resolution: {integrity: sha512-uuHUXJeOy/inWSDrwD0Cwax2rovpxYllDhM2RWh+6mVpQuNmZ3uw6IVg6dA2G1rOe24Ebs+Y9SzEogo+jYN7vw==}
|
resolution: {integrity: sha512-uuHUXJeOy/inWSDrwD0Cwax2rovpxYllDhM2RWh+6mVpQuNmZ3uw6IVg6dA2G1rOe24Ebs+Y9SzEogo+jYN7vw==}
|
||||||
|
|
||||||
'@api.global/typedrequest@3.2.7':
|
'@api.global/typedrequest@3.3.0':
|
||||||
resolution: {integrity: sha512-9CC8EojPDraKlwWK3ZjM8/wJ9jguY/kc+pCgcd61epHFXTIKC8jYts3vKPmEkBPno5Ejn3JZgqp/GRzplCC51w==}
|
resolution: {integrity: sha512-Jwobqla+9k2IBG0duwrCFtc6GU6wsvHS3f0gJJsxTrpapylBW1YSF7NnGHPGs7F9hbATsO6IoUBpR2ScoKyGJA==}
|
||||||
|
|
||||||
'@api.global/typedserver@3.0.80':
|
'@api.global/typedserver@3.0.80':
|
||||||
resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==}
|
resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==}
|
||||||
|
|
||||||
'@api.global/typedserver@8.4.0':
|
'@api.global/typedserver@8.4.2':
|
||||||
resolution: {integrity: sha512-qOa5jUwiuHEoY1ZuLZiuU1unPl5JNd99Vv+hNAwgEIgAZd4TTy/mjdTp7lyviBzkGf2pROeCmAbDJJF8YQFCSA==}
|
resolution: {integrity: sha512-eESOcWvrbqkshR4s4OeTX1AK74bNCeGgiRebKgjxIzJ+b0+rkPQyn2DOaMtyXjFZRNgRHyytLm5Iqj5fdazeqw==}
|
||||||
|
|
||||||
'@api.global/typedsocket@3.1.1':
|
'@api.global/typedsocket@3.1.1':
|
||||||
resolution: {integrity: sha512-Wkz3NlhmfdZMKqXXI2c2dMtGGmSmhdOegZiziL+9b2mqPYdc7Gd8AZRdEOKvbSoIvc9G22/5BEadIWHrfq66TA==}
|
resolution: {integrity: sha512-Wkz3NlhmfdZMKqXXI2c2dMtGGmSmhdOegZiziL+9b2mqPYdc7Gd8AZRdEOKvbSoIvc9G22/5BEadIWHrfq66TA==}
|
||||||
@@ -984,8 +984,8 @@ packages:
|
|||||||
'@push.rocks/smartmatch@2.0.0':
|
'@push.rocks/smartmatch@2.0.0':
|
||||||
resolution: {integrity: sha512-MBzP++1yNIBeox71X6VxpIgZ8m4bXnJpZJ4nWVH6IWpmO38MXTu4X0QF8tQnyT4LFcwvc9iiWaD15cstHa7Mmw==}
|
resolution: {integrity: sha512-MBzP++1yNIBeox71X6VxpIgZ8m4bXnJpZJ4nWVH6IWpmO38MXTu4X0QF8tQnyT4LFcwvc9iiWaD15cstHa7Mmw==}
|
||||||
|
|
||||||
'@push.rocks/smartmetrics@3.0.1':
|
'@push.rocks/smartmetrics@3.0.2':
|
||||||
resolution: {integrity: sha512-wdc9v8F0dQXwraAVCZjGvt2lnGpbVYHWzER9OFR+u+ultMq7aLjUevxSpkS8BkhBMLTuNMCCWIqyAzaCqHzFgQ==}
|
resolution: {integrity: sha512-bW60TrdCubsZwsYK1+lE9y+OoXN8MfB7bhSASlTKtwhExdCbjXYXnSt9W7zerD7HbsUNOsvejIjX9q4oju+P2g==}
|
||||||
|
|
||||||
'@push.rocks/smartmime@1.0.6':
|
'@push.rocks/smartmime@1.0.6':
|
||||||
resolution: {integrity: sha512-PHd+I4UcsnOATNg8wjDsSAmmJ4CwQFrQCNzd0HSJMs4ZpiK3Ya91almd6GLpDPU370U4HFh4FaPF4eEAI6vkJQ==}
|
resolution: {integrity: sha512-PHd+I4UcsnOATNg8wjDsSAmmJ4CwQFrQCNzd0HSJMs4ZpiK3Ya91almd6GLpDPU370U4HFh4FaPF4eEAI6vkJQ==}
|
||||||
@@ -1038,8 +1038,8 @@ packages:
|
|||||||
'@push.rocks/smartpromise@4.2.3':
|
'@push.rocks/smartpromise@4.2.3':
|
||||||
resolution: {integrity: sha512-Ycg/TJR+tMt+S3wSFurOpEoW6nXv12QBtKXgBcjMZ4RsdO28geN46U09osPn9N9WuwQy1PkmTV5J/V4F9U8qEw==}
|
resolution: {integrity: sha512-Ycg/TJR+tMt+S3wSFurOpEoW6nXv12QBtKXgBcjMZ4RsdO28geN46U09osPn9N9WuwQy1PkmTV5J/V4F9U8qEw==}
|
||||||
|
|
||||||
'@push.rocks/smartproxy@25.8.5':
|
'@push.rocks/smartproxy@25.9.1':
|
||||||
resolution: {integrity: sha512-oLmV+Bq7sSgQP9McTao/imb6Xb62QM7wlTFt5kNynrS5WK2wAe8cEjDKOcyu8N/WmzNCEClT5f/0xAtI6JxtkA==}
|
resolution: {integrity: sha512-X9Yc74CwwvxUay/WDdomRL48vkQyb/kT/QZ4r+AyUUJV2tlt0rQxhbegv9C9kkjrVNsflQWjrAKseh0GB4hAfA==}
|
||||||
|
|
||||||
'@push.rocks/smartpuppeteer@2.0.5':
|
'@push.rocks/smartpuppeteer@2.0.5':
|
||||||
resolution: {integrity: sha512-yK/qSeWVHIGWRp3c8S5tfdGP6WCKllZC4DR8d8CQlEjszOSBmHtlTdyyqOMBZ/BA4kd+eU5f3A1r4K2tGYty1g==}
|
resolution: {integrity: sha512-yK/qSeWVHIGWRp3c8S5tfdGP6WCKllZC4DR8d8CQlEjszOSBmHtlTdyyqOMBZ/BA4kd+eU5f3A1r4K2tGYty1g==}
|
||||||
@@ -1086,8 +1086,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.1.1':
|
'@push.rocks/smartstate@2.2.0':
|
||||||
resolution: {integrity: sha512-4OM9TXfiiSYIgVz2pQdM2UCTurXwd8o9LCtyZ/o+rnntnXp/X8UTWZ+WyTxgnfuzXhpIYXt83t34bVBJ2EPUOw==}
|
resolution: {integrity: sha512-e41vA1y9b0HBauzjMSh3l0YlRhcG4jhArm43/HHNdT+inxEGIeRL24VGeq+sl2MUr/eFWqgrETXhvL3YrsYFaw==}
|
||||||
|
|
||||||
'@push.rocks/smartstream@2.0.8':
|
'@push.rocks/smartstream@2.0.8':
|
||||||
resolution: {integrity: sha512-GlF/9cCkvBHwKa3DK4DO5wjfSgqkj6gAS4TrY9uD5NMHu9RQv4WiNrElTYj7iCEpnZgUnLO3tzw1JA3NRIMnnA==}
|
resolution: {integrity: sha512-GlF/9cCkvBHwKa3DK4DO5wjfSgqkj6gAS4TrY9uD5NMHu9RQv4WiNrElTYj7iCEpnZgUnLO3tzw1JA3NRIMnnA==}
|
||||||
@@ -1141,6 +1141,9 @@ packages:
|
|||||||
'@push.rocks/webrequest@4.0.2':
|
'@push.rocks/webrequest@4.0.2':
|
||||||
resolution: {integrity: sha512-rowzty+Q2papFBcnNYPcy+8CQJukSn/FGfQG8ap0bUgQUsx882u8kEyLM0Q+GlGHS5OiZ+Z0z5TZqLKlk3XHxA==}
|
resolution: {integrity: sha512-rowzty+Q2papFBcnNYPcy+8CQJukSn/FGfQG8ap0bUgQUsx882u8kEyLM0Q+GlGHS5OiZ+Z0z5TZqLKlk3XHxA==}
|
||||||
|
|
||||||
|
'@push.rocks/webrequest@4.0.5':
|
||||||
|
resolution: {integrity: sha512-wVSCaXqJ9Vh+rbwVz0wDl46dYz4rnwwSrm5vbVXKbuH6oKTPF0YRoujeJPqRltIn64RVGdLeY9/6ix+ZCrzhsg==}
|
||||||
|
|
||||||
'@push.rocks/websetup@3.0.19':
|
'@push.rocks/websetup@3.0.19':
|
||||||
resolution: {integrity: sha512-iKJDwXdMmQdu5siOIgziPRxM51lN1AU9HOr+yMteu1YMDkZT7HKCyisDAr4gC9WZ9a7FzsG8zgthm4dMeA8NTw==}
|
resolution: {integrity: sha512-iKJDwXdMmQdu5siOIgziPRxM51lN1AU9HOr+yMteu1YMDkZT7HKCyisDAr4gC9WZ9a7FzsG8zgthm4dMeA8NTw==}
|
||||||
|
|
||||||
@@ -1347,8 +1350,8 @@ packages:
|
|||||||
'@serve.zone/interfaces@5.3.0':
|
'@serve.zone/interfaces@5.3.0':
|
||||||
resolution: {integrity: sha512-venO7wtDR9ixzD9NhdERBGjNKbFA5LL0yHw4eqGh0UpmvtXVc3SFG0uuHDilOKMZqZ8bttV88qVsFy1aSTJrtA==}
|
resolution: {integrity: sha512-venO7wtDR9ixzD9NhdERBGjNKbFA5LL0yHw4eqGh0UpmvtXVc3SFG0uuHDilOKMZqZ8bttV88qVsFy1aSTJrtA==}
|
||||||
|
|
||||||
'@serve.zone/remoteingress@4.3.0':
|
'@serve.zone/remoteingress@4.4.0':
|
||||||
resolution: {integrity: sha512-yk14uS6oWIP83Zpem4hGf8zi3W9pefnxijtSWp45WvZ+u9XTXIADQNaUZBSTCId8CYkfPkfRGaaaARunVdjFXg==}
|
resolution: {integrity: sha512-+M2EHP0irezN0xutYn0H6ZXePWoMJy4ETbK9/5Zgb4nx2FbDRYQyFLJUXyLzVL/rtJ/5trToPwOa3ljZoVze3g==}
|
||||||
|
|
||||||
'@sindresorhus/is@5.6.0':
|
'@sindresorhus/is@5.6.0':
|
||||||
resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==}
|
resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==}
|
||||||
@@ -2084,8 +2087,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==}
|
resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==}
|
||||||
engines: {node: 20 || >=22}
|
engines: {node: 20 || >=22}
|
||||||
|
|
||||||
brace-expansion@5.0.3:
|
brace-expansion@5.0.4:
|
||||||
resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==}
|
resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==}
|
||||||
engines: {node: 18 || 20 || >=22}
|
engines: {node: 18 || 20 || >=22}
|
||||||
|
|
||||||
broadcast-channel@7.3.0:
|
broadcast-channel@7.3.0:
|
||||||
@@ -3247,8 +3250,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==}
|
resolution: {integrity: sha512-MClCe8IL5nRRmawL6ib/eT4oLyeKMGCghibcDWK+J0hh0Q8kqSdia6BvbRMVk6mPa6WqUa5uR2oxt6C5jd533A==}
|
||||||
engines: {node: 20 || >=22}
|
engines: {node: 20 || >=22}
|
||||||
|
|
||||||
minimatch@10.2.2:
|
minimatch@10.2.4:
|
||||||
resolution: {integrity: sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==}
|
resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==}
|
||||||
engines: {node: 18 || 20 || >=22}
|
engines: {node: 18 || 20 || >=22}
|
||||||
|
|
||||||
minimatch@3.1.3:
|
minimatch@3.1.3:
|
||||||
@@ -4294,7 +4297,7 @@ snapshots:
|
|||||||
|
|
||||||
'@api.global/typedrequest-interfaces@3.0.19': {}
|
'@api.global/typedrequest-interfaces@3.0.19': {}
|
||||||
|
|
||||||
'@api.global/typedrequest@3.2.7':
|
'@api.global/typedrequest@3.3.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@push.rocks/isounique': 1.0.5
|
'@push.rocks/isounique': 1.0.5
|
||||||
@@ -4303,12 +4306,12 @@ snapshots:
|
|||||||
'@push.rocks/smartdelay': 3.0.5
|
'@push.rocks/smartdelay': 3.0.5
|
||||||
'@push.rocks/smartguard': 3.1.0
|
'@push.rocks/smartguard': 3.1.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/webrequest': 4.0.2
|
'@push.rocks/webrequest': 4.0.5
|
||||||
'@push.rocks/webstream': 1.0.10
|
'@push.rocks/webstream': 1.0.10
|
||||||
|
|
||||||
'@api.global/typedserver@3.0.80(@push.rocks/smartserve@2.0.1)':
|
'@api.global/typedserver@3.0.80(@push.rocks/smartserve@2.0.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.7
|
'@api.global/typedrequest': 3.3.0
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@2.0.1)
|
'@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@2.0.1)
|
||||||
'@cloudflare/workers-types': 4.20260210.0
|
'@cloudflare/workers-types': 4.20260210.0
|
||||||
@@ -4354,9 +4357,9 @@ snapshots:
|
|||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
'@api.global/typedserver@8.4.0(@tiptap/pm@2.27.2)':
|
'@api.global/typedserver@8.4.2(@tiptap/pm@2.27.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.7
|
'@api.global/typedrequest': 3.3.0
|
||||||
'@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.1)
|
'@api.global/typedsocket': 4.1.2(@push.rocks/smartserve@2.0.1)
|
||||||
'@cloudflare/workers-types': 4.20260303.0
|
'@cloudflare/workers-types': 4.20260303.0
|
||||||
@@ -4402,7 +4405,7 @@ snapshots:
|
|||||||
|
|
||||||
'@api.global/typedsocket@3.1.1(@push.rocks/smartserve@2.0.1)':
|
'@api.global/typedsocket@3.1.1(@push.rocks/smartserve@2.0.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.7
|
'@api.global/typedrequest': 3.3.0
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@push.rocks/isohash': 2.0.1
|
'@push.rocks/isohash': 2.0.1
|
||||||
'@push.rocks/smartjson': 5.2.0
|
'@push.rocks/smartjson': 5.2.0
|
||||||
@@ -4422,7 +4425,7 @@ snapshots:
|
|||||||
|
|
||||||
'@api.global/typedsocket@4.1.2(@push.rocks/smartserve@2.0.1)':
|
'@api.global/typedsocket@4.1.2(@push.rocks/smartserve@2.0.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.7
|
'@api.global/typedrequest': 3.3.0
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@push.rocks/isohash': 2.0.1
|
'@push.rocks/isohash': 2.0.1
|
||||||
'@push.rocks/smartdelay': 3.0.5
|
'@push.rocks/smartdelay': 3.0.5
|
||||||
@@ -4997,14 +5000,14 @@ snapshots:
|
|||||||
|
|
||||||
'@design.estate/dees-comms@1.0.30':
|
'@design.estate/dees-comms@1.0.30':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.7
|
'@api.global/typedrequest': 3.3.0
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@push.rocks/smartdelay': 3.0.5
|
'@push.rocks/smartdelay': 3.0.5
|
||||||
broadcast-channel: 7.3.0
|
broadcast-channel: 7.3.0
|
||||||
|
|
||||||
'@design.estate/dees-domtools@2.3.8':
|
'@design.estate/dees-domtools@2.3.8':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.7
|
'@api.global/typedrequest': 3.3.0
|
||||||
'@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
|
||||||
@@ -5013,7 +5016,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.1.1
|
'@push.rocks/smartstate': 2.2.0
|
||||||
'@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
|
||||||
@@ -5290,7 +5293,7 @@ snapshots:
|
|||||||
|
|
||||||
'@git.zone/tswatch@3.2.0(@tiptap/pm@2.27.2)':
|
'@git.zone/tswatch@3.2.0(@tiptap/pm@2.27.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedserver': 8.4.0(@tiptap/pm@2.27.2)
|
'@api.global/typedserver': 8.4.2(@tiptap/pm@2.27.2)
|
||||||
'@git.zone/tsbundle': 2.9.0
|
'@git.zone/tsbundle': 2.9.0
|
||||||
'@git.zone/tsrun': 2.0.1
|
'@git.zone/tsrun': 2.0.1
|
||||||
'@push.rocks/early': 4.0.4
|
'@push.rocks/early': 4.0.4
|
||||||
@@ -5765,7 +5768,7 @@ snapshots:
|
|||||||
|
|
||||||
'@push.rocks/qenv@6.1.3':
|
'@push.rocks/qenv@6.1.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.7
|
'@api.global/typedrequest': 3.3.0
|
||||||
'@configvault.io/interfaces': 1.0.17
|
'@configvault.io/interfaces': 1.0.17
|
||||||
'@push.rocks/smartfile': 11.2.7
|
'@push.rocks/smartfile': 11.2.7
|
||||||
'@push.rocks/smartlog': 3.2.1
|
'@push.rocks/smartlog': 3.2.1
|
||||||
@@ -6179,7 +6182,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
matcher: 5.0.0
|
matcher: 5.0.0
|
||||||
|
|
||||||
'@push.rocks/smartmetrics@3.0.1':
|
'@push.rocks/smartmetrics@3.0.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartdelay': 3.0.5
|
'@push.rocks/smartdelay': 3.0.5
|
||||||
'@push.rocks/smartlog': 3.2.1
|
'@push.rocks/smartlog': 3.2.1
|
||||||
@@ -6354,13 +6357,13 @@ snapshots:
|
|||||||
|
|
||||||
'@push.rocks/smartpromise@4.2.3': {}
|
'@push.rocks/smartpromise@4.2.3': {}
|
||||||
|
|
||||||
'@push.rocks/smartproxy@25.8.5':
|
'@push.rocks/smartproxy@25.9.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartcrypto': 2.0.4
|
'@push.rocks/smartcrypto': 2.0.4
|
||||||
'@push.rocks/smartlog': 3.2.1
|
'@push.rocks/smartlog': 3.2.1
|
||||||
'@push.rocks/smartrust': 1.3.1
|
'@push.rocks/smartrust': 1.3.1
|
||||||
'@tsclass/tsclass': 9.3.0
|
'@tsclass/tsclass': 9.3.0
|
||||||
minimatch: 10.2.2
|
minimatch: 10.2.4
|
||||||
|
|
||||||
'@push.rocks/smartpuppeteer@2.0.5(typescript@5.9.3)':
|
'@push.rocks/smartpuppeteer@2.0.5(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -6438,7 +6441,7 @@ snapshots:
|
|||||||
|
|
||||||
'@push.rocks/smartserve@2.0.1':
|
'@push.rocks/smartserve@2.0.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.7
|
'@api.global/typedrequest': 3.3.0
|
||||||
'@cfworker/json-schema': 4.1.1
|
'@cfworker/json-schema': 4.1.1
|
||||||
'@push.rocks/lik': 6.2.2
|
'@push.rocks/lik': 6.2.2
|
||||||
'@push.rocks/smartenv': 6.0.0
|
'@push.rocks/smartenv': 6.0.0
|
||||||
@@ -6501,7 +6504,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@push.rocks/smartstate@2.1.1':
|
'@push.rocks/smartstate@2.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smarthash': 3.2.6
|
'@push.rocks/smarthash': 3.2.6
|
||||||
'@push.rocks/smartjson': 6.0.0
|
'@push.rocks/smartjson': 6.0.0
|
||||||
@@ -6650,6 +6653,14 @@ snapshots:
|
|||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/webstore': 2.0.20
|
'@push.rocks/webstore': 2.0.20
|
||||||
|
|
||||||
|
'@push.rocks/webrequest@4.0.5':
|
||||||
|
dependencies:
|
||||||
|
'@push.rocks/smartdelay': 3.0.5
|
||||||
|
'@push.rocks/smartenv': 6.0.0
|
||||||
|
'@push.rocks/smartjson': 6.0.0
|
||||||
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
|
'@push.rocks/webstore': 2.0.20
|
||||||
|
|
||||||
'@push.rocks/websetup@3.0.19':
|
'@push.rocks/websetup@3.0.19':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@pushrocks/smartdelay': 3.0.1
|
'@pushrocks/smartdelay': 3.0.1
|
||||||
@@ -6840,7 +6851,7 @@ snapshots:
|
|||||||
'@push.rocks/smartlog-interfaces': 3.0.2
|
'@push.rocks/smartlog-interfaces': 3.0.2
|
||||||
'@tsclass/tsclass': 9.3.0
|
'@tsclass/tsclass': 9.3.0
|
||||||
|
|
||||||
'@serve.zone/remoteingress@4.3.0':
|
'@serve.zone/remoteingress@4.4.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/qenv': 6.1.3
|
'@push.rocks/qenv': 6.1.3
|
||||||
'@push.rocks/smartrust': 1.3.1
|
'@push.rocks/smartrust': 1.3.1
|
||||||
@@ -7731,7 +7742,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
balanced-match: 4.0.2
|
balanced-match: 4.0.2
|
||||||
|
|
||||||
brace-expansion@5.0.3:
|
brace-expansion@5.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
balanced-match: 4.0.4
|
balanced-match: 4.0.4
|
||||||
|
|
||||||
@@ -9179,9 +9190,9 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 5.0.2
|
brace-expansion: 5.0.2
|
||||||
|
|
||||||
minimatch@10.2.2:
|
minimatch@10.2.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 5.0.3
|
brace-expansion: 5.0.4
|
||||||
|
|
||||||
minimatch@3.1.3:
|
minimatch@3.1.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { TypedRequest } from '@api.global/typedrequest';
|
|||||||
import * as interfaces from '../ts_interfaces/index.js';
|
import * as interfaces from '../ts_interfaces/index.js';
|
||||||
|
|
||||||
let testDcRouter: DcRouter;
|
let testDcRouter: DcRouter;
|
||||||
|
let adminIdentity: interfaces.data.IIdentity;
|
||||||
|
|
||||||
tap.test('should start DCRouter with OpsServer', async () => {
|
tap.test('should start DCRouter with OpsServer', async () => {
|
||||||
testDcRouter = new DcRouter({
|
testDcRouter = new DcRouter({
|
||||||
@@ -15,6 +16,21 @@ tap.test('should start DCRouter with OpsServer', async () => {
|
|||||||
expect(testDcRouter.opsServer).toBeInstanceOf(Object);
|
expect(testDcRouter.opsServer).toBeInstanceOf(Object);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('should login as admin', async () => {
|
||||||
|
const loginRequest = new TypedRequest<interfaces.requests.IReq_AdminLoginWithUsernameAndPassword>(
|
||||||
|
'http://localhost:3000/typedrequest',
|
||||||
|
'adminLoginWithUsernameAndPassword'
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = await loginRequest.fire({
|
||||||
|
username: 'admin',
|
||||||
|
password: 'admin',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(response).toHaveProperty('identity');
|
||||||
|
adminIdentity = response.identity;
|
||||||
|
});
|
||||||
|
|
||||||
tap.test('should respond to health status request', async () => {
|
tap.test('should respond to health status request', async () => {
|
||||||
const healthRequest = new TypedRequest<interfaces.requests.IReq_GetHealthStatus>(
|
const healthRequest = new TypedRequest<interfaces.requests.IReq_GetHealthStatus>(
|
||||||
'http://localhost:3000/typedrequest',
|
'http://localhost:3000/typedrequest',
|
||||||
@@ -22,7 +38,8 @@ tap.test('should respond to health status request', async () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const response = await healthRequest.fire({
|
const response = await healthRequest.fire({
|
||||||
detailed: false
|
identity: adminIdentity,
|
||||||
|
detailed: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(response).toHaveProperty('health');
|
expect(response).toHaveProperty('health');
|
||||||
@@ -37,7 +54,8 @@ tap.test('should respond to server statistics request', async () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const response = await statsRequest.fire({
|
const response = await statsRequest.fire({
|
||||||
includeHistory: false
|
identity: adminIdentity,
|
||||||
|
includeHistory: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(response).toHaveProperty('stats');
|
expect(response).toHaveProperty('stats');
|
||||||
@@ -52,7 +70,9 @@ tap.test('should respond to configuration request', async () => {
|
|||||||
'getConfiguration'
|
'getConfiguration'
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await configRequest.fire({});
|
const response = await configRequest.fire({
|
||||||
|
identity: adminIdentity,
|
||||||
|
});
|
||||||
|
|
||||||
expect(response).toHaveProperty('config');
|
expect(response).toHaveProperty('config');
|
||||||
expect(response.config).toHaveProperty('system');
|
expect(response.config).toHaveProperty('system');
|
||||||
@@ -72,7 +92,8 @@ tap.test('should handle log retrieval request', async () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const response = await logsRequest.fire({
|
const response = await logsRequest.fire({
|
||||||
limit: 10
|
identity: adminIdentity,
|
||||||
|
limit: 10,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(response).toHaveProperty('logs');
|
expect(response).toHaveProperty('logs');
|
||||||
@@ -81,6 +102,20 @@ tap.test('should handle log retrieval request', async () => {
|
|||||||
expect(response.logs).toBeArray();
|
expect(response.logs).toBeArray();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('should reject unauthenticated requests', async () => {
|
||||||
|
const healthRequest = new TypedRequest<interfaces.requests.IReq_GetHealthStatus>(
|
||||||
|
'http://localhost:3000/typedrequest',
|
||||||
|
'getHealthStatus'
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await healthRequest.fire({} as any);
|
||||||
|
expect(true).toBeFalse(); // Should not reach here
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).toBeTruthy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
tap.test('should stop DCRouter', async () => {
|
tap.test('should stop DCRouter', async () => {
|
||||||
await testDcRouter.stop();
|
await testDcRouter.stop();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,28 +82,31 @@ tap.test('should reject verify identity with invalid JWT', async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should allow access to public endpoints without auth', async () => {
|
tap.test('should reject protected endpoints without auth', async () => {
|
||||||
const healthRequest = new TypedRequest<interfaces.requests.IReq_GetHealthStatus>(
|
const healthRequest = new TypedRequest<interfaces.requests.IReq_GetHealthStatus>(
|
||||||
'http://localhost:3000/typedrequest',
|
'http://localhost:3000/typedrequest',
|
||||||
'getHealthStatus'
|
'getHealthStatus'
|
||||||
);
|
);
|
||||||
|
|
||||||
// No identity provided
|
try {
|
||||||
const response = await healthRequest.fire({});
|
// No identity provided — should be rejected
|
||||||
|
await healthRequest.fire({} as any);
|
||||||
expect(response).toHaveProperty('health');
|
expect(true).toBeFalse(); // Should not reach here
|
||||||
expect(response.health.healthy).toBeTrue();
|
} catch (error) {
|
||||||
console.log('Public endpoint accessible without auth');
|
expect(error).toBeTruthy();
|
||||||
|
console.log('Protected endpoint correctly rejects unauthenticated request');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should allow read-only config access', async () => {
|
tap.test('should allow authenticated access to protected endpoints', async () => {
|
||||||
const configRequest = new TypedRequest<interfaces.requests.IReq_GetConfiguration>(
|
const configRequest = new TypedRequest<interfaces.requests.IReq_GetConfiguration>(
|
||||||
'http://localhost:3000/typedrequest',
|
'http://localhost:3000/typedrequest',
|
||||||
'getConfiguration'
|
'getConfiguration'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Config is read-only and doesn't require auth
|
const response = await configRequest.fire({
|
||||||
const response = await configRequest.fire({});
|
identity: adminIdentity,
|
||||||
|
});
|
||||||
|
|
||||||
expect(response).toHaveProperty('config');
|
expect(response).toHaveProperty('config');
|
||||||
expect(response.config).toHaveProperty('system');
|
expect(response.config).toHaveProperty('system');
|
||||||
@@ -114,7 +117,7 @@ tap.test('should allow read-only config access', async () => {
|
|||||||
expect(response.config).toHaveProperty('cache');
|
expect(response.config).toHaveProperty('cache');
|
||||||
expect(response.config).toHaveProperty('radius');
|
expect(response.config).toHaveProperty('radius');
|
||||||
expect(response.config).toHaveProperty('remoteIngress');
|
expect(response.config).toHaveProperty('remoteIngress');
|
||||||
console.log('Configuration read successfully');
|
console.log('Authenticated access to config successful');
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should stop DCRouter', async () => {
|
tap.test('should stop DCRouter', async () => {
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/dcrouter',
|
name: '@serve.zone/dcrouter',
|
||||||
version: '10.1.5',
|
version: '11.0.0',
|
||||||
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,20 @@ import type DcRouter from '../classes.dcrouter.js';
|
|||||||
import * as plugins from '../plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import * as paths from '../paths.js';
|
import * as paths from '../paths.js';
|
||||||
import * as handlers from './handlers/index.js';
|
import * as handlers from './handlers/index.js';
|
||||||
|
import * as interfaces from '../../ts_interfaces/index.js';
|
||||||
|
import { requireValidIdentity, requireAdminIdentity } from './helpers/guards.js';
|
||||||
|
|
||||||
export class OpsServer {
|
export class OpsServer {
|
||||||
public dcRouterRef: DcRouter;
|
public dcRouterRef: DcRouter;
|
||||||
public server: plugins.typedserver.utilityservers.UtilityWebsiteServer;
|
public server: plugins.typedserver.utilityservers.UtilityWebsiteServer;
|
||||||
|
|
||||||
// TypedRouter for OpsServer-specific handlers
|
// Main TypedRouter — unauthenticated endpoints (login/logout/verify) and own-auth handlers
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||||||
|
|
||||||
|
// Auth-enforced routers — middleware validates identity before any handler runs
|
||||||
|
public viewRouter = new plugins.typedrequest.TypedRouter<{ request: { identity: interfaces.data.IIdentity } }>();
|
||||||
|
public adminRouter = new plugins.typedrequest.TypedRouter<{ request: { identity: interfaces.data.IIdentity } }>();
|
||||||
|
|
||||||
// Handler instances
|
// Handler instances
|
||||||
public adminHandler: handlers.AdminHandler;
|
public adminHandler: handlers.AdminHandler;
|
||||||
private configHandler: handlers.ConfigHandler;
|
private configHandler: handlers.ConfigHandler;
|
||||||
@@ -51,10 +57,25 @@ export class OpsServer {
|
|||||||
* Set up all TypedRequest handlers
|
* Set up all TypedRequest handlers
|
||||||
*/
|
*/
|
||||||
private async setupHandlers(): Promise<void> {
|
private async setupHandlers(): Promise<void> {
|
||||||
// Instantiate all handlers - they self-register with the typedrouter
|
// AdminHandler must be initialized first (JWT setup needed for guards)
|
||||||
this.adminHandler = new handlers.AdminHandler(this);
|
this.adminHandler = new handlers.AdminHandler(this);
|
||||||
await this.adminHandler.initialize(); // JWT needs async initialization
|
await this.adminHandler.initialize();
|
||||||
|
|
||||||
|
// viewRouter middleware: requires valid identity (any logged-in user)
|
||||||
|
this.viewRouter.addMiddleware(async (typedRequest) => {
|
||||||
|
await requireValidIdentity(this.adminHandler, typedRequest.request);
|
||||||
|
});
|
||||||
|
|
||||||
|
// adminRouter middleware: requires admin identity
|
||||||
|
this.adminRouter.addMiddleware(async (typedRequest) => {
|
||||||
|
await requireAdminIdentity(this.adminHandler, typedRequest.request);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Connect auth routers to the main typedrouter
|
||||||
|
this.typedrouter.addTypedRouter(this.viewRouter);
|
||||||
|
this.typedrouter.addTypedRouter(this.adminRouter);
|
||||||
|
|
||||||
|
// Instantiate all handlers — they self-register with the appropriate router
|
||||||
this.configHandler = new handlers.ConfigHandler(this);
|
this.configHandler = new handlers.ConfigHandler(this);
|
||||||
this.logsHandler = new handlers.LogsHandler(this);
|
this.logsHandler = new handlers.LogsHandler(this);
|
||||||
this.securityHandler = new handlers.SecurityHandler(this);
|
this.securityHandler = new handlers.SecurityHandler(this);
|
||||||
|
|||||||
@@ -3,34 +3,20 @@ import type { OpsServer } from '../classes.opsserver.js';
|
|||||||
import * as interfaces from '../../../ts_interfaces/index.js';
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
||||||
|
|
||||||
export class ApiTokenHandler {
|
export class ApiTokenHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Token management requires admin JWT only (tokens cannot manage tokens).
|
|
||||||
*/
|
|
||||||
private async requireAdmin(identity?: interfaces.data.IIdentity): Promise<string> {
|
|
||||||
if (!identity?.jwt) {
|
|
||||||
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
|
||||||
}
|
|
||||||
const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({ identity });
|
|
||||||
if (!isAdmin) {
|
|
||||||
throw new plugins.typedrequest.TypedResponseError('admin access required');
|
|
||||||
}
|
|
||||||
return identity.userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
// All token management endpoints register directly on adminRouter
|
||||||
|
// (middleware enforces admin JWT check, so no per-handler requireAdmin needed)
|
||||||
|
const router = this.opsServerRef.adminRouter;
|
||||||
|
|
||||||
// Create API token
|
// Create API token
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateApiToken>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateApiToken>(
|
||||||
'createApiToken',
|
'createApiToken',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
const userId = await this.requireAdmin(dataArg.identity);
|
|
||||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||||
if (!manager) {
|
if (!manager) {
|
||||||
return { success: false, message: 'Token management not initialized' };
|
return { success: false, message: 'Token management not initialized' };
|
||||||
@@ -39,7 +25,7 @@ export class ApiTokenHandler {
|
|||||||
dataArg.name,
|
dataArg.name,
|
||||||
dataArg.scopes,
|
dataArg.scopes,
|
||||||
dataArg.expiresInDays ?? null,
|
dataArg.expiresInDays ?? null,
|
||||||
userId,
|
dataArg.identity.userId,
|
||||||
);
|
);
|
||||||
return { success: true, tokenId: result.id, tokenValue: result.rawToken };
|
return { success: true, tokenId: result.id, tokenValue: result.rawToken };
|
||||||
},
|
},
|
||||||
@@ -47,11 +33,10 @@ export class ApiTokenHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// List API tokens
|
// List API tokens
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListApiTokens>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListApiTokens>(
|
||||||
'listApiTokens',
|
'listApiTokens',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
await this.requireAdmin(dataArg.identity);
|
|
||||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||||
if (!manager) {
|
if (!manager) {
|
||||||
return { tokens: [] };
|
return { tokens: [] };
|
||||||
@@ -62,11 +47,10 @@ export class ApiTokenHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Revoke API token
|
// Revoke API token
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RevokeApiToken>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RevokeApiToken>(
|
||||||
'revokeApiToken',
|
'revokeApiToken',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
await this.requireAdmin(dataArg.identity);
|
|
||||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||||
if (!manager) {
|
if (!manager) {
|
||||||
return { success: false, message: 'Token management not initialized' };
|
return { success: false, message: 'Token management not initialized' };
|
||||||
@@ -78,11 +62,10 @@ export class ApiTokenHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Roll API token
|
// Roll API token
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RollApiToken>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RollApiToken>(
|
||||||
'rollApiToken',
|
'rollApiToken',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
await this.requireAdmin(dataArg.identity);
|
|
||||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||||
if (!manager) {
|
if (!manager) {
|
||||||
return { success: false, message: 'Token management not initialized' };
|
return { success: false, message: 'Token management not initialized' };
|
||||||
@@ -97,11 +80,10 @@ export class ApiTokenHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Toggle API token
|
// Toggle API token
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ToggleApiToken>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ToggleApiToken>(
|
||||||
'toggleApiToken',
|
'toggleApiToken',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
await this.requireAdmin(dataArg.identity);
|
|
||||||
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
const manager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
||||||
if (!manager) {
|
if (!manager) {
|
||||||
return { success: false, message: 'Token management not initialized' };
|
return { success: false, message: 'Token management not initialized' };
|
||||||
|
|||||||
@@ -3,16 +3,18 @@ import type { OpsServer } from '../classes.opsserver.js';
|
|||||||
import * as interfaces from '../../../ts_interfaces/index.js';
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
||||||
|
|
||||||
export class CertificateHandler {
|
export class CertificateHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
const viewRouter = this.opsServerRef.viewRouter;
|
||||||
|
const adminRouter = this.opsServerRef.adminRouter;
|
||||||
|
|
||||||
|
// ---- Read endpoints (viewRouter — valid identity required via middleware) ----
|
||||||
|
|
||||||
// Get Certificate Overview
|
// Get Certificate Overview
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetCertificateOverview>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetCertificateOverview>(
|
||||||
'getCertificateOverview',
|
'getCertificateOverview',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
@@ -23,8 +25,10 @@ export class CertificateHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ---- Write endpoints (adminRouter — admin identity required via middleware) ----
|
||||||
|
|
||||||
// Legacy route-based reprovision (backward compat)
|
// Legacy route-based reprovision (backward compat)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ReprovisionCertificate>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ReprovisionCertificate>(
|
||||||
'reprovisionCertificate',
|
'reprovisionCertificate',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
@@ -34,7 +38,7 @@ export class CertificateHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Domain-based reprovision (preferred)
|
// Domain-based reprovision (preferred)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ReprovisionCertificateDomain>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ReprovisionCertificateDomain>(
|
||||||
'reprovisionCertificateDomain',
|
'reprovisionCertificateDomain',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
@@ -44,7 +48,7 @@ export class CertificateHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Delete certificate
|
// Delete certificate
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteCertificate>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteCertificate>(
|
||||||
'deleteCertificate',
|
'deleteCertificate',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
@@ -54,7 +58,7 @@ export class CertificateHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Export certificate
|
// Export certificate
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ExportCertificate>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ExportCertificate>(
|
||||||
'exportCertificate',
|
'exportCertificate',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
@@ -64,7 +68,7 @@ export class CertificateHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Import certificate
|
// Import certificate
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ImportCertificate>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ImportCertificate>(
|
||||||
'importCertificate',
|
'importCertificate',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
|
|||||||
@@ -4,17 +4,16 @@ import type { OpsServer } from '../classes.opsserver.js';
|
|||||||
import * as interfaces from '../../../ts_interfaces/index.js';
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
||||||
|
|
||||||
export class ConfigHandler {
|
export class ConfigHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
// Add this handler's router to the parent
|
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
// Config endpoint registers directly on viewRouter (valid identity required via middleware)
|
||||||
|
const router = this.opsServerRef.viewRouter;
|
||||||
|
|
||||||
// Get Configuration Handler (read-only)
|
// Get Configuration Handler (read-only)
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetConfiguration>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetConfiguration>(
|
||||||
'getConfiguration',
|
'getConfiguration',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
|
|||||||
@@ -3,17 +3,18 @@ import type { OpsServer } from '../classes.opsserver.js';
|
|||||||
import * as interfaces from '../../../ts_interfaces/index.js';
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
||||||
|
|
||||||
export class EmailOpsHandler {
|
export class EmailOpsHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
// Add this handler's router to the parent
|
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
const viewRouter = this.opsServerRef.viewRouter;
|
||||||
|
const adminRouter = this.opsServerRef.adminRouter;
|
||||||
|
|
||||||
|
// ---- Read endpoints (viewRouter — valid identity required via middleware) ----
|
||||||
|
|
||||||
// Get All Emails Handler
|
// Get All Emails Handler
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetAllEmails>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetAllEmails>(
|
||||||
'getAllEmails',
|
'getAllEmails',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
@@ -24,7 +25,7 @@ export class EmailOpsHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Get Email Detail Handler
|
// Get Email Detail Handler
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetEmailDetail>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetEmailDetail>(
|
||||||
'getEmailDetail',
|
'getEmailDetail',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
@@ -34,8 +35,10 @@ export class EmailOpsHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ---- Write endpoints (adminRouter) ----
|
||||||
|
|
||||||
// Resend Failed Email Handler
|
// Resend Failed Email Handler
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ResendEmail>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ResendEmail>(
|
||||||
'resendEmail',
|
'resendEmail',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
|
|||||||
@@ -10,12 +10,9 @@ let logPushDestinationInstalled = false;
|
|||||||
let currentOpsServerRef: OpsServer | null = null;
|
let currentOpsServerRef: OpsServer | null = null;
|
||||||
|
|
||||||
export class LogsHandler {
|
export class LogsHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
private activeStreamStops: Set<() => void> = new Set();
|
private activeStreamStops: Set<() => void> = new Set();
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
// Add this handler's router to the parent
|
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
this.setupLogPushDestination();
|
this.setupLogPushDestination();
|
||||||
}
|
}
|
||||||
@@ -35,8 +32,11 @@ export class LogsHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
// All log endpoints register directly on viewRouter (valid identity required via middleware)
|
||||||
|
const router = this.opsServerRef.viewRouter;
|
||||||
|
|
||||||
// Get Recent Logs Handler
|
// Get Recent Logs Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRecentLogs>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRecentLogs>(
|
||||||
'getRecentLogs',
|
'getRecentLogs',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -59,7 +59,7 @@ export class LogsHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Get Log Stream Handler
|
// Get Log Stream Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetLogStream>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetLogStream>(
|
||||||
'getLogStream',
|
'getLogStream',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
|
|||||||
@@ -3,21 +3,19 @@ import type { OpsServer } from '../classes.opsserver.js';
|
|||||||
import * as interfaces from '../../../ts_interfaces/index.js';
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
||||||
|
|
||||||
export class RadiusHandler {
|
export class RadiusHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
// Add this handler's router to the parent
|
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
const viewRouter = this.opsServerRef.viewRouter;
|
||||||
|
const adminRouter = this.opsServerRef.adminRouter;
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// RADIUS Client Management
|
// RADIUS Client Management
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
// Get all RADIUS clients
|
// Get all RADIUS clients (read)
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusClients>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusClients>(
|
||||||
'getRadiusClients',
|
'getRadiusClients',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -40,8 +38,8 @@ export class RadiusHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add or update a RADIUS client
|
// Add or update a RADIUS client (write)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SetRadiusClient>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SetRadiusClient>(
|
||||||
'setRadiusClient',
|
'setRadiusClient',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -61,8 +59,8 @@ export class RadiusHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove a RADIUS client
|
// Remove a RADIUS client (write)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RemoveRadiusClient>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RemoveRadiusClient>(
|
||||||
'removeRadiusClient',
|
'removeRadiusClient',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -85,8 +83,8 @@ export class RadiusHandler {
|
|||||||
// VLAN Mapping Management
|
// VLAN Mapping Management
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
// Get all VLAN mappings
|
// Get all VLAN mappings (read)
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetVlanMappings>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetVlanMappings>(
|
||||||
'getVlanMappings',
|
'getVlanMappings',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -121,8 +119,8 @@ export class RadiusHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add or update a VLAN mapping
|
// Add or update a VLAN mapping (write)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SetVlanMapping>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SetVlanMapping>(
|
||||||
'setVlanMapping',
|
'setVlanMapping',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -153,8 +151,8 @@ export class RadiusHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove a VLAN mapping
|
// Remove a VLAN mapping (write)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RemoveVlanMapping>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RemoveVlanMapping>(
|
||||||
'removeVlanMapping',
|
'removeVlanMapping',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -174,8 +172,8 @@ export class RadiusHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update VLAN configuration
|
// Update VLAN configuration (write)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateVlanConfig>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateVlanConfig>(
|
||||||
'updateVlanConfig',
|
'updateVlanConfig',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -206,8 +204,8 @@ export class RadiusHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test VLAN assignment
|
// Test VLAN assignment (read)
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_TestVlanAssignment>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_TestVlanAssignment>(
|
||||||
'testVlanAssignment',
|
'testVlanAssignment',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -240,8 +238,8 @@ export class RadiusHandler {
|
|||||||
// Accounting / Session Management
|
// Accounting / Session Management
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
// Get active sessions
|
// Get active sessions (read)
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusSessions>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusSessions>(
|
||||||
'getRadiusSessions',
|
'getRadiusSessions',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -289,8 +287,8 @@ export class RadiusHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Disconnect a session
|
// Disconnect a session (write)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DisconnectRadiusSession>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DisconnectRadiusSession>(
|
||||||
'disconnectRadiusSession',
|
'disconnectRadiusSession',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -314,8 +312,8 @@ export class RadiusHandler {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get accounting summary
|
// Get accounting summary (read)
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusAccountingSummary>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusAccountingSummary>(
|
||||||
'getRadiusAccountingSummary',
|
'getRadiusAccountingSummary',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -351,8 +349,8 @@ export class RadiusHandler {
|
|||||||
// Statistics
|
// Statistics
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
// Get RADIUS statistics
|
// Get RADIUS statistics (read)
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusStatistics>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRadiusStatistics>(
|
||||||
'getRadiusStatistics',
|
'getRadiusStatistics',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
|
|||||||
@@ -3,16 +3,18 @@ import type { OpsServer } from '../classes.opsserver.js';
|
|||||||
import * as interfaces from '../../../ts_interfaces/index.js';
|
import * as interfaces from '../../../ts_interfaces/index.js';
|
||||||
|
|
||||||
export class RemoteIngressHandler {
|
export class RemoteIngressHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
const viewRouter = this.opsServerRef.viewRouter;
|
||||||
|
const adminRouter = this.opsServerRef.adminRouter;
|
||||||
|
|
||||||
|
// ---- Read endpoints (viewRouter — valid identity required via middleware) ----
|
||||||
|
|
||||||
// Get all remote ingress edges
|
// Get all remote ingress edges
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngresses>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngresses>(
|
||||||
'getRemoteIngresses',
|
'getRemoteIngresses',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -36,8 +38,10 @@ export class RemoteIngressHandler {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ---- Write endpoints (adminRouter) ----
|
||||||
|
|
||||||
// Create a new remote ingress edge
|
// Create a new remote ingress edge
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateRemoteIngress>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateRemoteIngress>(
|
||||||
'createRemoteIngress',
|
'createRemoteIngress',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -69,7 +73,7 @@ export class RemoteIngressHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Delete a remote ingress edge
|
// Delete a remote ingress edge
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteRemoteIngress>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteRemoteIngress>(
|
||||||
'deleteRemoteIngress',
|
'deleteRemoteIngress',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -94,7 +98,7 @@ export class RemoteIngressHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Update a remote ingress edge
|
// Update a remote ingress edge
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateRemoteIngress>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateRemoteIngress>(
|
||||||
'updateRemoteIngress',
|
'updateRemoteIngress',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -138,7 +142,7 @@ export class RemoteIngressHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Regenerate secret for an edge
|
// Regenerate secret for an edge
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RegenerateRemoteIngressSecret>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RegenerateRemoteIngressSecret>(
|
||||||
'regenerateRemoteIngressSecret',
|
'regenerateRemoteIngressSecret',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -164,8 +168,8 @@ export class RemoteIngressHandler {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get runtime status of all edges
|
// Get runtime status of all edges (read)
|
||||||
this.typedrouter.addTypedHandler(
|
viewRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngressStatus>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngressStatus>(
|
||||||
'getRemoteIngressStatus',
|
'getRemoteIngressStatus',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -178,8 +182,8 @@ export class RemoteIngressHandler {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get a connection token for an edge
|
// Get a connection token for an edge (write — exposes secret)
|
||||||
this.typedrouter.addTypedHandler(
|
adminRouter.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngressConnectionToken>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRemoteIngressConnectionToken>(
|
||||||
'getRemoteIngressConnectionToken',
|
'getRemoteIngressConnectionToken',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
|
|||||||
@@ -4,17 +4,16 @@ import * as interfaces from '../../../ts_interfaces/index.js';
|
|||||||
import { MetricsManager } from '../../monitoring/index.js';
|
import { MetricsManager } from '../../monitoring/index.js';
|
||||||
|
|
||||||
export class SecurityHandler {
|
export class SecurityHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
// Add this handler's router to the parent
|
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
// All security endpoints register directly on viewRouter (valid identity required via middleware)
|
||||||
|
const router = this.opsServerRef.viewRouter;
|
||||||
|
|
||||||
// Security Metrics Handler
|
// Security Metrics Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetSecurityMetrics>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetSecurityMetrics>(
|
||||||
'getSecurityMetrics',
|
'getSecurityMetrics',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -40,7 +39,7 @@ export class SecurityHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Active Connections Handler
|
// Active Connections Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetActiveConnections>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetActiveConnections>(
|
||||||
'getActiveConnections',
|
'getActiveConnections',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -77,8 +76,8 @@ export class SecurityHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Network Stats Handler - provides comprehensive network metrics
|
// Network Stats Handler - provides comprehensive network metrics
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetNetworkStats>(
|
||||||
'getNetworkStats',
|
'getNetworkStats',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
// Get network stats from MetricsManager if available
|
// Get network stats from MetricsManager if available
|
||||||
@@ -121,7 +120,7 @@ export class SecurityHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Rate Limit Status Handler
|
// Rate Limit Status Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRateLimitStatus>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRateLimitStatus>(
|
||||||
'getRateLimitStatus',
|
'getRateLimitStatus',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
|
|||||||
@@ -5,17 +5,16 @@ import { MetricsManager } from '../../monitoring/index.js';
|
|||||||
import { SecurityLogger } from '../../security/classes.securitylogger.js';
|
import { SecurityLogger } from '../../security/classes.securitylogger.js';
|
||||||
|
|
||||||
export class StatsHandler {
|
export class StatsHandler {
|
||||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
||||||
|
|
||||||
constructor(private opsServerRef: OpsServer) {
|
constructor(private opsServerRef: OpsServer) {
|
||||||
// Add this handler's router to the parent
|
|
||||||
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
||||||
this.registerHandlers();
|
this.registerHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerHandlers(): void {
|
private registerHandlers(): void {
|
||||||
|
// All stats endpoints register directly on viewRouter (valid identity required via middleware)
|
||||||
|
const router = this.opsServerRef.viewRouter;
|
||||||
|
|
||||||
// Server Statistics Handler
|
// Server Statistics Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetServerStatistics>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetServerStatistics>(
|
||||||
'getServerStatistics',
|
'getServerStatistics',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -38,7 +37,7 @@ export class StatsHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Email Statistics Handler
|
// Email Statistics Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetEmailStatistics>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetEmailStatistics>(
|
||||||
'getEmailStatistics',
|
'getEmailStatistics',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -77,7 +76,7 @@ export class StatsHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// DNS Statistics Handler
|
// DNS Statistics Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDnsStatistics>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDnsStatistics>(
|
||||||
'getDnsStatistics',
|
'getDnsStatistics',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -114,7 +113,7 @@ export class StatsHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Queue Status Handler
|
// Queue Status Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetQueueStatus>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetQueueStatus>(
|
||||||
'getQueueStatus',
|
'getQueueStatus',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -142,7 +141,7 @@ export class StatsHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Health Status Handler
|
// Health Status Handler
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetHealthStatus>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetHealthStatus>(
|
||||||
'getHealthStatus',
|
'getHealthStatus',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
@@ -167,7 +166,7 @@ export class StatsHandler {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Combined Metrics Handler - More efficient for frontend polling
|
// Combined Metrics Handler - More efficient for frontend polling
|
||||||
this.typedrouter.addTypedHandler(
|
router.addTypedHandler(
|
||||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetCombinedMetrics>(
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetCombinedMetrics>(
|
||||||
'getCombinedMetrics',
|
'getCombinedMetrics',
|
||||||
async (dataArg, toolsArg) => {
|
async (dataArg, toolsArg) => {
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ export async function passGuards<T extends { identity?: any }>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to check admin identity in handlers
|
* Helper to check admin identity in handlers and middleware.
|
||||||
|
* Accepts both optional and required identity for flexibility.
|
||||||
*/
|
*/
|
||||||
export async function requireAdminIdentity<T extends { identity?: interfaces.data.IIdentity }>(
|
export async function requireAdminIdentity(
|
||||||
adminHandler: AdminHandler,
|
adminHandler: AdminHandler,
|
||||||
dataArg: T
|
dataArg: { identity?: interfaces.data.IIdentity }
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!dataArg.identity) {
|
if (!dataArg.identity) {
|
||||||
throw new plugins.typedrequest.TypedResponseError('No identity provided');
|
throw new plugins.typedrequest.TypedResponseError('No identity provided');
|
||||||
@@ -39,11 +40,12 @@ export async function requireAdminIdentity<T extends { identity?: interfaces.dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to check valid identity in handlers
|
* Helper to check valid identity in handlers and middleware.
|
||||||
|
* Accepts both optional and required identity for flexibility.
|
||||||
*/
|
*/
|
||||||
export async function requireValidIdentity<T extends { identity?: interfaces.data.IIdentity }>(
|
export async function requireValidIdentity(
|
||||||
adminHandler: AdminHandler,
|
adminHandler: AdminHandler,
|
||||||
dataArg: T
|
dataArg: { identity?: interfaces.data.IIdentity }
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!dataArg.identity) {
|
if (!dataArg.identity) {
|
||||||
throw new plugins.typedrequest.TypedResponseError('No identity provided');
|
throw new plugins.typedrequest.TypedResponseError('No identity provided');
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export interface IReq_CreateApiToken extends plugins.typedrequestInterfaces.impl
|
|||||||
> {
|
> {
|
||||||
method: 'createApiToken';
|
method: 'createApiToken';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
name: string;
|
name: string;
|
||||||
scopes: TApiTokenScope[];
|
scopes: TApiTokenScope[];
|
||||||
expiresInDays?: number | null;
|
expiresInDays?: number | null;
|
||||||
@@ -38,7 +38,7 @@ export interface IReq_ListApiTokens extends plugins.typedrequestInterfaces.imple
|
|||||||
> {
|
> {
|
||||||
method: 'listApiTokens';
|
method: 'listApiTokens';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
tokens: IApiTokenInfo[];
|
tokens: IApiTokenInfo[];
|
||||||
@@ -54,7 +54,7 @@ export interface IReq_RevokeApiToken extends plugins.typedrequestInterfaces.impl
|
|||||||
> {
|
> {
|
||||||
method: 'revokeApiToken';
|
method: 'revokeApiToken';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -73,7 +73,7 @@ export interface IReq_RollApiToken extends plugins.typedrequestInterfaces.implem
|
|||||||
> {
|
> {
|
||||||
method: 'rollApiToken';
|
method: 'rollApiToken';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -92,7 +92,7 @@ export interface IReq_ToggleApiToken extends plugins.typedrequestInterfaces.impl
|
|||||||
> {
|
> {
|
||||||
method: 'toggleApiToken';
|
method: 'toggleApiToken';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
id: string;
|
id: string;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export interface IReq_GetCertificateOverview extends plugins.typedrequestInterfa
|
|||||||
> {
|
> {
|
||||||
method: 'getCertificateOverview';
|
method: 'getCertificateOverview';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
certificates: ICertificateInfo[];
|
certificates: ICertificateInfo[];
|
||||||
@@ -50,7 +50,7 @@ export interface IReq_ReprovisionCertificate extends plugins.typedrequestInterfa
|
|||||||
> {
|
> {
|
||||||
method: 'reprovisionCertificate';
|
method: 'reprovisionCertificate';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
routeName: string;
|
routeName: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -66,7 +66,7 @@ export interface IReq_ReprovisionCertificateDomain extends plugins.typedrequestI
|
|||||||
> {
|
> {
|
||||||
method: 'reprovisionCertificateDomain';
|
method: 'reprovisionCertificateDomain';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
domain: string;
|
domain: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -82,7 +82,7 @@ export interface IReq_DeleteCertificate extends plugins.typedrequestInterfaces.i
|
|||||||
> {
|
> {
|
||||||
method: 'deleteCertificate';
|
method: 'deleteCertificate';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
domain: string;
|
domain: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -98,7 +98,7 @@ export interface IReq_ExportCertificate extends plugins.typedrequestInterfaces.i
|
|||||||
> {
|
> {
|
||||||
method: 'exportCertificate';
|
method: 'exportCertificate';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
domain: string;
|
domain: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -123,7 +123,7 @@ export interface IReq_ImportCertificate extends plugins.typedrequestInterfaces.i
|
|||||||
> {
|
> {
|
||||||
method: 'importCertificate';
|
method: 'importCertificate';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
cert: {
|
cert: {
|
||||||
id: string;
|
id: string;
|
||||||
domainName: string;
|
domainName: string;
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export interface IReq_GetConfiguration extends plugins.typedrequestInterfaces.im
|
|||||||
> {
|
> {
|
||||||
method: 'getConfiguration';
|
method: 'getConfiguration';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
section?: string;
|
section?: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export interface IReq_GetAllEmails extends plugins.typedrequestInterfaces.implem
|
|||||||
> {
|
> {
|
||||||
method: 'getAllEmails';
|
method: 'getAllEmails';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
emails: IEmail[];
|
emails: IEmail[];
|
||||||
@@ -84,7 +84,7 @@ export interface IReq_GetEmailDetail extends plugins.typedrequestInterfaces.impl
|
|||||||
> {
|
> {
|
||||||
method: 'getEmailDetail';
|
method: 'getEmailDetail';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
emailId: string;
|
emailId: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -101,7 +101,7 @@ export interface IReq_ResendEmail extends plugins.typedrequestInterfaces.impleme
|
|||||||
> {
|
> {
|
||||||
method: 'resendEmail';
|
method: 'resendEmail';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
emailId: string;
|
emailId: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export interface IReq_GetRecentLogs extends plugins.typedrequestInterfaces.imple
|
|||||||
> {
|
> {
|
||||||
method: 'getRecentLogs';
|
method: 'getRecentLogs';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
level?: 'debug' | 'info' | 'warn' | 'error';
|
level?: 'debug' | 'info' | 'warn' | 'error';
|
||||||
category?: 'smtp' | 'dns' | 'security' | 'system' | 'email';
|
category?: 'smtp' | 'dns' | 'security' | 'system' | 'email';
|
||||||
limit?: number;
|
limit?: number;
|
||||||
@@ -31,7 +31,7 @@ export interface IReq_GetLogStream extends plugins.typedrequestInterfaces.implem
|
|||||||
> {
|
> {
|
||||||
method: 'getLogStream';
|
method: 'getLogStream';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
follow?: boolean;
|
follow?: boolean;
|
||||||
filters?: {
|
filters?: {
|
||||||
level?: string[];
|
level?: string[];
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export interface IReq_GetRadiusClients extends plugins.typedrequestInterfaces.im
|
|||||||
> {
|
> {
|
||||||
method: 'getRadiusClients';
|
method: 'getRadiusClients';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
clients: Array<{
|
clients: Array<{
|
||||||
@@ -35,7 +35,7 @@ export interface IReq_SetRadiusClient extends plugins.typedrequestInterfaces.imp
|
|||||||
> {
|
> {
|
||||||
method: 'setRadiusClient';
|
method: 'setRadiusClient';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
client: {
|
client: {
|
||||||
name: string;
|
name: string;
|
||||||
ipRange: string;
|
ipRange: string;
|
||||||
@@ -59,7 +59,7 @@ export interface IReq_RemoveRadiusClient extends plugins.typedrequestInterfaces.
|
|||||||
> {
|
> {
|
||||||
method: 'removeRadiusClient';
|
method: 'removeRadiusClient';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -81,7 +81,7 @@ export interface IReq_GetVlanMappings extends plugins.typedrequestInterfaces.imp
|
|||||||
> {
|
> {
|
||||||
method: 'getVlanMappings';
|
method: 'getVlanMappings';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
mappings: Array<{
|
mappings: Array<{
|
||||||
@@ -108,7 +108,7 @@ export interface IReq_SetVlanMapping extends plugins.typedrequestInterfaces.impl
|
|||||||
> {
|
> {
|
||||||
method: 'setVlanMapping';
|
method: 'setVlanMapping';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
mapping: {
|
mapping: {
|
||||||
mac: string;
|
mac: string;
|
||||||
vlan: number;
|
vlan: number;
|
||||||
@@ -139,7 +139,7 @@ export interface IReq_RemoveVlanMapping extends plugins.typedrequestInterfaces.i
|
|||||||
> {
|
> {
|
||||||
method: 'removeVlanMapping';
|
method: 'removeVlanMapping';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
mac: string;
|
mac: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -157,7 +157,7 @@ export interface IReq_UpdateVlanConfig extends plugins.typedrequestInterfaces.im
|
|||||||
> {
|
> {
|
||||||
method: 'updateVlanConfig';
|
method: 'updateVlanConfig';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
defaultVlan?: number;
|
defaultVlan?: number;
|
||||||
allowUnknownMacs?: boolean;
|
allowUnknownMacs?: boolean;
|
||||||
};
|
};
|
||||||
@@ -179,7 +179,7 @@ export interface IReq_TestVlanAssignment extends plugins.typedrequestInterfaces.
|
|||||||
> {
|
> {
|
||||||
method: 'testVlanAssignment';
|
method: 'testVlanAssignment';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
mac: string;
|
mac: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -207,7 +207,7 @@ export interface IReq_GetRadiusSessions extends plugins.typedrequestInterfaces.i
|
|||||||
> {
|
> {
|
||||||
method: 'getRadiusSessions';
|
method: 'getRadiusSessions';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
filter?: {
|
filter?: {
|
||||||
username?: string;
|
username?: string;
|
||||||
nasIpAddress?: string;
|
nasIpAddress?: string;
|
||||||
@@ -243,7 +243,7 @@ export interface IReq_DisconnectRadiusSession extends plugins.typedrequestInterf
|
|||||||
> {
|
> {
|
||||||
method: 'disconnectRadiusSession';
|
method: 'disconnectRadiusSession';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
sessionId: string;
|
sessionId: string;
|
||||||
reason?: string;
|
reason?: string;
|
||||||
};
|
};
|
||||||
@@ -262,7 +262,7 @@ export interface IReq_GetRadiusAccountingSummary extends plugins.typedrequestInt
|
|||||||
> {
|
> {
|
||||||
method: 'getRadiusAccountingSummary';
|
method: 'getRadiusAccountingSummary';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
startTime: number;
|
startTime: number;
|
||||||
endTime: number;
|
endTime: number;
|
||||||
};
|
};
|
||||||
@@ -296,7 +296,7 @@ export interface IReq_GetRadiusStatistics extends plugins.typedrequestInterfaces
|
|||||||
> {
|
> {
|
||||||
method: 'getRadiusStatistics';
|
method: 'getRadiusStatistics';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
stats: {
|
stats: {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export interface IReq_CreateRemoteIngress extends plugins.typedrequestInterfaces
|
|||||||
> {
|
> {
|
||||||
method: 'createRemoteIngress';
|
method: 'createRemoteIngress';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
name: string;
|
name: string;
|
||||||
listenPorts?: number[];
|
listenPorts?: number[];
|
||||||
autoDerivePorts?: boolean;
|
autoDerivePorts?: boolean;
|
||||||
@@ -36,7 +36,7 @@ export interface IReq_DeleteRemoteIngress extends plugins.typedrequestInterfaces
|
|||||||
> {
|
> {
|
||||||
method: 'deleteRemoteIngress';
|
method: 'deleteRemoteIngress';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -54,7 +54,7 @@ export interface IReq_UpdateRemoteIngress extends plugins.typedrequestInterfaces
|
|||||||
> {
|
> {
|
||||||
method: 'updateRemoteIngress';
|
method: 'updateRemoteIngress';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
id: string;
|
id: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
listenPorts?: number[];
|
listenPorts?: number[];
|
||||||
@@ -77,7 +77,7 @@ export interface IReq_RegenerateRemoteIngressSecret extends plugins.typedrequest
|
|||||||
> {
|
> {
|
||||||
method: 'regenerateRemoteIngressSecret';
|
method: 'regenerateRemoteIngressSecret';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -95,7 +95,7 @@ export interface IReq_GetRemoteIngresses extends plugins.typedrequestInterfaces.
|
|||||||
> {
|
> {
|
||||||
method: 'getRemoteIngresses';
|
method: 'getRemoteIngresses';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
edges: IRemoteIngress[];
|
edges: IRemoteIngress[];
|
||||||
@@ -111,7 +111,7 @@ export interface IReq_GetRemoteIngressStatus extends plugins.typedrequestInterfa
|
|||||||
> {
|
> {
|
||||||
method: 'getRemoteIngressStatus';
|
method: 'getRemoteIngressStatus';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
statuses: IRemoteIngressStatus[];
|
statuses: IRemoteIngressStatus[];
|
||||||
@@ -128,7 +128,7 @@ export interface IReq_GetRemoteIngressConnectionToken extends plugins.typedreque
|
|||||||
> {
|
> {
|
||||||
method: 'getRemoteIngressConnectionToken';
|
method: 'getRemoteIngressConnectionToken';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
edgeId: string;
|
edgeId: string;
|
||||||
hubHost?: string;
|
hubHost?: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export interface IReq_GetServerStatistics extends plugins.typedrequestInterfaces
|
|||||||
> {
|
> {
|
||||||
method: 'getServerStatistics';
|
method: 'getServerStatistics';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
includeHistory?: boolean;
|
includeHistory?: boolean;
|
||||||
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
};
|
};
|
||||||
@@ -29,7 +29,7 @@ export interface IReq_GetEmailStatistics extends plugins.typedrequestInterfaces.
|
|||||||
> {
|
> {
|
||||||
method: 'getEmailStatistics';
|
method: 'getEmailStatistics';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
domain?: string;
|
domain?: string;
|
||||||
includeDetails?: boolean;
|
includeDetails?: boolean;
|
||||||
@@ -49,7 +49,7 @@ export interface IReq_GetDnsStatistics extends plugins.typedrequestInterfaces.im
|
|||||||
> {
|
> {
|
||||||
method: 'getDnsStatistics';
|
method: 'getDnsStatistics';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
domain?: string;
|
domain?: string;
|
||||||
includeQueryTypes?: boolean;
|
includeQueryTypes?: boolean;
|
||||||
@@ -69,7 +69,7 @@ export interface IReq_GetRateLimitStatus extends plugins.typedrequestInterfaces.
|
|||||||
> {
|
> {
|
||||||
method: 'getRateLimitStatus';
|
method: 'getRateLimitStatus';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
domain?: string;
|
domain?: string;
|
||||||
ip?: string;
|
ip?: string;
|
||||||
includeBlocked?: boolean;
|
includeBlocked?: boolean;
|
||||||
@@ -91,7 +91,7 @@ export interface IReq_GetSecurityMetrics extends plugins.typedrequestInterfaces.
|
|||||||
> {
|
> {
|
||||||
method: 'getSecurityMetrics';
|
method: 'getSecurityMetrics';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
timeRange?: '1h' | '6h' | '24h' | '7d' | '30d';
|
||||||
includeDetails?: boolean;
|
includeDetails?: boolean;
|
||||||
};
|
};
|
||||||
@@ -112,7 +112,7 @@ export interface IReq_GetActiveConnections extends plugins.typedrequestInterface
|
|||||||
> {
|
> {
|
||||||
method: 'getActiveConnections';
|
method: 'getActiveConnections';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
protocol?: 'smtp' | 'smtps' | 'http' | 'https';
|
protocol?: 'smtp' | 'smtps' | 'http' | 'https';
|
||||||
state?: string;
|
state?: string;
|
||||||
};
|
};
|
||||||
@@ -137,7 +137,7 @@ export interface IReq_GetQueueStatus extends plugins.typedrequestInterfaces.impl
|
|||||||
> {
|
> {
|
||||||
method: 'getQueueStatus';
|
method: 'getQueueStatus';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
queueName?: string;
|
queueName?: string;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
@@ -153,10 +153,31 @@ export interface IReq_GetHealthStatus extends plugins.typedrequestInterfaces.imp
|
|||||||
> {
|
> {
|
||||||
method: 'getHealthStatus';
|
method: 'getHealthStatus';
|
||||||
request: {
|
request: {
|
||||||
identity?: authInterfaces.IIdentity;
|
identity: authInterfaces.IIdentity;
|
||||||
detailed?: boolean;
|
detailed?: boolean;
|
||||||
};
|
};
|
||||||
response: {
|
response: {
|
||||||
health: statsInterfaces.IHealthStatus;
|
health: statsInterfaces.IHealthStatus;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Network Stats (raw SmartProxy network data)
|
||||||
|
export interface IReq_GetNetworkStats extends plugins.typedrequestInterfaces.implementsTR<
|
||||||
|
plugins.typedrequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetNetworkStats
|
||||||
|
> {
|
||||||
|
method: 'getNetworkStats';
|
||||||
|
request: {
|
||||||
|
identity: authInterfaces.IIdentity;
|
||||||
|
};
|
||||||
|
response: {
|
||||||
|
connectionsByIP: Array<{ ip: string; count: number }>;
|
||||||
|
throughputRate: { bytesInPerSecond: number; bytesOutPerSecond: number };
|
||||||
|
topIPs: Array<{ ip: string; count: number }>;
|
||||||
|
totalDataTransferred: { bytesIn: number; bytesOut: number };
|
||||||
|
throughputHistory: Array<{ timestamp: number; in: number; out: number }>;
|
||||||
|
throughputByIP: Array<{ ip: string; in: number; out: number }>;
|
||||||
|
requestsPerSecond: number;
|
||||||
|
requestsTotal: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/dcrouter',
|
name: '@serve.zone/dcrouter',
|
||||||
version: '10.1.5',
|
version: '11.0.0',
|
||||||
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -298,8 +298,8 @@ export const logoutAction = loginStatePart.createAction(async (statePartArg) =>
|
|||||||
// Fetch All Stats Action - Using combined endpoint for efficiency
|
// Fetch All Stats Action - Using combined endpoint for efficiency
|
||||||
export const fetchAllStatsAction = statsStatePart.createAction(async (statePartArg) => {
|
export const fetchAllStatsAction = statsStatePart.createAction(async (statePartArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
|
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
if (!context.identity) return currentState;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Use combined metrics endpoint - single request instead of 4
|
// Use combined metrics endpoint - single request instead of 4
|
||||||
@@ -340,8 +340,8 @@ export const fetchAllStatsAction = statsStatePart.createAction(async (statePartA
|
|||||||
// Fetch Configuration Action (read-only)
|
// Fetch Configuration Action (read-only)
|
||||||
export const fetchConfigurationAction = configStatePart.createAction(async (statePartArg) => {
|
export const fetchConfigurationAction = configStatePart.createAction(async (statePartArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
|
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
if (!context.identity) return currentState;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const configRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
const configRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
||||||
@@ -373,6 +373,7 @@ export const fetchRecentLogsAction = logStatePart.createAction<{
|
|||||||
category?: 'smtp' | 'dns' | 'security' | 'system' | 'email';
|
category?: 'smtp' | 'dns' | 'security' | 'system' | 'email';
|
||||||
}>(async (statePartArg, dataArg) => {
|
}>(async (statePartArg, dataArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
|
if (!context.identity) return statePartArg.getState();
|
||||||
|
|
||||||
const logsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
const logsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
||||||
interfaces.requests.IReq_GetRecentLogs
|
interfaces.requests.IReq_GetRecentLogs
|
||||||
@@ -448,8 +449,8 @@ export const setActiveViewAction = uiStatePart.createAction<string>(async (state
|
|||||||
// Fetch Network Stats Action
|
// Fetch Network Stats Action
|
||||||
export const fetchNetworkStatsAction = networkStatePart.createAction(async (statePartArg) => {
|
export const fetchNetworkStatsAction = networkStatePart.createAction(async (statePartArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
|
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
if (!context.identity) return currentState;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Fetch active connections using the existing endpoint
|
// Fetch active connections using the existing endpoint
|
||||||
@@ -522,6 +523,7 @@ export const fetchNetworkStatsAction = networkStatePart.createAction(async (stat
|
|||||||
export const fetchAllEmailsAction = emailOpsStatePart.createAction(async (statePartArg) => {
|
export const fetchAllEmailsAction = emailOpsStatePart.createAction(async (statePartArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
if (!context.identity) return currentState;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
||||||
@@ -554,6 +556,7 @@ export const fetchAllEmailsAction = emailOpsStatePart.createAction(async (stateP
|
|||||||
export const fetchCertificateOverviewAction = certificateStatePart.createAction(async (statePartArg) => {
|
export const fetchCertificateOverviewAction = certificateStatePart.createAction(async (statePartArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
if (!context.identity) return currentState;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
||||||
@@ -581,7 +584,7 @@ export const fetchCertificateOverviewAction = certificateStatePart.createAction(
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const reprovisionCertificateAction = certificateStatePart.createAction<string>(
|
export const reprovisionCertificateAction = certificateStatePart.createAction<string>(
|
||||||
async (statePartArg, domain) => {
|
async (statePartArg, domain, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -596,8 +599,7 @@ export const reprovisionCertificateAction = certificateStatePart.createAction<st
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Re-fetch overview after reprovisioning
|
// Re-fetch overview after reprovisioning
|
||||||
await certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null);
|
return await actionContext.dispatch(fetchCertificateOverviewAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -608,7 +610,7 @@ export const reprovisionCertificateAction = certificateStatePart.createAction<st
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const deleteCertificateAction = certificateStatePart.createAction<string>(
|
export const deleteCertificateAction = certificateStatePart.createAction<string>(
|
||||||
async (statePartArg, domain) => {
|
async (statePartArg, domain, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -623,8 +625,7 @@ export const deleteCertificateAction = certificateStatePart.createAction<string>
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Re-fetch overview after deletion
|
// Re-fetch overview after deletion
|
||||||
await certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null);
|
return await actionContext.dispatch(fetchCertificateOverviewAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -643,7 +644,7 @@ export const importCertificateAction = certificateStatePart.createAction<{
|
|||||||
publicKey: string;
|
publicKey: string;
|
||||||
csr: string;
|
csr: string;
|
||||||
}>(
|
}>(
|
||||||
async (statePartArg, cert) => {
|
async (statePartArg, cert, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -658,8 +659,7 @@ export const importCertificateAction = certificateStatePart.createAction<{
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Re-fetch overview after import
|
// Re-fetch overview after import
|
||||||
await certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null);
|
return await actionContext.dispatch(fetchCertificateOverviewAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -700,6 +700,7 @@ export async function fetchConnectionToken(edgeId: string) {
|
|||||||
export const fetchRemoteIngressAction = remoteIngressStatePart.createAction(async (statePartArg) => {
|
export const fetchRemoteIngressAction = remoteIngressStatePart.createAction(async (statePartArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
if (!context.identity) return currentState;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const edgesRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
const edgesRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
||||||
@@ -737,7 +738,7 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|||||||
listenPorts?: number[];
|
listenPorts?: number[];
|
||||||
autoDerivePorts?: boolean;
|
autoDerivePorts?: boolean;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
}>(async (statePartArg, dataArg) => {
|
}>(async (statePartArg, dataArg, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -756,7 +757,7 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
// Refresh the list
|
// Refresh the list
|
||||||
await remoteIngressStatePart.dispatchAction(fetchRemoteIngressAction, null);
|
await actionContext.dispatch(fetchRemoteIngressAction, null);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...statePartArg.getState(),
|
...statePartArg.getState(),
|
||||||
@@ -774,7 +775,7 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const deleteRemoteIngressAction = remoteIngressStatePart.createAction<string>(
|
export const deleteRemoteIngressAction = remoteIngressStatePart.createAction<string>(
|
||||||
async (statePartArg, edgeId) => {
|
async (statePartArg, edgeId, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -788,8 +789,7 @@ export const deleteRemoteIngressAction = remoteIngressStatePart.createAction<str
|
|||||||
id: edgeId,
|
id: edgeId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await remoteIngressStatePart.dispatchAction(fetchRemoteIngressAction, null);
|
return await actionContext.dispatch(fetchRemoteIngressAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -805,7 +805,7 @@ export const updateRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|||||||
listenPorts?: number[];
|
listenPorts?: number[];
|
||||||
autoDerivePorts?: boolean;
|
autoDerivePorts?: boolean;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
}>(async (statePartArg, dataArg) => {
|
}>(async (statePartArg, dataArg, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -823,8 +823,7 @@ export const updateRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|||||||
tags: dataArg.tags,
|
tags: dataArg.tags,
|
||||||
});
|
});
|
||||||
|
|
||||||
await remoteIngressStatePart.dispatchAction(fetchRemoteIngressAction, null);
|
return await actionContext.dispatch(fetchRemoteIngressAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -877,7 +876,7 @@ export const clearNewEdgeIdAction = remoteIngressStatePart.createAction(
|
|||||||
export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{
|
export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{
|
||||||
id: string;
|
id: string;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
}>(async (statePartArg, dataArg) => {
|
}>(async (statePartArg, dataArg, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -892,8 +891,7 @@ export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|||||||
enabled: dataArg.enabled,
|
enabled: dataArg.enabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
await remoteIngressStatePart.dispatchAction(fetchRemoteIngressAction, null);
|
return await actionContext.dispatch(fetchRemoteIngressAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -909,6 +907,7 @@ export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{
|
|||||||
export const fetchMergedRoutesAction = routeManagementStatePart.createAction(async (statePartArg) => {
|
export const fetchMergedRoutesAction = routeManagementStatePart.createAction(async (statePartArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
if (!context.identity) return currentState;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
||||||
@@ -939,7 +938,7 @@ export const fetchMergedRoutesAction = routeManagementStatePart.createAction(asy
|
|||||||
export const createRouteAction = routeManagementStatePart.createAction<{
|
export const createRouteAction = routeManagementStatePart.createAction<{
|
||||||
route: any;
|
route: any;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
}>(async (statePartArg, dataArg) => {
|
}>(async (statePartArg, dataArg, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -954,8 +953,7 @@ export const createRouteAction = routeManagementStatePart.createAction<{
|
|||||||
enabled: dataArg.enabled,
|
enabled: dataArg.enabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null);
|
return await actionContext.dispatch(fetchMergedRoutesAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -965,7 +963,7 @@ export const createRouteAction = routeManagementStatePart.createAction<{
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const deleteRouteAction = routeManagementStatePart.createAction<string>(
|
export const deleteRouteAction = routeManagementStatePart.createAction<string>(
|
||||||
async (statePartArg, routeId) => {
|
async (statePartArg, routeId, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -979,8 +977,7 @@ export const deleteRouteAction = routeManagementStatePart.createAction<string>(
|
|||||||
id: routeId,
|
id: routeId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null);
|
return await actionContext.dispatch(fetchMergedRoutesAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -993,7 +990,7 @@ export const deleteRouteAction = routeManagementStatePart.createAction<string>(
|
|||||||
export const toggleRouteAction = routeManagementStatePart.createAction<{
|
export const toggleRouteAction = routeManagementStatePart.createAction<{
|
||||||
id: string;
|
id: string;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
}>(async (statePartArg, dataArg) => {
|
}>(async (statePartArg, dataArg, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -1008,8 +1005,7 @@ export const toggleRouteAction = routeManagementStatePart.createAction<{
|
|||||||
enabled: dataArg.enabled,
|
enabled: dataArg.enabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null);
|
return await actionContext.dispatch(fetchMergedRoutesAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -1021,7 +1017,7 @@ export const toggleRouteAction = routeManagementStatePart.createAction<{
|
|||||||
export const setRouteOverrideAction = routeManagementStatePart.createAction<{
|
export const setRouteOverrideAction = routeManagementStatePart.createAction<{
|
||||||
routeName: string;
|
routeName: string;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
}>(async (statePartArg, dataArg) => {
|
}>(async (statePartArg, dataArg, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -1036,8 +1032,7 @@ export const setRouteOverrideAction = routeManagementStatePart.createAction<{
|
|||||||
enabled: dataArg.enabled,
|
enabled: dataArg.enabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null);
|
return await actionContext.dispatch(fetchMergedRoutesAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -1047,7 +1042,7 @@ export const setRouteOverrideAction = routeManagementStatePart.createAction<{
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const removeRouteOverrideAction = routeManagementStatePart.createAction<string>(
|
export const removeRouteOverrideAction = routeManagementStatePart.createAction<string>(
|
||||||
async (statePartArg, routeName) => {
|
async (statePartArg, routeName, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -1061,8 +1056,7 @@ export const removeRouteOverrideAction = routeManagementStatePart.createAction<s
|
|||||||
routeName,
|
routeName,
|
||||||
});
|
});
|
||||||
|
|
||||||
await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null);
|
return await actionContext.dispatch(fetchMergedRoutesAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -1079,6 +1073,7 @@ export const removeRouteOverrideAction = routeManagementStatePart.createAction<s
|
|||||||
export const fetchApiTokensAction = routeManagementStatePart.createAction(async (statePartArg) => {
|
export const fetchApiTokensAction = routeManagementStatePart.createAction(async (statePartArg) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
if (!context.identity) return currentState;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
||||||
@@ -1128,7 +1123,7 @@ export async function rollApiToken(id: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const revokeApiTokenAction = routeManagementStatePart.createAction<string>(
|
export const revokeApiTokenAction = routeManagementStatePart.createAction<string>(
|
||||||
async (statePartArg, tokenId) => {
|
async (statePartArg, tokenId, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -1142,8 +1137,7 @@ export const revokeApiTokenAction = routeManagementStatePart.createAction<string
|
|||||||
id: tokenId,
|
id: tokenId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await routeManagementStatePart.dispatchAction(fetchApiTokensAction, null);
|
return await actionContext.dispatch(fetchApiTokensAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -1156,7 +1150,7 @@ export const revokeApiTokenAction = routeManagementStatePart.createAction<string
|
|||||||
export const toggleApiTokenAction = routeManagementStatePart.createAction<{
|
export const toggleApiTokenAction = routeManagementStatePart.createAction<{
|
||||||
id: string;
|
id: string;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
}>(async (statePartArg, dataArg) => {
|
}>(async (statePartArg, dataArg, actionContext) => {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
const currentState = statePartArg.getState();
|
const currentState = statePartArg.getState();
|
||||||
|
|
||||||
@@ -1171,8 +1165,7 @@ export const toggleApiTokenAction = routeManagementStatePart.createAction<{
|
|||||||
enabled: dataArg.enabled,
|
enabled: dataArg.enabled,
|
||||||
});
|
});
|
||||||
|
|
||||||
await routeManagementStatePart.dispatchAction(fetchApiTokensAction, null);
|
return await actionContext.dispatch(fetchApiTokensAction, null);
|
||||||
return statePartArg.getState();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
...currentState,
|
...currentState,
|
||||||
@@ -1233,6 +1226,7 @@ async function disconnectSocket() {
|
|||||||
// Combined refresh action for efficient polling
|
// Combined refresh action for efficient polling
|
||||||
async function dispatchCombinedRefreshAction() {
|
async function dispatchCombinedRefreshAction() {
|
||||||
const context = getActionContext();
|
const context = getActionContext();
|
||||||
|
if (!context.identity) return;
|
||||||
const currentView = uiStatePart.getState().activeView;
|
const currentView = uiStatePart.getState().activeView;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ export class OpsViewApiTokens extends DeesElement {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Roll',
|
name: 'Roll',
|
||||||
iconName: 'lucide:rotate-cw',
|
iconName: 'lucide:rotateCw',
|
||||||
type: ['inRow', 'contextmenu'] as any,
|
type: ['inRow', 'contextmenu'] as any,
|
||||||
actionFunc: async (actionData: any) => {
|
actionFunc: async (actionData: any) => {
|
||||||
const token = actionData.item as interfaces.data.IApiTokenInfo;
|
const token = actionData.item as interfaces.data.IApiTokenInfo;
|
||||||
@@ -306,7 +306,7 @@ export class OpsViewApiTokens extends DeesElement {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Roll Token',
|
name: 'Roll Token',
|
||||||
iconName: 'lucide:rotate-cw',
|
iconName: 'lucide:rotateCw',
|
||||||
action: async (modalArg: any) => {
|
action: async (modalArg: any) => {
|
||||||
await modalArg.destroy();
|
await modalArg.destroy();
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user