@serve.zone/dcrouter 15.0.1 → 15.0.2

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 (53) hide show
  1. package/deno.json +1 -1
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/acme/classes.smartacme-lifecycle.d.ts +25 -0
  4. package/dist_ts/acme/classes.smartacme-lifecycle.js +144 -0
  5. package/dist_ts/acme/index.d.ts +1 -0
  6. package/dist_ts/acme/index.js +2 -1
  7. package/dist_ts/classes.dcrouter.d.ts +21 -139
  8. package/dist_ts/classes.dcrouter.js +71 -1585
  9. package/dist_ts/dns/classes.dns-server-runtime.d.ts +37 -0
  10. package/dist_ts/dns/classes.dns-server-runtime.js +449 -0
  11. package/dist_ts/dns/index.d.ts +1 -0
  12. package/dist_ts/dns/index.js +2 -1
  13. package/dist_ts/email/classes.accepted-email-spool.d.ts +55 -0
  14. package/dist_ts/email/classes.accepted-email-spool.js +345 -0
  15. package/dist_ts/email/classes.email-route-builder.d.ts +28 -0
  16. package/dist_ts/email/classes.email-route-builder.js +260 -0
  17. package/dist_ts/email/index.d.ts +2 -0
  18. package/dist_ts/email/index.js +3 -1
  19. package/dist_ts/opsserver/handlers/gatewayclient.handler.js +10 -8
  20. package/dist_ts/remoteingress/classes.hub-lifecycle.d.ts +27 -0
  21. package/dist_ts/remoteingress/classes.hub-lifecycle.js +241 -0
  22. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +1 -2
  23. package/dist_ts/remoteingress/index.d.ts +1 -0
  24. package/dist_ts/remoteingress/index.js +2 -1
  25. package/dist_ts/security/classes.route-policy-augmenter.d.ts +22 -0
  26. package/dist_ts/security/classes.route-policy-augmenter.js +120 -0
  27. package/dist_ts/security/index.d.ts +1 -0
  28. package/dist_ts/security/index.js +2 -1
  29. package/dist_ts/vpn/classes.vpn-access-resolver.d.ts +34 -0
  30. package/dist_ts/vpn/classes.vpn-access-resolver.js +101 -0
  31. package/dist_ts/vpn/index.d.ts +1 -0
  32. package/dist_ts/vpn/index.js +2 -1
  33. package/dist_ts_migrations/index.js +92 -9
  34. package/dist_ts_web/00_commitinfo_data.js +1 -1
  35. package/package.json +1 -1
  36. package/ts/00_commitinfo_data.ts +1 -1
  37. package/ts/acme/classes.smartacme-lifecycle.ts +155 -0
  38. package/ts/acme/index.ts +1 -0
  39. package/ts/classes.dcrouter.ts +118 -1919
  40. package/ts/dns/classes.dns-server-runtime.ts +525 -0
  41. package/ts/dns/index.ts +1 -0
  42. package/ts/email/classes.accepted-email-spool.ts +434 -0
  43. package/ts/email/classes.email-route-builder.ts +312 -0
  44. package/ts/email/index.ts +2 -0
  45. package/ts/opsserver/handlers/gatewayclient.handler.ts +9 -7
  46. package/ts/remoteingress/classes.hub-lifecycle.ts +278 -0
  47. package/ts/remoteingress/classes.remoteingress-manager.ts +1 -1
  48. package/ts/remoteingress/index.ts +1 -0
  49. package/ts/security/classes.route-policy-augmenter.ts +140 -0
  50. package/ts/security/index.ts +1 -0
  51. package/ts/vpn/classes.vpn-access-resolver.ts +126 -0
  52. package/ts/vpn/index.ts +1 -0
  53. package/ts_web/00_commitinfo_data.ts +1 -1
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serve.zone/dcrouter",
3
- "version": "15.0.1",
3
+ "version": "15.0.2",
4
4
  "exports": "./binary/dcrouter.ts",
