Compare commits

..

6 Commits

Author SHA1 Message Date
336e8aa4cc v12.9.3
Some checks failed
Docker (tags) / security (push) Failing after 3s
Docker (tags) / test (push) Has been skipped
Docker (tags) / release (push) Has been skipped
Docker (tags) / metadata (push) Has been skipped
2026-04-04 19:29:49 +00:00
c8f19cf783 fix(route-management): include stored VPN routes in domain resolution and align programmatic route types with dcrouter configs 2026-04-04 19:29:49 +00:00
12b2cc11da v12.9.2
Some checks failed
Docker (tags) / security (push) Failing after 3s
Docker (tags) / test (push) Has been skipped
Docker (tags) / release (push) Has been skipped
Docker (tags) / metadata (push) Has been skipped
2026-04-04 19:03:11 +00:00
ffcc35be64 fix(config-ui): handle missing HTTP/3 config safely and standardize overview section headings 2026-04-04 19:03:11 +00:00
59e0d41bdb v12.9.1
Some checks failed
Docker (tags) / security (push) Failing after 2s
Docker (tags) / test (push) Has been skipped
Docker (tags) / release (push) Has been skipped
Docker (tags) / metadata (push) Has been skipped
2026-04-04 17:08:05 +00:00
9509d87b1e fix(monitoring): update SmartProxy and use direct connection protocol metrics access 2026-04-04 17:08:05 +00:00
12 changed files with 79 additions and 35 deletions

View File

@@ -1,5 +1,25 @@
# Changelog
## 2026-04-04 - 12.9.3 - fix(route-management)
include stored VPN routes in domain resolution and align programmatic route types with dcrouter configs
- Scans enabled stored/programmatic routes for VPN domain matches when resolving client access domains.
- Replaces generic smartproxy route typings with IDcRouterRouteConfig across route management and stored route models.
- Updates @push.rocks/smartproxy to ^27.4.0.
## 2026-04-04 - 12.9.2 - fix(config-ui)
handle missing HTTP/3 config safely and standardize overview section headings
- Prevents route augmentation logic from failing when HTTP/3 configuration is undefined by using optional chaining.
- Updates the operations overview to use dees-heading components for activity, email, DNS, RADIUS, and VPN section headings.
- Bumps @push.rocks/smartproxy from ^27.2.0 to ^27.3.1.
## 2026-04-04 - 12.9.1 - fix(monitoring)
update SmartProxy and use direct connection protocol metrics access
- bump @push.rocks/smartproxy from ^27.1.0 to ^27.2.0
- replace fallback any-based access with direct frontend and backend protocol metric calls in MetricsManager
## 2026-04-04 - 12.9.0 - feat(monitoring)
add frontend and backend protocol distribution metrics to network stats

View File

