@serve.zone/dcrouter 6.3.0 → 6.4.0

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 (55) hide show
  1. package/dist_serve/bundle.js +559 -452
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/classes.dcrouter.d.ts +22 -0
  4. package/dist_ts/classes.dcrouter.js +42 -1
  5. package/dist_ts/index.d.ts +1 -0
  6. package/dist_ts/index.js +3 -1
  7. package/dist_ts/opsserver/classes.opsserver.d.ts +1 -0
  8. package/dist_ts/opsserver/classes.opsserver.js +3 -1
  9. package/dist_ts/opsserver/handlers/index.d.ts +1 -0
  10. package/dist_ts/opsserver/handlers/index.js +2 -1
  11. package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +8 -0
  12. package/dist_ts/opsserver/handlers/remoteingress.handler.js +107 -0
  13. package/dist_ts/plugins.d.ts +2 -1
  14. package/dist_ts/plugins.js +3 -2
  15. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +56 -0
  16. package/dist_ts/remoteingress/classes.remoteingress-manager.js +133 -0
  17. package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +45 -0
  18. package/dist_ts/remoteingress/classes.tunnel-manager.js +107 -0
  19. package/dist_ts/remoteingress/index.d.ts +2 -0
  20. package/dist_ts/remoteingress/index.js +3 -0
  21. package/dist_ts_interfaces/data/index.d.ts +1 -0
  22. package/dist_ts_interfaces/data/index.js +2 -1
  23. package/dist_ts_interfaces/data/remoteingress.d.ts +24 -0
  24. package/dist_ts_interfaces/data/remoteingress.js +2 -0
  25. package/dist_ts_interfaces/requests/index.d.ts +1 -0
  26. package/dist_ts_interfaces/requests/index.js +2 -1
  27. package/dist_ts_interfaces/requests/remoteingress.d.ts +89 -0
  28. package/dist_ts_interfaces/requests/remoteingress.js +3 -0
  29. package/dist_ts_web/00_commitinfo_data.js +1 -1
  30. package/dist_ts_web/appstate.d.ts +19 -0
  31. package/dist_ts_web/appstate.js +124 -2
  32. package/dist_ts_web/elements/index.d.ts +1 -0
  33. package/dist_ts_web/elements/index.js +2 -1
  34. package/dist_ts_web/elements/ops-dashboard.js +6 -1
  35. package/dist_ts_web/elements/ops-view-remoteingress.d.ts +20 -0
  36. package/dist_ts_web/elements/ops-view-remoteingress.js +317 -0
  37. package/dist_ts_web/router.d.ts +1 -1
  38. package/dist_ts_web/router.js +2 -2
  39. package/package.json +2 -1
  40. package/ts/00_commitinfo_data.ts +1 -1
  41. package/ts/classes.dcrouter.ts +66 -0
  42. package/ts/index.ts +3 -0
  43. package/ts/opsserver/classes.opsserver.ts +2 -0
  44. package/ts/opsserver/handlers/index.ts +2 -1
  45. package/ts/opsserver/handlers/remoteingress.handler.ts +163 -0
  46. package/ts/plugins.ts +3 -1
  47. package/ts/remoteingress/classes.remoteingress-manager.ts +160 -0
  48. package/ts/remoteingress/classes.tunnel-manager.ts +126 -0
  49. package/ts/remoteingress/index.ts +2 -0
  50. package/ts_web/00_commitinfo_data.ts +1 -1
  51. package/ts_web/appstate.ts +180 -1
  52. package/ts_web/elements/index.ts +1 -0
  53. package/ts_web/elements/ops-dashboard.ts +5 -0
  54. package/ts_web/elements/ops-view-remoteingress.ts +290 -0
  55. package/ts_web/router.ts +1 -1
