@serve.zone/dcrouter 11.0.39 → 11.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist_serve/bundle.js +1 -1
  2. package/dist_ts/errors/base.errors.js +320 -0
  3. package/dist_ts/errors/error.codes.d.ts +115 -0
  4. package/dist_ts/errors/error.codes.js +136 -0
  5. package/dist_ts/monitoring/classes.metricsmanager.d.ts +178 -0
  6. package/dist_ts/monitoring/classes.metricsmanager.js +642 -0
  7. package/dist_ts/monitoring/index.d.ts +1 -0
  8. package/dist_ts/monitoring/index.js +2 -0
  9. package/dist_ts/opsserver/classes.opsserver.d.ts +37 -0
  10. package/dist_ts/opsserver/classes.opsserver.js +85 -0
  11. package/dist_ts/opsserver/handlers/api-token.handler.d.ts +6 -0
  12. package/dist_ts/opsserver/handlers/api-token.handler.js +62 -0
  13. package/dist_ts/opsserver/handlers/certificate.handler.d.ts +32 -0
  14. package/dist_ts/opsserver/handlers/certificate.handler.js +421 -0
  15. package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +30 -0
  16. package/dist_ts/opsserver/handlers/email-ops.handler.js +227 -0
  17. package/dist_ts/opsserver/handlers/index.d.ts +11 -0
  18. package/dist_ts/opsserver/handlers/index.js +12 -0
  19. package/dist_ts/opsserver/handlers/radius.handler.d.ts +6 -0
  20. package/dist_ts/opsserver/handlers/radius.handler.js +295 -0
  21. package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +6 -0
  22. package/dist_ts/opsserver/handlers/remoteingress.handler.js +156 -0
  23. package/dist_ts/opsserver/handlers/route-management.handler.d.ts +14 -0
  24. package/dist_ts/opsserver/handlers/route-management.handler.js +117 -0
  25. package/dist_ts/opsserver/handlers/security.handler.d.ts +9 -0
  26. package/dist_ts/opsserver/handlers/security.handler.js +231 -0
  27. package/dist_ts/opsserver/handlers/stats.handler.d.ts +11 -0
  28. package/dist_ts/opsserver/handlers/stats.handler.js +399 -0
  29. package/dist_ts/opsserver/helpers/guards.d.ts +27 -0
  30. package/dist_ts/opsserver/helpers/guards.js +43 -0
  31. package/dist_ts/opsserver/index.d.ts +1 -0
  32. package/dist_ts/opsserver/index.js +2 -0
  33. package/dist_ts/radius/classes.accounting.manager.d.ts +218 -0
  34. package/dist_ts/radius/classes.accounting.manager.js +417 -0
  35. package/dist_ts/radius/classes.radius.server.d.ts +171 -0
  36. package/dist_ts/radius/classes.radius.server.js +385 -0
  37. package/dist_ts/radius/classes.vlan.manager.d.ts +128 -0
  38. package/dist_ts/radius/classes.vlan.manager.js +279 -0
  39. package/dist_ts/radius/index.d.ts +13 -0
  40. package/dist_ts/radius/index.js +14 -0
  41. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +82 -0
  42. package/dist_ts/remoteingress/classes.remoteingress-manager.js +227 -0
  43. package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +59 -0
  44. package/dist_ts/remoteingress/classes.tunnel-manager.js +165 -0
  45. package/dist_ts/remoteingress/index.d.ts +2 -0
  46. package/dist_ts/remoteingress/index.js +3 -0
  47. package/dist_ts_web/00_commitinfo_data.js +1 -1
  48. package/package.json +2 -2
  49. package/ts/00_commitinfo_data.ts +1 -1
  50. package/ts_web/00_commitinfo_data.ts +1 -1