@@ -1,7 +1,7 @@
{
"name": "@serve.zone/dcrouter",
"private": false,
"version": "12.9.0",
"version": "12.9.3",
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
"type": "module",
"exports": {
@@ -53,7 +53,7 @@
"@push.rocks/smartnetwork": "^4.5.2",
"@push.rocks/smartpath": "^6.0.0",
"@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smartproxy": "^27.1.0",
"@push.rocks/smartproxy": "^27.4.0",
"@push.rocks/smartradius": "^1.1.1",
"@push.rocks/smartrequest": "^5.0.1",
"@push.rocks/smartrx": "^3.0.10",

22
pnpm-lock.yaml generated
View File

@@ -78,8 +78,8 @@ importers:
specifier: ^4.2.3
version: 4.2.3
'@push.rocks/smartproxy':
specifier: ^27.1.0
version: 27.1.0
specifier: ^27.4.0
version: 27.4.0
'@push.rocks/smartradius':
specifier: ^1.1.1
version: 1.1.1
@@ -1279,8 +1279,8 @@ packages:
'@push.rocks/smartpromise@4.2.3':
resolution: {integrity: sha512-Ycg/TJR+tMt+S3wSFurOpEoW6nXv12QBtKXgBcjMZ4RsdO28geN46U09osPn9N9WuwQy1PkmTV5J/V4F9U8qEw==}
'@push.rocks/smartproxy@27.1.0':
resolution: {integrity: sha512-uMtmbT6/9Y+lOnSi4w6SRICWJr9q9bHsYAq6xMLmym3zvnEzEwJWF6sw4Jb/uEFEjI2/e4irNSQ9Ba74DhFRlg==}
'@push.rocks/smartproxy@27.4.0':
resolution: {integrity: sha512-r6ym6+FpiHHLFgCdY0KfCe8s2eLuLUU/daXIcKwsmMHNY3BOlBIxwN5CL17+v2Hvh7Lg2JWBY+1L7/7ehYXj1w==}
'@push.rocks/smartpuppeteer@2.0.5':
resolution: {integrity: sha512-yK/qSeWVHIGWRp3c8S5tfdGP6WCKllZC4DR8d8CQlEjszOSBmHtlTdyyqOMBZ/BA4kd+eU5f3A1r4K2tGYty1g==}
@@ -3303,6 +3303,10 @@ packages:
resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==}
engines: {node: 18 || 20 || >=22}
minimatch@10.2.5:
resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
engines: {node: 18 || 20 || >=22}
minimatch@3.1.5:
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
@@ -6518,14 +6522,14 @@ snapshots:
'@push.rocks/smartpromise@4.2.3': {}
'@push.rocks/smartproxy@27.1.0':
'@push.rocks/smartproxy@27.4.0':
dependencies:
'@push.rocks/smartcrypto': 2.0.4
'@push.rocks/smartlog': 3.2.1
'@push.rocks/smartnftables': 1.0.1
'@push.rocks/smartnftables': 1.1.0
'@push.rocks/smartrust': 1.3.2
'@tsclass/tsclass': 9.5.0
minimatch: 10.2.4
minimatch: 10.2.5
'@push.rocks/smartpuppeteer@2.0.5(typescript@6.0.2)':
dependencies:
@@ -9063,6 +9067,10 @@ snapshots:
dependencies:
brace-expansion: 5.0.5
minimatch@10.2.5:
dependencies:
brace-expansion: 5.0.5
minimatch@3.1.5:
dependencies:
brace-expansion: 1.1.13

View File

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

View File

@@ -2164,6 +2164,26 @@ export class DcRouter {
}
}
// Also scan stored/programmatic routes
const storedRoutes = this.routeConfigManager?.getStoredRoutes();
if (storedRoutes) {
for (const [, stored] of storedRoutes) {
if (!stored.enabled) continue;
const dcRoute = stored.route as import('../ts_interfaces/data/remoteingress.js').IDcRouterRouteConfig;
if (!dcRoute.vpn?.enabled) continue;
const routeTags = dcRoute.vpn.allowedServerDefinedClientTags;
if (!routeTags?.length || clientTags.some(t => routeTags.includes(t))) {
const domains = (stored.route.match as any)?.domains;
if (Array.isArray(domains)) {
for (const d of domains) {
domainsToResolve.add(d.replace(/^\*\./, ''));
}
}
}
}
}
// Resolve DNS A records for matched domains (with caching)
for (const domain of domainsToResolve) {
const resolvedIps = await this.resolveVpnDomainIPs(domain);

View File

@@ -83,7 +83,7 @@ export class RouteConfigManager {
// =========================================================================
public async createRoute(
route: plugins.smartproxy.IRouteConfig,
route: IDcRouterRouteConfig,
createdBy: string,
enabled = true,
metadata?: IRouteMetadata,
@@ -123,7 +123,7 @@ export class RouteConfigManager {
public async updateRoute(
id: string,
patch: {
route?: Partial<plugins.smartproxy.IRouteConfig>;
route?: Partial<IDcRouterRouteConfig>;
enabled?: boolean;
metadata?: Partial<IRouteMetadata>;
},
@@ -132,7 +132,7 @@ export class RouteConfigManager {
if (!stored) return false;
if (patch.route) {
stored.route = { ...stored.route, ...patch.route } as plugins.smartproxy.IRouteConfig;
stored.route = { ...stored.route, ...patch.route } as IDcRouterRouteConfig;
}
if (patch.enabled !== undefined) {
stored.enabled = patch.enabled;
@@ -386,7 +386,7 @@ export class RouteConfigManager {
for (const stored of this.storedRoutes.values()) {
if (stored.enabled) {
let route = stored.route;
if (http3Config && http3Config.enabled !== false) {
if (http3Config?.enabled !== false) {
route = augmentRouteWithHttp3(route, { enabled: true, ...http3Config });
}
enabledRoutes.push(injectVpn(route));

View File

@@ -1,6 +1,7 @@
import * as plugins from '../../plugins.js';
import { DcRouterDb } from '../classes.dcrouter-db.js';
import type { IRouteMetadata } from '../../../ts_interfaces/data/route-management.js';
import type { IDcRouterRouteConfig } from '../../../ts_interfaces/data/remoteingress.js';
const getDb = () => DcRouterDb.getInstance().getDb();
@@ -11,7 +12,7 @@ export class StoredRouteDoc extends plugins.smartdata.SmartDataDbDoc<StoredRoute
public id!: string;
@plugins.smartdata.svDb()
public route!: plugins.smartproxy.IRouteConfig;
public route!: IDcRouterRouteConfig;
@plugins.smartdata.svDb()
public enabled!: boolean;

View File

@@ -591,10 +591,9 @@ export class MetricsManager {
const requestsPerSecond = proxyMetrics.requests.perSecond();
const requestsTotal = proxyMetrics.requests.total();
// Get frontend/backend protocol distribution (available in SmartProxy >= next release)
const conn = proxyMetrics.connections as any;
const frontendProtocols = conn.frontendProtocols?.() ?? null;
const backendProtocols = conn.backendProtocols?.() ?? null;
// Get frontend/backend protocol distribution
const frontendProtocols = proxyMetrics.connections.frontendProtocols() ?? null;
const backendProtocols = proxyMetrics.connections.backendProtocols() ?? null;
// Collect backend protocol data
const backendMetrics = proxyMetrics.backends.byBackend();

View File

@@ -1,4 +1,5 @@
import type { IRouteConfig } from '@push.rocks/smartproxy';
import type { IDcRouterRouteConfig } from './remoteingress.js';
// Derive IRouteSecurity from IRouteConfig since it's not directly exported
export type IRouteSecurity = NonNullable<IRouteConfig['security']>;
@@ -77,7 +78,7 @@ export interface IRouteMetadata {
* A merged route combining hardcoded and programmatic sources.
*/
export interface IMergedRoute {
route: IRouteConfig;
route: IDcRouterRouteConfig;
source: 'hardcoded' | 'programmatic';
enabled: boolean;
overridden: boolean;
@@ -118,7 +119,7 @@ export interface IApiTokenInfo {
*/
export interface IStoredRoute {
id: string;
route: IRouteConfig;
route: IDcRouterRouteConfig;
enabled: boolean;
createdAt: number;
updatedAt: number;

View File

@@ -2,6 +2,7 @@ import * as plugins from '../plugins.js';
import type * as authInterfaces from '../data/auth.js';
import type { IMergedRoute, IRouteWarning, IRouteMetadata } from '../data/route-management.js';
import type { IRouteConfig } from '@push.rocks/smartproxy';
import type { IDcRouterRouteConfig } from '../data/remoteingress.js';
// ============================================================================
// Route Management Endpoints
@@ -36,7 +37,7 @@ export interface IReq_CreateRoute extends plugins.typedrequestInterfaces.impleme
request: {
identity?: authInterfaces.IIdentity;
apiToken?: string;
route: IRouteConfig;
route: IDcRouterRouteConfig;
enabled?: boolean;
metadata?: IRouteMetadata;
};
@@ -59,7 +60,7 @@ export interface IReq_UpdateRoute extends plugins.typedrequestInterfaces.impleme
identity?: authInterfaces.IIdentity;
apiToken?: string;
id: string;
route?: Partial<IRouteConfig>;
route?: Partial<IDcRouterRouteConfig>;
enabled?: boolean;
metadata?: Partial<IRouteMetadata>;
};

View File

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

View File

@@ -64,13 +64,6 @@ export class OpsViewOverview extends DeesElement {
cssManager.defaultStyles,
shared.viewHostCss,
css`
h2 {
margin: 32px 0 16px 0;
font-size: 24px;
font-weight: 600;
color: ${cssManager.bdTheme('#333', '#ccc')};
}
.chartGrid {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -123,6 +116,7 @@ export class OpsViewOverview extends DeesElement {
${this.renderVpnStats()}
<dees-heading level="hr">Activity Charts</dees-heading>
<div class="chartGrid">
<dees-chart-area
.label=${'Email Traffic (24h)'}
@@ -330,7 +324,7 @@ export class OpsViewOverview extends DeesElement {
];
return html`
<h2>Email Statistics</h2>
<dees-heading level="hr">Email Statistics</dees-heading>
<dees-statsgrid .tiles=${tiles}></dees-statsgrid>
`;
}
@@ -379,7 +373,7 @@ export class OpsViewOverview extends DeesElement {
];
return html`
<h2>DNS Statistics</h2>
<dees-heading level="hr">DNS Statistics</dees-heading>
<dees-statsgrid .tiles=${tiles}></dees-statsgrid>
`;
}
@@ -430,7 +424,7 @@ export class OpsViewOverview extends DeesElement {
];
return html`
<h2>RADIUS Statistics</h2>
<dees-heading level="hr">RADIUS Statistics</dees-heading>
<dees-statsgrid .tiles=${tiles}></dees-statsgrid>
`;
}
@@ -470,7 +464,7 @@ export class OpsViewOverview extends DeesElement {
];
return html`
<h2>VPN Statistics</h2>
<dees-heading level="hr">VPN Statistics</dees-heading>
<dees-statsgrid .tiles=${tiles}></dees-statsgrid>
`;
}