@@ -0,0 +1,317 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { DeesElement, html, customElement, css, state, cssManager, } from '@design.estate/dees-element';
36
+ import * as appstate from '../appstate.js';
37
+ import * as interfaces from '../../dist_ts_interfaces/index.js';
38
+ import { viewHostCss } from './shared/css.js';
39
+ import {} from '@design.estate/dees-catalog';
40
+ let OpsViewRemoteIngress = (() => {
41
+ let _classDecorators = [customElement('ops-view-remoteingress')];
42
+ let _classDescriptor;
43
+ let _classExtraInitializers = [];
44
+ let _classThis;
45
+ let _classSuper = DeesElement;
46
+ let _riState_decorators;
47
+ let _riState_initializers = [];
48
+ let _riState_extraInitializers = [];
49
+ var OpsViewRemoteIngress = class extends _classSuper {
50
+ static { _classThis = this; }
51
+ static {
52
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
53
+ _riState_decorators = [state()];
54
+ __esDecorate(this, null, _riState_decorators, { kind: "accessor", name: "riState", static: false, private: false, access: { has: obj => "riState" in obj, get: obj => obj.riState, set: (obj, value) => { obj.riState = value; } }, metadata: _metadata }, _riState_initializers, _riState_extraInitializers);
55
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
56
+ OpsViewRemoteIngress = _classThis = _classDescriptor.value;
57
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
58
+ }
59
+ #riState_accessor_storage = __runInitializers(this, _riState_initializers, appstate.remoteIngressStatePart.getState());
60
+ get riState() { return this.#riState_accessor_storage; }
61
+ set riState(value) { this.#riState_accessor_storage = value; }
62
+ constructor() {
63
+ super();
64
+ __runInitializers(this, _riState_extraInitializers);
65
+ const sub = appstate.remoteIngressStatePart.state.subscribe((newState) => {
66
+ this.riState = newState;
67
+ });
68
+ this.rxSubscriptions.push(sub);
69
+ }
70
+ async connectedCallback() {
71
+ await super.connectedCallback();
72
+ await appstate.remoteIngressStatePart.dispatchAction(appstate.fetchRemoteIngressAction, null);
73
+ }
74
+ static styles = [
75
+ cssManager.defaultStyles,
76
+ viewHostCss,
77
+ css `
78
+ .remoteIngressContainer {
79
+ display: flex;
80
+ flex-direction: column;
81
+ gap: 24px;
82
+ }
83
+
84
+ .statusBadge {
85
+ display: inline-flex;
86
+ align-items: center;
87
+ padding: 3px 10px;
88
+ border-radius: 12px;
89
+ font-size: 12px;
90
+ font-weight: 600;
91
+ letter-spacing: 0.02em;
92
+ text-transform: uppercase;
93
+ }
94
+
95
+ .statusBadge.connected {
96
+ background: ${cssManager.bdTheme('#dcfce7', '#14532d')};
97
+ color: ${cssManager.bdTheme('#166534', '#4ade80')};
98
+ }
99
+
100
+ .statusBadge.disconnected {
101
+ background: ${cssManager.bdTheme('#fef2f2', '#450a0a')};
102
+ color: ${cssManager.bdTheme('#991b1b', '#f87171')};
103
+ }
104
+
105
+ .statusBadge.disabled {
106
+ background: ${cssManager.bdTheme('#f3f4f6', '#374151')};
107
+ color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
108
+ }
109
+
110
+ .secretDialog {
111
+ padding: 16px;
112
+ background: ${cssManager.bdTheme('#fffbeb', '#1c1917')};
113
+ border: 1px solid ${cssManager.bdTheme('#fbbf24', '#92400e')};
114
+ border-radius: 8px;
115
+ margin-bottom: 16px;
116
+ }
117
+
118
+ .secretDialog code {
119
+ display: block;
120
+ padding: 8px 12px;
121
+ background: ${cssManager.bdTheme('#1f2937', '#111827')};
122
+ color: #10b981;
123
+ border-radius: 4px;
124
+ font-family: monospace;
125
+ font-size: 13px;
126
+ word-break: break-all;
127
+ margin: 8px 0;
128
+ user-select: all;
129
+ }
130
+
131
+ .secretDialog .warning {
132
+ font-size: 12px;
133
+ color: ${cssManager.bdTheme('#92400e', '#fbbf24')};
134
+ margin-top: 8px;
135
+ }
136
+
137
+ .portsDisplay {
138
+ display: flex;
139
+ gap: 4px;
140
+ flex-wrap: wrap;
141
+ }
142
+
143
+ .portBadge {
144
+ display: inline-flex;
145
+ padding: 2px 8px;
146
+ border-radius: 4px;
147
+ font-size: 12px;
148
+ font-weight: 500;
149
+ background: ${cssManager.bdTheme('#eff6ff', '#172554')};
150
+ color: ${cssManager.bdTheme('#1e40af', '#60a5fa')};
151
+ }
152
+ `,
153
+ ];
154
+ render() {
155
+ const totalEdges = this.riState.edges.length;
156
+ const connectedEdges = this.riState.statuses.filter(s => s.connected).length;
157
+ const disconnectedEdges = totalEdges - connectedEdges;
158
+ const activeTunnels = this.riState.statuses.reduce((sum, s) => sum + s.activeTunnels, 0);
159
+ const statsTiles = [
160
+ {
161
+ id: 'totalEdges',
162
+ title: 'Total Edges',
163
+ type: 'number',
164
+ value: totalEdges,
165
+ icon: 'lucide:server',
166
+ description: 'Registered edge nodes',
167
+ color: '#3b82f6',
168
+ },
169
+ {
170
+ id: 'connectedEdges',
171
+ title: 'Connected',
172
+ type: 'number',
173
+ value: connectedEdges,
174
+ icon: 'lucide:link',
175
+ description: 'Currently connected edges',
176
+ color: '#10b981',
177
+ },
178
+ {
179
+ id: 'disconnectedEdges',
180
+ title: 'Disconnected',
181
+ type: 'number',
182
+ value: disconnectedEdges,
183
+ icon: 'lucide:unlink',
184
+ description: 'Offline edge nodes',
185
+ color: disconnectedEdges > 0 ? '#ef4444' : '#6b7280',
186
+ },
187
+ {
188
+ id: 'activeTunnels',
189
+ title: 'Active Tunnels',
190
+ type: 'number',
191
+ value: activeTunnels,
192
+ icon: 'lucide:cable',
193
+ description: 'Active client connections',
194
+ color: '#8b5cf6',
195
+ },
196
+ ];
197
+ return html `
198
+ <ops-sectionheading>Remote Ingress</ops-sectionheading>
199
+
200
+ ${this.riState.newEdgeSecret ? html `
201
+ <div class="secretDialog">
202
+ <strong>Edge Secret (copy now - shown only once):</strong>
203
+ <code>${this.riState.newEdgeSecret}</code>
204
+ <div class="warning">This secret will not be shown again. Save it securely.</div>
205
+ <dees-button
206
+ @click=${() => appstate.remoteIngressStatePart.dispatchAction(appstate.clearNewEdgeSecretAction, null)}
207
+ >Dismiss</dees-button>
208
+ </div>
209
+ ` : ''}
210
+
211
+ <div class="remoteIngressContainer">
212
+ <dees-statsgrid .tiles=${statsTiles}></dees-statsgrid>
213
+
214
+ <dees-table
215
+ .heading1=${'Edge Nodes'}
216
+ .heading2=${'Manage remote ingress edge registrations'}
217
+ .data=${this.riState.edges}
218
+ .displayFunction=${(edge) => ({
219
+ name: edge.name,
220
+ status: this.getEdgeStatusHtml(edge),
221
+ publicIp: this.getEdgePublicIp(edge.id),
222
+ ports: this.getPortsHtml(edge.listenPorts),
223
+ tunnels: this.getEdgeTunnelCount(edge.id),
224
+ lastHeartbeat: this.getLastHeartbeat(edge.id),
225
+ })}
226
+ .dataActions=${[
227
+ {
228
+ name: 'Regenerate Secret',
229
+ iconName: 'lucide:key',
230
+ action: async (edge) => {
231
+ await appstate.remoteIngressStatePart.dispatchAction(appstate.regenerateRemoteIngressSecretAction, edge.id);
232
+ },
233
+ },
234
+ {
235
+ name: 'Delete',
236
+ iconName: 'lucide:trash2',
237
+ action: async (edge) => {
238
+ await appstate.remoteIngressStatePart.dispatchAction(appstate.deleteRemoteIngressAction, edge.id);
239
+ },
240
+ },
241
+ ]}
242
+ .createNewAction=${async () => {
243
+ const { DeesModal } = await import('@design.estate/dees-catalog');
244
+ const result = await DeesModal.createAndShow({
245
+ heading: 'Create Edge Node',
246
+ content: html `
247
+ <dees-form>
248
+ <dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
249
+ <dees-input-text .key=${'listenPorts'} .label=${'Listen Ports (comma-separated)'} .required=${true} .value=${'443,25'}></dees-input-text>
250
+ <dees-input-text .key=${'tags'} .label=${'Tags (comma-separated, optional)'}></dees-input-text>
251
+ </dees-form>
252
+ `,
253
+ menuOptions: [],
254
+ });
255
+ if (result) {
256
+ const formData = result;
257
+ const ports = (formData.name ? formData.listenPorts : '443')
258
+ .split(',')
259
+ .map((p) => parseInt(p.trim(), 10))
260
+ .filter((p) => !isNaN(p));
261
+ const tags = formData.tags
262
+ ? formData.tags.split(',').map((t) => t.trim()).filter(Boolean)
263
+ : undefined;
264
+ await appstate.remoteIngressStatePart.dispatchAction(appstate.createRemoteIngressAction, {
265
+ name: formData.name,
266
+ listenPorts: ports,
267
+ tags,
268
+ });
269
+ }
270
+ }}
271
+ ></dees-table>
272
+ </div>
273
+ `;
274
+ }
275
+ getEdgeStatus(edgeId) {
276
+ return this.riState.statuses.find(s => s.edgeId === edgeId);
277
+ }
278
+ getEdgeStatusHtml(edge) {
279
+ if (!edge.enabled) {
280
+ return html `<span class="statusBadge disabled">Disabled</span>`;
281
+ }
282
+ const status = this.getEdgeStatus(edge.id);
283
+ if (status?.connected) {
284
+ return html `<span class="statusBadge connected">Connected</span>`;
285
+ }
286
+ return html `<span class="statusBadge disconnected">Disconnected</span>`;
287
+ }
288
+ getEdgePublicIp(edgeId) {
289
+ const status = this.getEdgeStatus(edgeId);
290
+ return status?.publicIp || '-';
291
+ }
292
+ getPortsHtml(ports) {
293
+ return html `<div class="portsDisplay">${ports.map(p => html `<span class="portBadge">${p}</span>`)}</div>`;
294
+ }
295
+ getEdgeTunnelCount(edgeId) {
296
+ const status = this.getEdgeStatus(edgeId);
297
+ return status?.activeTunnels || 0;
298
+ }
299
+ getLastHeartbeat(edgeId) {
300
+ const status = this.getEdgeStatus(edgeId);
301
+ if (!status?.lastHeartbeat)
302
+ return '-';
303
+ const ago = Date.now() - status.lastHeartbeat;
304
+ if (ago < 60000)
305
+ return `${Math.floor(ago / 1000)}s ago`;
306
+ if (ago < 3600000)
307
+ return `${Math.floor(ago / 60000)}m ago`;
308
+ return `${Math.floor(ago / 3600000)}h ago`;
309
+ }
310
+ static {
311
+ __runInitializers(_classThis, _classExtraInitializers);
312
+ }
313
+ };
314
+ return OpsViewRemoteIngress = _classThis;
315
+ })();
316
+ export { OpsViewRemoteIngress };
317
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctcmVtb3RlaW5ncmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3dlYi9lbGVtZW50cy9vcHMtdmlldy1yZW1vdGVpbmdyZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLElBQUksRUFDSixhQUFhLEVBRWIsR0FBRyxFQUNILEtBQUssRUFDTCxVQUFVLEdBQ1gsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEtBQUssUUFBUSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sS0FBSyxVQUFVLE1BQU0sbUNBQW1DLENBQUM7QUFDaEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sRUFBbUIsTUFBTSw2QkFBNkIsQ0FBQztJQVNqRCxvQkFBb0I7NEJBRGhDLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQzs7OztzQkFDRSxXQUFXOzs7O29DQUFuQixTQUFRLFdBQVc7Ozs7bUNBQ2xELEtBQUssRUFBRTtZQUNSLDBLQUFTLE9BQU8sNkJBQVAsT0FBTyx5RkFBNEU7WUFGOUYsNktBNFFDOzs7O1FBMVFDLDJFQUFpRCxRQUFRLENBQUMsc0JBQXNCLENBQUMsUUFBUSxFQUFFLEVBQUM7UUFBNUYsSUFBUyxPQUFPLDZDQUE0RTtRQUE1RixJQUFTLE9BQU8sbURBQTRFO1FBRTVGO1lBQ0UsS0FBSyxFQUFFLENBQUM7O1lBQ1IsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDdkUsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7WUFDMUIsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNoQztRQUVELEtB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
@@ -1,4 +1,4 @@
1
- export declare const validViews: readonly ["overview", "network", "emails", "logs", "configuration", "security", "certificates"];
1
+ export declare const validViews: readonly ["overview", "network", "emails", "logs", "configuration", "security", "certificates", "remoteingress"];
2
2
  export declare const validEmailFolders: readonly ["queued", "sent", "failed", "security"];
3
3
  export type TValidView = typeof validViews[number];
4
4
  export type TValidEmailFolder = typeof validEmailFolders[number];
@@ -1,7 +1,7 @@
1
1
  import * as plugins from './plugins.js';
2
2
  import * as appstate from './appstate.js';
3
3
  const SmartRouter = plugins.domtools.plugins.smartrouter.SmartRouter;
4
- export const validViews = ['overview', 'network', 'emails', 'logs', 'configuration', 'security', 'certificates'];
4
+ export const validViews = ['overview', 'network', 'emails', 'logs', 'configuration', 'security', 'certificates', 'remoteingress'];
5
5
  export const validEmailFolders = ['queued', 'sent', 'failed', 'security'];
6
6
  class AppRouter {
7
7
  router;
@@ -162,4 +162,4 @@ class AppRouter {
162
162
  }
163
163
  }
164
164
  export const appRouter = new AppRouter();
165
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssUUFBUSxNQUFNLGVBQWUsQ0FBQztBQUUxQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0FBRXJFLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLGNBQWMsQ0FBVSxDQUFDO0FBQzFILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsVUFBVSxDQUFVLENBQUM7QUFLbkYsTUFBTSxTQUFTO0lBQ0wsTUFBTSxDQUFtQztJQUN6QyxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQ3BCLG1CQUFtQixHQUFHLEtBQUssQ0FBQztJQUVwQztRQUNFLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxXQUFXLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRU0sSUFBSTtRQUNULElBQUksSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFPO1FBQzdCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDMUIsQ0FBQztJQUVPLFdBQVc7UUFDakIsYUFBYTtRQUNiLEtBQUssTUFBTSxJQUFJLElBQUksVUFBVSxFQUFFLENBQUM7WUFDOUIsSUFBSSxJQUFJLEtBQUssUUFBUSxFQUFFLENB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
165
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssUUFBUSxNQUFNLGVBQWUsQ0FBQztBQUUxQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0FBRXJFLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxlQUFlLENBQVUsQ0FBQztBQUMzSSxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBVSxDQUFDO0FBS25GLE1BQU0sU0FBUztJQUNMLE1BQU0sQ0FBbUM7SUFDekMsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUNwQixtQkFBbUIsR0FBRyxLQUFLLENBQUM7SUFFcEM7UUFDRSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksV0FBVyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVNLElBQUk7UUFDVCxJQUFJLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTztRQUM3QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQzFCLENBQUM7SUFFTyxXQUFXO1FBQ2pCLGFBQWE7UUFDYixLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzlCLElBQUksSUFBSSxLQUFLLFFB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
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@serve.zone/dcrouter",
3
3
  "private": false,
4
- "version": "6.3.0",
4
+ "version": "6.4.0",
5
5
  "description": "A multifaceted routing service handling mail and SMS delivery functions.",
6
6
  "type": "module",
7
7
  "exports": {
@@ -56,6 +56,7 @@
56
56
  "@push.rocks/smartstate": "^2.0.30",
57
57
  "@push.rocks/smartunique": "^3.0.9",
58
58
  "@serve.zone/interfaces": "^5.3.0",
59
+ "@serve.zone/remoteingress": "^3.0.1",
59
60
  "@tsclass/tsclass": "^9.3.0",
60
61
  "lru-cache": "^11.2.6",
61
62
  "uuid": "^13.0.0"
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '6.3.0',
6
+ version: '6.4.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  }
@@ -21,6 +21,7 @@ import { CacheDb, CacheCleaner, type ICacheDbOptions } from './cache/index.js';
21
21
  import { OpsServer } from './opsserver/index.js';
22
22
  import { MetricsManager } from './monitoring/index.js';
23
23
  import { RadiusServer, type IRadiusServerConfig } from './radius/index.js';
24
+ import { RemoteIngressManager, TunnelManager } from './remoteingress/index.js';
24
25
 
25
26
  export interface IDcRouterOptions {
26
27
  /** Base directory for all dcrouter data. Defaults to ~/.serve.zone/dcrouter */
@@ -155,6 +156,22 @@ export interface IDcRouterOptions {
155
156
  * Enables MAC Authentication Bypass (MAB) and VLAN assignment
156
157
  */
157
158
  radiusConfig?: IRadiusServerConfig;
159
+
160
+ /**
161
+ * Remote Ingress configuration for edge tunnel nodes
162
+ * Enables edge nodes to accept incoming connections and tunnel them to this DcRouter
163
+ */
164
+ remoteIngressConfig?: {
165
+ /** Enable remote ingress hub (default: false) */
166
+ enabled?: boolean;
167
+ /** Port for tunnel connections from edge nodes (default: 8443) */
168
+ tunnelPort?: number;
169
+ /** TLS configuration for the tunnel server */
170
+ tls?: {
171
+ certPath?: string;
172
+ keyPath?: string;
173
+ };
174
+ };
158
175
  }
159
176
 
160
177
  /**
@@ -189,6 +206,10 @@ export class DcRouter {
189
206
  public cacheDb?: CacheDb;
190
207
  public cacheCleaner?: CacheCleaner;
191
208
 
209
+ // Remote Ingress
210
+ public remoteIngressManager?: RemoteIngressManager;
211
+ public tunnelManager?: TunnelManager;
212
+
192
213
  // Certificate status tracking from SmartProxy events (keyed by domain)
193
214
  public certificateStatusMap = new Map<string, {
194
215
  status: 'valid' | 'failed';
@@ -266,6 +287,11 @@ export class DcRouter {
266
287
  await this.setupRadiusServer();
267
288
  }
268
289
 
290
+ // Set up Remote Ingress hub if configured
291
+ if (this.options.remoteIngressConfig?.enabled) {
292
+ await this.setupRemoteIngress();
293
+ }
294
+
269
295
  this.logStartupSummary();
270
296
  } catch (error) {
271
297
  console.error('❌ Error starting DcRouter:', error);
@@ -352,6 +378,16 @@ export class DcRouter {
352
378
  console.log(` └─ Accounting: ${this.options.radiusConfig.accounting?.enabled ? 'Enabled' : 'Disabled'}`);
353
379
  }
354
380
 
381
+ // Remote Ingress summary
382
+ if (this.tunnelManager && this.options.remoteIngressConfig?.enabled) {
383
+ console.log('\n🌐 Remote Ingress:');
384
+ console.log(` ├─ Tunnel Port: ${this.options.remoteIngressConfig.tunnelPort || 8443}`);
385
+ const edgeCount = this.remoteIngressManager?.getAllEdges().length || 0;
386
+ const connectedCount = this.tunnelManager.getConnectedCount();
387
+ console.log(` ├─ Registered Edges: ${edgeCount}`);
388
+ console.log(` └─ Connected Edges: ${connectedCount}`);
389
+ }
390
+
355
391
  // Storage summary
356
392
  if (this.storageManager && this.options.storage) {
357
393
  console.log('\n💾 Storage:');
@@ -886,6 +922,11 @@ export class DcRouter {
886
922
  // Stop RADIUS server if running
887
923
  this.radiusServer ?
888
924
  this.radiusServer.stop().catch(err => console.error('Error stopping RADIUS server:', err)) :
925
+ Promise.resolve(),
926
+
927
+ // Stop Remote Ingress tunnel manager if running
928
+ this.tunnelManager ?
929
+ this.tunnelManager.stop().catch(err => console.error('Error stopping TunnelManager:', err)) :
889
930
  Promise.resolve()
890
931
  ]);
891
932
 
@@ -1532,6 +1573,31 @@ export class DcRouter {
1532
1573
  }
1533
1574
  }
1534
1575
 
1576
+ /**
1577
+ * Set up Remote Ingress hub for edge tunnel connections
1578
+ */
1579
+ private async setupRemoteIngress(): Promise<void> {
1580
+ if (!this.options.remoteIngressConfig?.enabled) {
1581
+ return;
1582
+ }
1583
+
1584
+ logger.log('info', 'Setting up Remote Ingress hub...');
1585
+
1586
+ // Initialize the edge registration manager
1587
+ this.remoteIngressManager = new RemoteIngressManager(this.storageManager);
1588
+ await this.remoteIngressManager.initialize();
1589
+
1590
+ // Create and start the tunnel manager
1591
+ this.tunnelManager = new TunnelManager(this.remoteIngressManager, {
1592
+ tunnelPort: this.options.remoteIngressConfig.tunnelPort ?? 8443,
1593
+ targetHost: '127.0.0.1',
1594
+ });
1595
+ await this.tunnelManager.start();
1596
+
1597
+ const edgeCount = this.remoteIngressManager.getAllEdges().length;
1598
+ logger.log('info', `Remote Ingress hub started on port ${this.options.remoteIngressConfig.tunnelPort || 8443} with ${edgeCount} registered edge(s)`);
1599
+ }
1600
+
1535
1601
  /**
1536
1602
  * Set up RADIUS server for network authentication
1537
1603
  */
package/ts/index.ts CHANGED
@@ -10,4 +10,7 @@ export * from './classes.dcrouter.js';
10
10
  // RADIUS module
11
11
  export * from './radius/index.js';
12
12
 
13
+ // Remote Ingress module
14
+ export * from './remoteingress/index.js';
15
+
13
16
  export const runCli = async () => {};
@@ -19,6 +19,7 @@ export class OpsServer {
19
19
  private radiusHandler: handlers.RadiusHandler;
20
20
  private emailOpsHandler: handlers.EmailOpsHandler;
21
21
  private certificateHandler: handlers.CertificateHandler;
22
+ private remoteIngressHandler: handlers.RemoteIngressHandler;
22
23
 
23
24
  constructor(dcRouterRefArg: DcRouter) {
24
25
  this.dcRouterRef = dcRouterRefArg;
@@ -59,6 +60,7 @@ export class OpsServer {
59
60
  this.radiusHandler = new handlers.RadiusHandler(this);
60
61
  this.emailOpsHandler = new handlers.EmailOpsHandler(this);
61
62
  this.certificateHandler = new handlers.CertificateHandler(this);
63
+ this.remoteIngressHandler = new handlers.RemoteIngressHandler(this);
62
64
 
63
65
  console.log('✅ OpsServer TypedRequest handlers initialized');
64
66
  }
@@ -5,4 +5,5 @@ export * from './security.handler.js';
5
5
  export * from './stats.handler.js';
6
6
  export * from './radius.handler.js';
7
7
  export * from './email-ops.handler.js';
8
- export * from './certificate.handler.js';
8
+ export * from './certificate.handler.js';
9
+ export * from './remoteingress.handler.js';