5
5
  "compile": {
6
6
  "include": [
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '15.0.1',
6
+ version: '15.0.2',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
@@ -0,0 +1,25 @@
1
+ import type { DcRouter } from '../classes.dcrouter.js';
2
+ /**
3
+ * Background start/retry/stop lifecycle for the DcRouter-owned SmartAcme
4
+ * instance. SmartAcme startup can hit ACME rate limits, so startup runs in
5
+ * the background with generation-guarded exponential retry, and certificate
6
+ * provisioning is re-triggered once DNS-01 becomes ready.
7
+ */
8
+ export declare class SmartAcmeLifecycle {
9
+ private dcRouterRef;
10
+ /** True once the SmartAcme DNS-01 provider finished starting. */
11
+ ready: boolean;
12
+ /** Tracks whether the taskbuffer SmartAcme service is started, so SmartProxy rebuilds can re-kick startup. */
13
+ serviceStarted: boolean;
14
+ private startGeneration;
15
+ private startPromise?;
16
+ private retryTimer?;
17
+ private retryAttempt;
18
+ constructor(dcRouterRef: DcRouter);
19
+ startInBackground(): void;
20
+ stop(): Promise<void>;
21
+ private scheduleStart;
22
+ private runStartAttempt;
23
+ private retriggerCertificateProvisioning;
24
+ private clearRetryTimer;
25
+ }
@@ -0,0 +1,144 @@
1
+ import * as plugins from '../plugins.js';
2
+ import { logger } from '../logger.js';
3
+ /**
4
+ * Background start/retry/stop lifecycle for the DcRouter-owned SmartAcme
5
+ * instance. SmartAcme startup can hit ACME rate limits, so startup runs in
6
+ * the background with generation-guarded exponential retry, and certificate
7
+ * provisioning is re-triggered once DNS-01 becomes ready.
8
+ */
9
+ export class SmartAcmeLifecycle {
10
+ dcRouterRef;
11
+ /** True once the SmartAcme DNS-01 provider finished starting. */
12
+ ready = false;
13
+ /** Tracks whether the taskbuffer SmartAcme service is started, so SmartProxy rebuilds can re-kick startup. */
14
+ serviceStarted = false;
15
+ startGeneration = 0;
16
+ startPromise;
17
+ retryTimer;
18
+ retryAttempt = 0;
19
+ constructor(dcRouterRef) {
20
+ this.dcRouterRef = dcRouterRef;
21
+ }
22
+ startInBackground() {
23
+ if (!this.dcRouterRef.smartAcme) {
24
+ this.ready = false;
25
+ return;
26
+ }
27
+ const generation = ++this.startGeneration;
28
+ this.ready = false;
29
+ this.retryAttempt = 0;
30
+ this.clearRetryTimer();
31
+ this.scheduleStart(generation, 0);
32
+ }
33
+ async stop() {
34
+ this.startGeneration++;
35
+ this.ready = false;
36
+ this.retryAttempt = 0;
37
+ this.clearRetryTimer();
38
+ const smartAcme = this.dcRouterRef.smartAcme;
39
+ if (!smartAcme) {
40
+ return;
41
+ }
42
+ try {
43
+ await smartAcme.stop();
44
+ }
45
+ catch (err) {
46
+ logger.log('error', 'Error stopping SmartAcme', { error: String(err) });
47
+ }
48
+ finally {
49
+ if (this.dcRouterRef.smartAcme === smartAcme) {
50
+ this.dcRouterRef.smartAcme = undefined;
51
+ }
52
+ }
53
+ }
54
+ scheduleStart(generation, delayMs) {
55
+ this.clearRetryTimer();
56
+ const retryTimer = setTimeout(() => {
57
+ this.retryTimer = undefined;
58
+ this.runStartAttempt(generation).catch((err) => {
59
+ logger.log('error', `Unexpected SmartAcme startup error: ${err.message}`);
60
+ });
61
+ }, delayMs);
62
+ this.retryTimer = retryTimer;
63
+ const unrefableTimer = retryTimer;
64
+ if (typeof unrefableTimer?.unref === 'function') {
65
+ unrefableTimer.unref();
66
+ }
67
+ }
68
+ async runStartAttempt(generation) {
69
+ const smartAcme = this.dcRouterRef.smartAcme;
70
+ if (!smartAcme || generation !== this.startGeneration) {
71
+ return;
72
+ }
73
+ const startPromise = smartAcme.start();
74
+ this.startPromise = startPromise;
75
+ try {
76
+ await startPromise;
77
+ if (generation !== this.startGeneration || this.dcRouterRef.smartAcme !== smartAcme) {
78
+ await smartAcme.stop().catch((err) => {
79
+ logger.log('warn', `Failed to stop stale SmartAcme instance: ${err.message}`);
80
+ });
81
+ return;
82
+ }
83
+ this.ready = true;
84
+ this.retryAttempt = 0;
85
+ logger.log('info', 'SmartAcme DNS-01 provider is now ready');
86
+ this.retriggerCertificateProvisioning();
87
+ }
88
+ catch (err) {
89
+ if (generation !== this.startGeneration || this.dcRouterRef.smartAcme !== smartAcme) {
90
+ return;
91
+ }
92
+ this.ready = false;
93
+ await smartAcme.stop().catch((stopErr) => {
94
+ logger.log('warn', `Failed to clean up SmartAcme after startup failure: ${stopErr.message}`);
95
+ });
96
+ this.retryAttempt++;
97
+ if (this.retryAttempt > 20) {
98
+ logger.log('error', `SmartAcme DNS-01 provider failed after 20 startup attempts: ${err.message}`);
99
+ return;
100
+ }
101
+ const baseDelayMs = 5000;
102
+ const maxDelayMs = 3_600_000;
103
+ const delayMs = Math.min(baseDelayMs * Math.pow(2, this.retryAttempt - 1), maxDelayMs);
104
+ const jitter = 0.8 + Math.random() * 0.4;
105
+ const actualDelayMs = Math.floor(delayMs * jitter);
106
+ logger.log('warn', `SmartAcme DNS-01 provider startup failed: ${err.message}; retrying in ${actualDelayMs}ms (attempt ${this.retryAttempt}/20)`);
107
+ this.scheduleStart(generation, actualDelayMs);
108
+ }
109
+ finally {
110
+ if (this.startPromise === startPromise) {
111
+ this.startPromise = undefined;
112
+ }
113
+ }
114
+ }
115
+ retriggerCertificateProvisioning() {
116
+ // During startup, certProvisionFunction returns 'http01' while SmartAcme is not ready,
117
+ // but Rust ACME is disabled when certProvisionFunction is set. Re-applying routes
118
+ // retries provisioning now that DNS-01 is available.
119
+ if (this.dcRouterRef.routeConfigManager) {
120
+ logger.log('info', 'Re-triggering certificate provisioning via RouteConfigManager');
121
+ this.dcRouterRef.routeConfigManager.applyRoutes().catch((err) => {
122
+ logger.log('warn', `Failed to re-trigger cert provisioning: ${err?.message || err}`);
123
+ });
124
+ return;
125
+ }
126
+ if (this.dcRouterRef.smartProxy) {
127
+ if (this.dcRouterRef.certProvisionScheduler) {
128
+ this.dcRouterRef.certProvisionScheduler.clear();
129
+ }
130
+ const currentRoutes = this.dcRouterRef.smartProxy.routeManager.getRoutes();
131
+ logger.log('info', `Re-triggering certificate provisioning for ${currentRoutes.length} routes`);
132
+ this.dcRouterRef.smartProxy.updateRoutes(currentRoutes).catch((err) => {
133
+ logger.log('warn', `Failed to re-trigger cert provisioning: ${err?.message || err}`);
134
+ });
135
+ }
136
+ }
137
+ clearRetryTimer() {
138
+ if (this.retryTimer) {
139
+ clearTimeout(this.retryTimer);
140
+ this.retryTimer = undefined;
141
+ }
142
+ }
143
+ }
144
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydGFjbWUtbGlmZWN5Y2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvYWNtZS9jbGFzc2VzLnNtYXJ0YWNtZS1saWZlY3ljbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUd0Qzs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFXVDtJQVZwQixpRUFBaUU7SUFDMUQsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQiw4R0FBOEc7SUFDdkcsY0FBYyxHQUFHLEtBQUssQ0FBQztJQUV0QixlQUFlLEdBQUcsQ0FBQyxDQUFDO0lBQ3BCLFlBQVksQ0FBaUI7SUFDN0IsVUFBVSxDQUFpQztJQUMzQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO0lBRXpCLFlBQW9CLFdBQXFCO1FBQXJCLGdCQUFXLEdBQVgsV0FBVyxDQUFVO0lBQUcsQ0FBQztJQUV0QyxpQkFBaUI7UUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7WUFDbkIsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDMUMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSTtRQUNmLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxHQUFHLEtB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
@@ -1 +1,2 @@
1
1
  export * from './manager.acme-config.js';
2
+ export * from './classes.smartacme-lifecycle.js';
@@ -1,2 +1,3 @@
1
1
  export * from './manager.acme-config.js';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9hY21lL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsMEJBQTBCLENBQUMifQ==
2
+ export * from './classes.smartacme-lifecycle.js';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9hY21lL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsMEJBQTBCLENBQUM7QUFDekMsY0FBYyxrQ0FBa0MsQ0FBQyJ9
@@ -6,16 +6,18 @@ import { DcRouterDb, CacheCleaner } from './db/index.js';
6
6
  import { OpsServer } from './opsserver/index.js';
7
7
  import { MetricsManager } from './monitoring/index.js';
8
8
  import { RadiusServer, type IRadiusServerConfig } from './radius/index.js';
9
- import { RemoteIngressManager, TunnelManager } from './remoteingress/index.js';
10
- import { VpnManager } from './vpn/index.js';
9
+ import { RemoteIngressHubLifecycle, RemoteIngressManager, TunnelManager } from './remoteingress/index.js';
10
+ import { VpnAccessResolver, VpnManager } from './vpn/index.js';
11
11
  import { RouteConfigManager, ApiTokenManager, GatewayClientManager, ReferenceResolver, TargetProfileManager } from './config/index.js';
12
- import { SecurityPolicyManager } from './security/index.js';
12
+ import { SecurityPolicyManager, RoutePolicyAugmenter } from './security/index.js';
13
13
  import { type IHttp3Config } from './http3/index.js';
14
14
  import { DnsManager } from './dns/manager.dns.js';
15
+ import { DnsServerRuntime } from './dns/classes.dns-server-runtime.js';
15
16
  import { AcmeConfigManager } from './acme/manager.acme-config.js';
16
- import { EmailDomainManager, EmailSettingsManager, WorkAppMailManager } from './email/index.js';
17
+ import { SmartAcmeLifecycle } from './acme/classes.smartacme-lifecycle.js';
18
+ import { AcceptedEmailSpool, EmailDomainManager, EmailRouteBuilder, EmailSettingsManager, WorkAppMailManager } from './email/index.js';
17
19
  import type { IEmailPortConfig, IEmailServerSettings, TEmailServerSettingsUpdate } from '../dist_ts_interfaces/data/email-settings.js';
18
- import type { IRemoteIngressHubSettings, TRemoteIngressHubSettingsUpdate } from '../dist_ts_interfaces/data/remoteingress.js';
20
+ import type { IDcRouterRouteConfig, IRemoteIngressHubSettings, TRemoteIngressHubSettingsUpdate } from '../dist_ts_interfaces/data/remoteingress.js';
19
21
  export interface IDcRouterOptions {
20
22
  /** Base directory for all dcrouter data. Defaults to ~/.serve.zone/dcrouter */
21
23
  baseDir?: string;
@@ -224,16 +226,8 @@ export declare class DcRouter {
224
226
  cacheCleaner?: CacheCleaner;
225
227
  remoteIngressManager?: RemoteIngressManager;
226
228
  tunnelManager?: TunnelManager;
227
- private remoteIngressHubLifecycleChain;
228
229
  private smartProxyLifecycleChain;
229
230
  private emailLifecycleChain;
230
- private acceptedEmailSpoolTimer?;
231
- private acceptedEmailSpoolRun?;
232
- private acceptedEmailSpoolProcessing;
233
- private acceptedEmailSpoolStopping;
234
- private acceptedEmailQueueUpdatePromises;
235
- private remoteIngressHubStopping;
236
- private remoteIngressHubGeneration;
237
231
  vpnManager?: VpnManager;
238
232
  routeConfigManager?: RouteConfigManager;
239
233
  apiTokenManager?: ApiTokenManager;
@@ -245,12 +239,9 @@ export declare class DcRouter {
245
239
  emailSettingsManager?: EmailSettingsManager;
246
240
  emailDomainManager?: EmailDomainManager;
247
241
  workAppMailManager: WorkAppMailManager;
242
+ acceptedEmailSpool: AcceptedEmailSpool;
248
243
  securityPolicyManager?: SecurityPolicyManager;
249
244
  detectedPublicIp: string | null;
250
- private dnsLogWindowSecond;
251
- private dnsLogWindowCount;
252
- private dnsBatchCount;
253
- private dnsBatchTimer;
254
245
  certificateStatusMap: Map<string, {
255
246
  status: "valid" | "failed";
256
247
  routeNames: string[];
@@ -262,15 +253,15 @@ export declare class DcRouter {
262
253
  certProvisionScheduler?: CertProvisionScheduler;
263
254
  serviceManager: plugins.taskbuffer.ServiceManager;
264
255
  private serviceSubjectSubscription?;
265
- smartAcmeReady: boolean;
266
- private smartAcmeServiceStarted;
267
- private smartAcmeStartGeneration;
268
- private smartAcmeStartPromise?;
269
- private smartAcmeRetryTimer?;
270
- private smartAcmeRetryAttempt;
256
+ smartAcmeLifecycle: SmartAcmeLifecycle;
257
+ vpnAccessResolver: VpnAccessResolver;
258
+ remoteIngressHubLifecycle: RemoteIngressHubLifecycle;
259
+ dnsServerRuntime: DnsServerRuntime;
260
+ emailRouteBuilder: EmailRouteBuilder;
261
+ routePolicyAugmenter: RoutePolicyAugmenter;
271
262
  typedrouter: plugins.typedrequest.TypedRouter<import("@api.global/typedrequest-interfaces").ITypedRequest>;
272
263
  private seedConfigRoutes;
273
- private seedEmailRoutes;
264
+ seedEmailRoutes: IDcRouterRouteConfig[];
274
265
  private seedDnsRoutes;
275
266
  private runtimeDnsRoutes;
276
267
  private qenv;
@@ -280,15 +271,9 @@ export declare class DcRouter {
280
271
  * Services are started in dependency order, with failure isolation for optional services.
281
272
  */
282
273
  private registerServices;
283
- private isRemoteIngressHubEnabled;
274
+ isRemoteIngressHubEnabled(): boolean;
284
275
  private getRemoteIngressHubSettingsMigrationSeed;
285
276
  private getEmailSettingsMigrationSeed;
286
- private startSmartAcmeInBackground;
287
- private scheduleSmartAcmeStart;
288
- private runSmartAcmeStartAttempt;
289
- private retriggerCertificateProvisioningAfterSmartAcmeReady;
290
- private clearSmartAcmeRetryTimer;
291
- private stopSmartAcme;
292
277
  start(): Promise<void>;
293
278
  /**
294
279
  * Detect OS-level resource limits and warn if they are too low for production use.
@@ -308,27 +293,10 @@ export declare class DcRouter {
308
293
  */
309
294
  private setupSmartProxy;
310
295
  applySecurityPolicy(): Promise<void>;
311
- private mergeSecurityPolicies;
312
- private applyInboundProxyProtocolPolicies;
313
- private getDesiredInboundProxyProtocolPolicy;
314
- private getInboundProxyListenerKeys;
315
- private mergeInboundProxyProtocolPolicies;
316
- /**
317
- * Generate SmartProxy routes for email configuration
318
- */
319
- private generateEmailRoutes;
320
296
  /**
321
297
  * Generate SmartProxy routes for DNS configuration
322
298
  */
323
299
  private generateDnsRoutes;
324
- private getRuntimeEmailRoutes;
325
- private getCurrentGeneratedEmailRouteNames;
326
- private shouldHydrateGeneratedEmailRoute;
327
- private createServerFirstEmailRuntimeRoute;
328
- private getRemoteIngressEmailInboundProxyPolicy;
329
- private createEmailSocketProxyHandler;
330
- private createProxyProtocolV1Header;
331
- private hydrateStoredRouteForRuntime;
332
300
  /**
333
301
  * Check if a domain matches a pattern (including wildcard support)
334
302
  * @param domain The domain to check
@@ -351,26 +319,6 @@ export declare class DcRouter {
351
319
  * This implements the consolidated emailConfig approach
352
320
  */
353
321
  private setupUnifiedEmailHandling;
354
- private acceptSmartMtaMessage;
355
- private setDcRouterCacheIdHeader;
356
- private processAcceptedCachedEmail;
357
- private startAcceptedEmailSpoolProcessor;
358
- private clearAcceptedEmailSpoolTimer;
359
- private stopAcceptedEmailSpoolProcessor;
360
- private runAcceptedEmailSpoolProcessor;
361
- private processAcceptedEmailSpool;
362
- private buildCachedEmailSession;
363
- private parseCachedEmailRouteData;
364
- private updateAcceptedEmailFromQueueItem;
365
- private trackAcceptedEmailQueueUpdate;
366
- private drainAcceptedEmailQueueUpdates;
367
- private waitForPromiseToSettleWithTimeout;
368
- private recoverQueuedAcceptedEmails;
369
- private isCachedEmailTerminal;
370
- private getCachedEmailIdFromQueueItem;
371
- private getHeaderValue;
372
- private removeHeader;
373
- private throwIfMessageAcceptanceAborted;
374
322
  /**
375
323
  * Update the unified email configuration
376
324
  * @param config New email configuration
@@ -394,90 +342,24 @@ export declare class DcRouter {
394
342
  * Register DNS records with the DNS server
395
343
  * @param records Array of DNS records to register
396
344
  */
397
- private registerDnsRecords;
398
- /**
399
- * Parse DNS record data based on record type
400
- * @param type DNS record type
401
- * @param value DNS record value
402
- * @returns Parsed data for the DNS response
403
- */
404
- private parseDnsRecordData;
405
- /**
406
- * Set up DNS server with socket handler for DoH
407
- */
408
- private setupDnsWithSocketHandler;
409
- /**
410
- * Create DNS socket handler for DoH
411
- */
412
- private createDnsSocketHandler;
413
- /**
414
- * Validate DNS configuration
415
- */
416
- private validateDnsConfiguration;
417
- /**
418
- * Generate email DNS records for domains with internal-dns mode
419
- */
420
- private generateEmailDnsRecords;
421
- /**
422
- * Generate DKIM DNS records for internal-dns domains from smartmta's selector-aware DKIM state.
423
- */
424
- private loadDkimRecords;
425
- /**
426
- * Initialize DKIM keys for all configured email domains
427
- * This ensures DKIM records are available immediately at startup
428
- */
429
- private initializeDkimForEmailDomains;
430
- /**
431
- * Generate authoritative DNS records (NS only) for all domains in dnsScopes
432
- * SOA records are now automatically generated by smartdns with primaryNameserver setting
433
- */
434
- private generateAuthoritativeRecords;
435
- /**
436
- * Extract the base domain from a DNS record name
437
- */
438
- private extractDomain;
439
- /**
440
- * Apply proxy IP replacement logic to DNS records
441
- */
442
- private applyProxyIpReplacement;
443
345
  private addEmailEventSubscription;
444
346
  private clearEmailEventSubscriptions;
445
- /**
446
- * Detect the server's public IP address
447
- */
448
- private detectServerPublicIp;
449
347
  /**
450
348
  * Set up Remote Ingress hub for edge tunnel connections
451
349
  */
452
- private setupRemoteIngress;
453
- private isRemoteIngressHubGenerationCurrent;
454
- private queueRemoteIngressHubTask;
455
350
  private queueSmartProxyLifecycleTask;
456
351
  private queueEmailLifecycleTask;
457
- private stopRemoteIngress;
352
+ /** Serialized edge mutation on the RemoteIngress hub (delegates to the hub lifecycle). */
458
353
  mutateRemoteIngressEdges<T>(mutation: (manager: RemoteIngressManager) => Promise<T>, syncAllowedEdges?: boolean): Promise<T>;
459
- private updateRemoteIngressRoutes;
460
354
  updateRemoteIngressHubSettings(updates: TRemoteIngressHubSettingsUpdate, updatedBy: string): Promise<IRemoteIngressHubSettings>;
461
- private restartSmartProxyForRemoteIngressSettings;
462
- private stopRemoteIngressTunnelHubLocked;
463
- private restartRemoteIngressTunnelHubLocked;
464
- private startRemoteIngressTunnelHubLocked;
465
- private resolveRemoteIngressTlsConfig;
355
+ /** Restart SmartProxy after RemoteIngress hub settings changed listener wiring. Called by RemoteIngressHubLifecycle. */
356
+ restartSmartProxyForRemoteIngressSettings(): Promise<void>;
357
+ /** Bootstrap routes the RemoteIngress hub uses to derive edge ports before the DB route set is applied. */
358
+ getRemoteIngressBootstrapRoutes(): plugins.smartproxy.IRouteConfig[];
466
359
  /**
467
360
  * Set up VPN server for VPN-based route access control.
468
361
  */
469
- private createVpnClientAccessResolver;
470
362
  private setupVpnServer;
471
- /** Cache for DNS-resolved IPs of VPN-gated domains. TTL: 5 minutes. */
472
- private vpnDomainIpCache;
473
- /** Deduplicate wildcard-resolution warnings for WireGuard AllowedIPs generation. */
474
- private warnedWildcardVpnDomains;
475
- /**
476
- * Resolve a domain's A record(s) for VPN AllowedIPs, with a 5-minute cache.
477
- */
478
- private resolveVpnDomainIPs;
479
- private isWildcardVpnDomain;
480
- private logSkippedWildcardAllowedIp;
481
363
  /**
482
364
  * Set up RADIUS server for network authentication
483
365
  */