@@ -0,0 +1,128 @@
1
+ import type { StorageManager } from '../storage/index.js';
2
+ /**
3
+ * MAC address to VLAN mapping
4
+ */
5
+ export interface IMacVlanMapping {
6
+ /** MAC address (full) or OUI pattern (e.g., "00:11:22" for vendor prefix) */
7
+ mac: string;
8
+ /** VLAN ID to assign */
9
+ vlan: number;
10
+ /** Optional description */
11
+ description?: string;
12
+ /** Whether this mapping is enabled */
13
+ enabled: boolean;
14
+ /** Creation timestamp */
15
+ createdAt: number;
16
+ /** Last update timestamp */
17
+ updatedAt: number;
18
+ }
19
+ /**
20
+ * VLAN assignment result
21
+ */
22
+ export interface IVlanAssignmentResult {
23
+ /** Whether a VLAN was successfully assigned */
24
+ assigned: boolean;
25
+ /** The assigned VLAN ID (or default if not matched) */
26
+ vlan: number;
27
+ /** The matching rule (if any) */
28
+ matchedRule?: IMacVlanMapping;
29
+ /** Whether default VLAN was used */
30
+ isDefault: boolean;
31
+ }
32
+ /**
33
+ * VlanManager configuration
34
+ */
35
+ export interface IVlanManagerConfig {
36
+ /** Default VLAN for unknown MACs */
37
+ defaultVlan?: number;
38
+ /** Whether to allow unknown MACs (assign default VLAN) or reject */
39
+ allowUnknownMacs?: boolean;
40
+ /** Storage key prefix for persistence */
41
+ storagePrefix?: string;
42
+ }
43
+ /**
44
+ * Manages MAC address to VLAN mappings with support for:
45
+ * - Exact MAC address matching
46
+ * - OUI (vendor prefix) pattern matching
47
+ * - Wildcard patterns
48
+ * - Default VLAN for unknown devices
49
+ */
50
+ export declare class VlanManager {
51
+ private mappings;
52
+ private config;
53
+ private storageManager?;
54
+ private normalizedMacCache;
55
+ constructor(config?: IVlanManagerConfig, storageManager?: StorageManager);
56
+ /**
57
+ * Initialize the VLAN manager and load persisted mappings
58
+ */
59
+ initialize(): Promise<void>;
60
+ /**
61
+ * Normalize a MAC address to lowercase with colons
62
+ * Accepts formats: 00:11:22:33:44:55, 00-11-22-33-44-55, 001122334455
63
+ */
64
+ normalizeMac(mac: string): string;
65
+ /**
66
+ * Check if a MAC address matches a pattern
67
+ * Supports:
68
+ * - Exact match: "00:11:22:33:44:55"
69
+ * - OUI match: "00:11:22" (matches any device with this vendor prefix)
70
+ * - Wildcard: "*" (matches all)
71
+ */
72
+ macMatchesPattern(mac: string, pattern: string): boolean;
73
+ /**
74
+ * Add or update a MAC to VLAN mapping
75
+ */
76
+ addMapping(mapping: Omit<IMacVlanMapping, 'createdAt' | 'updatedAt'>): Promise<IMacVlanMapping>;
77
+ /**
78
+ * Remove a MAC to VLAN mapping
79
+ */
80
+ removeMapping(mac: string): Promise<boolean>;
81
+ /**
82
+ * Get a specific mapping by MAC
83
+ */
84
+ getMapping(mac: string): IMacVlanMapping | undefined;
85
+ /**
86
+ * Get all mappings
87
+ */
88
+ getAllMappings(): IMacVlanMapping[];
89
+ /**
90
+ * Determine VLAN assignment for a MAC address
91
+ * Returns the most specific matching rule (exact > OUI > wildcard > default)
92
+ */
93
+ assignVlan(mac: string): IVlanAssignmentResult;
94
+ /**
95
+ * Bulk import mappings
96
+ */
97
+ importMappings(mappings: Array<Omit<IMacVlanMapping, 'createdAt' | 'updatedAt'>>): Promise<number>;
98
+ /**
99
+ * Export all mappings
100
+ */
101
+ exportMappings(): IMacVlanMapping[];
102
+ /**
103
+ * Update configuration
104
+ */
105
+ updateConfig(config: Partial<IVlanManagerConfig>): void;
106
+ /**
107
+ * Get current configuration
108
+ */
109
+ getConfig(): Required<IVlanManagerConfig>;
110
+ /**
111
+ * Get statistics
112
+ */
113
+ getStats(): {
114
+ totalMappings: number;
115
+ enabledMappings: number;
116
+ exactMatches: number;
117
+ ouiPatterns: number;
118
+ wildcardPatterns: number;
119
+ };
120
+ /**
121
+ * Load mappings from storage
122
+ */
123
+ private loadMappings;
124
+ /**
125
+ * Save mappings to storage
126
+ */
127
+ private saveMappings;
128
+ }
@@ -0,0 +1,279 @@
1
+ import * as plugins from '../plugins.js';
2
+ import { logger } from '../logger.js';
3
+ /**
4
+ * Manages MAC address to VLAN mappings with support for:
5
+ * - Exact MAC address matching
6
+ * - OUI (vendor prefix) pattern matching
7
+ * - Wildcard patterns
8
+ * - Default VLAN for unknown devices
9
+ */
10
+ export class VlanManager {
11
+ mappings = new Map();
12
+ config;
13
+ storageManager;
14
+ // Cache for normalized MAC lookups
15
+ normalizedMacCache = new Map();
16
+ constructor(config, storageManager) {
17
+ this.config = {
18
+ defaultVlan: config?.defaultVlan ?? 1,
19
+ allowUnknownMacs: config?.allowUnknownMacs ?? true,
20
+ storagePrefix: config?.storagePrefix ?? '/radius/vlan-mappings',
21
+ };
22
+ this.storageManager = storageManager;
23
+ }
24
+ /**
25
+ * Initialize the VLAN manager and load persisted mappings
26
+ */
27
+ async initialize() {
28
+ if (this.storageManager) {
29
+ await this.loadMappings();
30
+ }
31
+ logger.log('info', `VlanManager initialized with ${this.mappings.size} mappings, default VLAN: ${this.config.defaultVlan}`);
32
+ }
33
+ /**
34
+ * Normalize a MAC address to lowercase with colons
35
+ * Accepts formats: 00:11:22:33:44:55, 00-11-22-33-44-55, 001122334455
36
+ */
37
+ normalizeMac(mac) {
38
+ // Check cache first
39
+ const cached = this.normalizedMacCache.get(mac);
40
+ if (cached) {
41
+ return cached;
42
+ }
43
+ // Remove all separators and convert to lowercase
44
+ const cleaned = mac.toLowerCase().replace(/[-:]/g, '');
45
+ // Format with colons
46
+ const normalized = cleaned.match(/.{1,2}/g)?.join(':') || mac.toLowerCase();
47
+ // Cache the result
48
+ this.normalizedMacCache.set(mac, normalized);
49
+ // Prevent unbounded cache growth
50
+ if (this.normalizedMacCache.size > 10000) {
51
+ const iterator = this.normalizedMacCache.keys();
52
+ for (let i = 0; i < 1000; i++) {
53
+ this.normalizedMacCache.delete(iterator.next().value);
54
+ }
55
+ }
56
+ return normalized;
57
+ }
58
+ /**
59
+ * Check if a MAC address matches a pattern
60
+ * Supports:
61
+ * - Exact match: "00:11:22:33:44:55"
62
+ * - OUI match: "00:11:22" (matches any device with this vendor prefix)
63
+ * - Wildcard: "*" (matches all)
64
+ */
65
+ macMatchesPattern(mac, pattern) {
66
+ const normalizedMac = this.normalizeMac(mac);
67
+ const normalizedPattern = this.normalizeMac(pattern);
68
+ // Wildcard matches all
69
+ if (pattern === '*') {
70
+ return true;
71
+ }
72
+ // Exact match
73
+ if (normalizedMac === normalizedPattern) {
74
+ return true;
75
+ }
76
+ // OUI/prefix match (pattern is shorter than full MAC)
77
+ if (normalizedPattern.length < 17 && normalizedMac.startsWith(normalizedPattern)) {
78
+ return true;
79
+ }
80
+ return false;
81
+ }
82
+ /**
83
+ * Add or update a MAC to VLAN mapping
84
+ */
85
+ async addMapping(mapping) {
86
+ const normalizedMac = this.normalizeMac(mapping.mac);
87
+ const now = Date.now();
88
+ const existingMapping = this.mappings.get(normalizedMac);
89
+ const fullMapping = {
90
+ ...mapping,
91
+ mac: normalizedMac,
92
+ createdAt: existingMapping?.createdAt || now,
93
+ updatedAt: now,
94
+ };
95
+ this.mappings.set(normalizedMac, fullMapping);
96
+ // Persist to storage
97
+ if (this.storageManager) {
98
+ await this.saveMappings();
99
+ }
100
+ logger.log('info', `VLAN mapping ${existingMapping ? 'updated' : 'added'}: ${normalizedMac} -> VLAN ${mapping.vlan}`);
101
+ return fullMapping;
102
+ }
103
+ /**
104
+ * Remove a MAC to VLAN mapping
105
+ */
106
+ async removeMapping(mac) {
107
+ const normalizedMac = this.normalizeMac(mac);
108
+ const removed = this.mappings.delete(normalizedMac);
109
+ if (removed && this.storageManager) {
110
+ await this.saveMappings();
111
+ logger.log('info', `VLAN mapping removed: ${normalizedMac}`);
112
+ }
113
+ return removed;
114
+ }
115
+ /**
116
+ * Get a specific mapping by MAC
117
+ */
118
+ getMapping(mac) {
119
+ return this.mappings.get(this.normalizeMac(mac));
120
+ }
121
+ /**
122
+ * Get all mappings
123
+ */
124
+ getAllMappings() {
125
+ return Array.from(this.mappings.values());
126
+ }
127
+ /**
128
+ * Determine VLAN assignment for a MAC address
129
+ * Returns the most specific matching rule (exact > OUI > wildcard > default)
130
+ */
131
+ assignVlan(mac) {
132
+ const normalizedMac = this.normalizeMac(mac);
133
+ // First, try exact match
134
+ const exactMatch = this.mappings.get(normalizedMac);
135
+ if (exactMatch && exactMatch.enabled) {
136
+ return {
137
+ assigned: true,
138
+ vlan: exactMatch.vlan,
139
+ matchedRule: exactMatch,
140
+ isDefault: false,
141
+ };
142
+ }
143
+ // Try OUI/prefix matches (sorted by specificity - longer patterns first)
144
+ const patternMatches = [];
145
+ for (const mapping of this.mappings.values()) {
146
+ if (mapping.enabled && mapping.mac !== normalizedMac && this.macMatchesPattern(normalizedMac, mapping.mac)) {
147
+ patternMatches.push(mapping);
148
+ }
149
+ }
150
+ // Sort by pattern length (most specific first)
151
+ patternMatches.sort((a, b) => b.mac.length - a.mac.length);
152
+ if (patternMatches.length > 0) {
153
+ const bestMatch = patternMatches[0];
154
+ return {
155
+ assigned: true,
156
+ vlan: bestMatch.vlan,
157
+ matchedRule: bestMatch,
158
+ isDefault: false,
159
+ };
160
+ }
161
+ // No match - use default VLAN if allowed
162
+ if (this.config.allowUnknownMacs) {
163
+ return {
164
+ assigned: true,
165
+ vlan: this.config.defaultVlan,
166
+ isDefault: true,
167
+ };
168
+ }
169
+ // Unknown MAC and not allowed
170
+ return {
171
+ assigned: false,
172
+ vlan: 0,
173
+ isDefault: false,
174
+ };
175
+ }
176
+ /**
177
+ * Bulk import mappings
178
+ */
179
+ async importMappings(mappings) {
180
+ let imported = 0;
181
+ for (const mapping of mappings) {
182
+ await this.addMapping(mapping);
183
+ imported++;
184
+ }
185
+ logger.log('info', `Imported ${imported} VLAN mappings`);
186
+ return imported;
187
+ }
188
+ /**
189
+ * Export all mappings
190
+ */
191
+ exportMappings() {
192
+ return this.getAllMappings();
193
+ }
194
+ /**
195
+ * Update configuration
196
+ */
197
+ updateConfig(config) {
198
+ if (config.defaultVlan !== undefined) {
199
+ this.config.defaultVlan = config.defaultVlan;
200
+ }
201
+ if (config.allowUnknownMacs !== undefined) {
202
+ this.config.allowUnknownMacs = config.allowUnknownMacs;
203
+ }
204
+ logger.log('info', `VlanManager config updated: defaultVlan=${this.config.defaultVlan}, allowUnknown=${this.config.allowUnknownMacs}`);
205
+ }
206
+ /**
207
+ * Get current configuration
208
+ */
209
+ getConfig() {
210
+ return { ...this.config };
211
+ }
212
+ /**
213
+ * Get statistics
214
+ */
215
+ getStats() {
216
+ let exactMatches = 0;
217
+ let ouiPatterns = 0;
218
+ let wildcardPatterns = 0;
219
+ let enabledMappings = 0;
220
+ for (const mapping of this.mappings.values()) {
221
+ if (mapping.enabled) {
222
+ enabledMappings++;
223
+ }
224
+ if (mapping.mac === '*') {
225
+ wildcardPatterns++;
226
+ }
227
+ else if (mapping.mac.length < 17) {
228
+ // OUI patterns are shorter than full MAC (17 chars with colons)
229
+ ouiPatterns++;
230
+ }
231
+ else {
232
+ exactMatches++;
233
+ }
234
+ }
235
+ return {
236
+ totalMappings: this.mappings.size,
237
+ enabledMappings,
238
+ exactMatches,
239
+ ouiPatterns,
240
+ wildcardPatterns,
241
+ };
242
+ }
243
+ /**
244
+ * Load mappings from storage
245
+ */
246
+ async loadMappings() {
247
+ if (!this.storageManager) {
248
+ return;
249
+ }
250
+ try {
251
+ const data = await this.storageManager.getJSON(this.config.storagePrefix);
252
+ if (data && Array.isArray(data)) {
253
+ for (const mapping of data) {
254
+ this.mappings.set(this.normalizeMac(mapping.mac), mapping);
255
+ }
256
+ logger.log('info', `Loaded ${data.length} VLAN mappings from storage`);
257
+ }
258
+ }
259
+ catch (error) {
260
+ logger.log('warn', `Failed to load VLAN mappings from storage: ${error.message}`);
261
+ }
262
+ }
263
+ /**
264
+ * Save mappings to storage
265
+ */
266
+ async saveMappings() {
267
+ if (!this.storageManager) {
268
+ return;
269
+ }
270
+ try {
271
+ const mappings = Array.from(this.mappings.values());
272
+ await this.storageManager.setJSON(this.config.storagePrefix, mappings);
273
+ }
274
+ catch (error) {
275
+ logger.log('error', `Failed to save VLAN mappings to storage: ${error.message}`);
276
+ }
277
+ }
278
+ }
279
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy52bGFuLm1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9yYWRpdXMvY2xhc3Nlcy52bGFuLm1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQStDdEM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFDZCxRQUFRLEdBQWlDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkQsTUFBTSxDQUErQjtJQUNyQyxjQUFjLENBQWtCO0lBRXhDLG1DQUFtQztJQUMzQixrQkFBa0IsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUU1RCxZQUFZLE1BQTJCLEVBQUUsY0FBK0I7UUFDdEUsSUFBSSxDQUFDLE1BQU0sR0FBRztZQUNaLFdBQVcsRUFBRSxNQUFNLEVBQUUsV0FBVyxJQUFJLENBQUM7WUFDckMsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLGdCQUFnQixJQUFJLElBQUk7WUFDbEQsYUFBYSxFQUFFLE1BQU0sRUFBRSxhQUFhLElBQUksdUJBQXVCO1NBQ2hFLENBQUM7UUFDRixJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsVUFBVTtRQUNkLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzVCLENBQUM7UUFDRCxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxnQ0FBZ0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLDRCQUE0QixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDOUgsQ0FBQztJQUVEOzs7T0FHRztJQUNILFlBQVksQ0FBQyxHQUFXO1FBQ3RCLG9CQUFvQjtR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
@@ -0,0 +1,13 @@
1
+ /**
2
+ * RADIUS module for DcRouter
3
+ *
4
+ * Provides:
5
+ * - MAC Authentication Bypass (MAB) for network device authentication
6
+ * - VLAN assignment based on MAC addresses
7
+ * - OUI (vendor prefix) pattern matching for device categorization
8
+ * - RADIUS accounting for session tracking and billing
9
+ * - Integration with StorageManager for persistence
10
+ */
11
+ export * from './classes.radius.server.js';
12
+ export * from './classes.vlan.manager.js';
13
+ export * from './classes.accounting.manager.js';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * RADIUS module for DcRouter
3
+ *
4
+ * Provides:
5
+ * - MAC Authentication Bypass (MAB) for network device authentication
6
+ * - VLAN assignment based on MAC addresses
7
+ * - OUI (vendor prefix) pattern matching for device categorization
8
+ * - RADIUS accounting for session tracking and billing
9
+ * - Integration with StorageManager for persistence
10
+ */
11
+ export * from './classes.radius.server.js';
12
+ export * from './classes.vlan.manager.js';
13
+ export * from './classes.accounting.manager.js';
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9yYWRpdXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7OztHQVNHO0FBRUgsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLDJCQUEyQixDQUFDO0FBQzFDLGNBQWMsaUNBQWlDLENBQUMifQ==
@@ -0,0 +1,82 @@
1
+ import type { StorageManager } from '../storage/classes.storagemanager.js';
2
+ import type { IRemoteIngress, IDcRouterRouteConfig } from '../../dist_ts_interfaces/data/remoteingress.js';
3
+ /**
4
+ * Manages CRUD for remote ingress edge registrations.
5
+ * Persists edge configs via StorageManager and provides
6
+ * the allowed edges list for the Rust hub.
7
+ */
8
+ export declare class RemoteIngressManager {
9
+ private storageManager;
10
+ private edges;
11
+ private routes;
12
+ constructor(storageManager: StorageManager);
13
+ /**
14
+ * Load all edge registrations from storage into memory.
15
+ */
16
+ initialize(): Promise<void>;
17
+ /**
18
+ * Store the current route configs for port derivation.
19
+ */
20
+ setRoutes(routes: IDcRouterRouteConfig[]): void;
21
+ /**
22
+ * Derive listen ports for an edge from routes tagged with remoteIngress.enabled.
23
+ * When a route specifies edgeFilter, only edges whose id or tags match get that route's ports.
24
+ * When edgeFilter is absent, the route applies to all edges.
25
+ */
26
+ derivePortsForEdge(edgeId: string, edgeTags?: string[]): number[];
27
+ /**
28
+ * Get the effective listen ports for an edge.
29
+ * Manual ports are always included. Auto-derived ports are added (union) when autoDerivePorts is true.
30
+ */
31
+ getEffectiveListenPorts(edge: IRemoteIngress): number[];
32
+ /**
33
+ * Get manual and derived port breakdown for an edge (used in API responses).
34
+ * Derived ports exclude any ports already present in the manual list.
35
+ */
36
+ getPortBreakdown(edge: IRemoteIngress): {
37
+ manual: number[];
38
+ derived: number[];
39
+ };
40
+ /**
41
+ * Create a new edge registration.
42
+ */
43
+ createEdge(name: string, listenPorts?: number[], tags?: string[], autoDerivePorts?: boolean): Promise<IRemoteIngress>;
44
+ /**
45
+ * Get an edge by ID.
46
+ */
47
+ getEdge(id: string): IRemoteIngress | undefined;
48
+ /**
49
+ * Get all edge registrations.
50
+ */
51
+ getAllEdges(): IRemoteIngress[];
52
+ /**
53
+ * Update an edge registration.
54
+ */
55
+ updateEdge(id: string, updates: {
56
+ name?: string;
57
+ listenPorts?: number[];
58
+ autoDerivePorts?: boolean;
59
+ enabled?: boolean;
60
+ tags?: string[];
61
+ }): Promise<IRemoteIngress | null>;
62
+ /**
63
+ * Delete an edge registration.
64
+ */
65
+ deleteEdge(id: string): Promise<boolean>;
66
+ /**
67
+ * Regenerate the secret for an edge.
68
+ */
69
+ regenerateSecret(id: string): Promise<string | null>;
70
+ /**
71
+ * Verify an edge's secret using constant-time comparison.
72
+ */
73
+ verifySecret(id: string, secret: string): boolean;
74
+ /**
75
+ * Get the list of allowed edges (enabled only) for the Rust hub.
76
+ */
77
+ getAllowedEdges(): Array<{
78
+ id: string;
79
+ secret: string;
80
+ listenPorts: number[];
81
+ }>;
82
+ }