@serve.zone/dcrouter 17.1.4 → 17.1.6

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 (49) hide show
  1. package/deno.json +1 -1
  2. package/dist_serve/bundle.js +559 -559
  3. package/dist_ts/00_commitinfo_data.js +1 -1
  4. package/dist_ts/classes.dcrouter.js +9 -3
  5. package/dist_ts/db/documents/classes.ip-intelligence.doc.d.ts +10 -0
  6. package/dist_ts/db/documents/classes.ip-intelligence.doc.js +63 -1
  7. package/dist_ts/dns/classes.dns-server-runtime.d.ts +1 -0
  8. package/dist_ts/dns/classes.dns-server-runtime.js +8 -4
  9. package/dist_ts/dns/manager.dns.js +23 -6
  10. package/dist_ts/email/classes.email-domain.manager.js +27 -15
  11. package/dist_ts/email/classes.mail-dns-sync.d.ts +19 -2
  12. package/dist_ts/email/classes.mail-dns-sync.js +158 -32
  13. package/dist_ts/email/index.d.ts +1 -0
  14. package/dist_ts/email/index.js +2 -1
  15. package/dist_ts/email/mail-dns-status.d.ts +5 -0
  16. package/dist_ts/email/mail-dns-status.js +31 -0
  17. package/dist_ts/monitoring/classes.metricscache.d.ts +2 -0
  18. package/dist_ts/monitoring/classes.metricscache.js +28 -6
  19. package/dist_ts/monitoring/classes.metricsmanager.d.ts +10 -0
  20. package/dist_ts/monitoring/classes.metricsmanager.js +99 -31
  21. package/dist_ts/opsserver/handlers/security.handler.js +24 -6
  22. package/dist_ts/opsserver/handlers/stats.handler.js +2 -3
  23. package/dist_ts/remoteingress/classes.hub-lifecycle.js +2 -2
  24. package/dist_ts/security/classes.security-policy-manager.d.ts +17 -0
  25. package/dist_ts/security/classes.security-policy-manager.js +171 -26
  26. package/dist_ts_interfaces/requests/stats.d.ts +7 -0
  27. package/dist_ts_migrations/index.js +395 -9
  28. package/dist_ts_web/00_commitinfo_data.js +1 -1
  29. package/dist_ts_web/appstate/network.js +11 -2
  30. package/dist_ts_web/appstate/ui.js +1 -8
  31. package/package.json +3 -3
  32. package/ts/00_commitinfo_data.ts +1 -1
  33. package/ts/classes.dcrouter.ts +11 -2
  34. package/ts/db/documents/classes.ip-intelligence.doc.ts +75 -0
  35. package/ts/dns/classes.dns-server-runtime.ts +9 -3
  36. package/ts/dns/manager.dns.ts +22 -5
  37. package/ts/email/classes.email-domain.manager.ts +23 -16
  38. package/ts/email/classes.mail-dns-sync.ts +172 -38
  39. package/ts/email/index.ts +1 -0
  40. package/ts/email/mail-dns-status.ts +35 -0
  41. package/ts/monitoring/classes.metricscache.ts +36 -8
  42. package/ts/monitoring/classes.metricsmanager.ts +113 -32
  43. package/ts/opsserver/handlers/security.handler.ts +35 -6
  44. package/ts/opsserver/handlers/stats.handler.ts +1 -2
  45. package/ts/remoteingress/classes.hub-lifecycle.ts +3 -1
  46. package/ts/security/classes.security-policy-manager.ts +193 -26
  47. package/ts_web/00_commitinfo_data.ts +1 -1
  48. package/ts_web/appstate/network.ts +12 -1
  49. package/ts_web/appstate/ui.ts +0 -9
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '17.1.4',
6
+ version: '17.1.6',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
@@ -3,6 +3,8 @@ import * as interfaces from '../../dist_ts_interfaces/index.js';
3
3
  import { appState } from './shared.js';
4
4
  import { getActionContext } from './login.js';
5
5
  import { runBackgroundRefresh } from './shared.js';
6
+ const IP_INTELLIGENCE_REFRESH_INTERVAL_MS = 60_000;
7
+ let lastIpIntelligenceRefreshAt = 0;
6
8
  export const networkStatePart = await appState.getStatePart('network', {
7
9
  connections: [],
8
10
  connectionsByIP: {},
@@ -25,9 +27,16 @@ export const networkStatePart = await appState.getStatePart('network', {
25
27
  error: null,
26
28
  }, 'soft');
27
29
  export function refreshNetworkIpIntelligence(identity, ipAddresses) {
28
- const ips = [...new Set(ipAddresses.filter(Boolean))].slice(0, 100);
30
+ const ips = [...new Set(ipAddresses.map((ip) => ip.trim()).filter(Boolean))]
31
+ .sort()
32
+ .slice(0, 100);
29
33
  if (ips.length === 0)
30
34
  return;
35
+ const now = Date.now();
36
+ if (now - lastIpIntelligenceRefreshAt < IP_INTELLIGENCE_REFRESH_INTERVAL_MS) {
37
+ return;
38
+ }
39
+ lastIpIntelligenceRefreshAt = now;
31
40
  runBackgroundRefresh('networkIpIntelligence', 'IP intelligence refresh failed:', async () => {
32
41
  const intelligenceRequest = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'listIpIntelligence');
33
42
  const intelligenceResponse = await intelligenceRequest.fire({
@@ -119,4 +128,4 @@ export const fetchNetworkStatsAction = networkStatePart.createAction(async (stat
119
128
  }
120
129
  });
121
130
  // ============================================================================
122
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzX3dlYi9hcHBzdGF0ZS9uZXR3b3JrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxVQUFVLE1BQU0sOEJBQThCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDOUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBd0JuRCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLFFBQVEsQ0FBQyxZQUFZLENBQ3pELFNBQVMsRUFDVDtJQUNFLFdBQVcsRUFBRSxFQUFFO0lBQ2YsZUFBZSxFQUFFLEVBQUU7SUFDbkIsY0FBYyxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLENBQUMsRUFBRTtJQUM3RCxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUU7SUFDN0IsTUFBTSxFQUFFLEVBQUU7SUFDVixpQkFBaUIsRUFBRSxFQUFFO0lBQ3JCLE9BQU8sRUFBRSxFQUFFO0lBQ1gsY0FBYyxFQUFFLEVBQUU7SUFDbEIsY0FBYyxFQUFFLEVBQUU7SUFDbEIsY0FBYyxFQUFFLEVBQUU7SUFDbEIsaUJBQWlCLEVBQUUsRUFBRTtJQUNyQixpQkFBaUIsRUFBRSxDQUFDO0lBQ3BCLGFBQWEsRUFBRSxDQUFDO0lBQ2hCLFFBQVEsRUFBRSxFQUFFO0lBQ1osaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixnQkFBZ0IsRUFBRSxJQUFJO0lBQ3RCLFdBQVcsRUFBRSxDQUFDO0lBQ2QsU0FBUyxFQUFFLEtBQUs7SUFDaEIsS0FBSyxFQUFFLElBQUk7Q0FDWixFQUNELE1BQU0sQ0FDUCxD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
131
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzX3dlYi9hcHBzdGF0ZS9uZXR3b3JrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxVQUFVLE1BQU0sOEJBQThCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDOUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRW5ELE1BQU0sbUNBQW1DLEdBQUcsTUFBTSxDQUFDO0FBQ25ELElBQUksMkJBQTJCLEdBQUcsQ0FBQyxDQUFDO0FBd0JwQyxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLFFBQVEsQ0FBQyxZQUFZLENBQ3pELFNBQVMsRUFDVDtJQUNFLFdBQVcsRUFBRSxFQUFFO0lBQ2YsZUFBZSxFQUFFLEVBQUU7SUFDbkIsY0FBYyxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxFQUFFLGlCQUFpQixFQUFFLENBQUMsRUFBRTtJQUM3RCxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUU7SUFDN0IsTUFBTSxFQUFFLEVBQUU7SUFDVixpQkFBaUIsRUFBRSxFQUFFO0lBQ3JCLE9BQU8sRUFBRSxFQUFFO0lBQ1gsY0FBYyxFQUFFLEVBQUU7SUFDbEIsY0FBYyxFQUFFLEVBQUU7SUFDbEIsY0FBYyxFQUFFLEVBQUU7SUFDbEIsaUJBQWlCLEVBQUUsRUFBRTtJQUNyQixpQkFBaUIsRUFBRSxDQUFDO0lBQ3BCLGFBQWEsRUFBRSxDQUFDO0lBQ2hCLFFBQVEsRUFBRSxFQUFFO0lBQ1osaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixnQkFBZ0IsRUFBRSxJQUFJO0lBQ3RCLFdBQVcsRUFBRSxD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
@@ -1,5 +1,4 @@
1
1
  import { appState } from './shared.js';
2
- import { networkStatePart, fetchNetworkStatsAction } from './network.js';
3
2
  import { certificateStatePart, fetchCertificateOverviewAction } from './certificates.js';
4
3
  // Determine initial view from URL path
5
4
  const getInitialView = () => {
@@ -34,12 +33,6 @@ export const toggleAutoRefreshAction = uiStatePart.createAction(async (statePart
34
33
  // Set Active View Action
35
34
  export const setActiveViewAction = uiStatePart.createAction(async (statePartArg, viewName) => {
36
35
  const currentState = statePartArg.getState();
37
- // If switching to network view, ensure we fetch network data
38
- if (viewName === 'network' && currentState.activeView !== 'network') {
39
- setTimeout(() => {
40
- networkStatePart.dispatchAction(fetchNetworkStatsAction, null);
41
- }, 100);
42
- }
43
36
  // If switching to the Domains group, ensure we fetch certificate data
44
37
  // (Certificates is a subview of Domains).
45
38
  if (viewName === 'domains' && currentState.activeView !== 'domains') {
@@ -52,4 +45,4 @@ export const setActiveViewAction = uiStatePart.createAction(async (statePartArg,
52
45
  activeView: viewName,
53
46
  };
54
47
  });
55
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90c193ZWIvYXBwc3RhdGUvdWkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLDhCQUE4QixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFXekYsdUNBQXVDO0FBQ3ZDLE1BQU0sY0FBYyxHQUFHLEdBQVcsRUFBRTtJQUNsQyxNQUFNLElBQUksR0FBRyxPQUFPLE1BQU0sS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDNUUsTUFBTSxVQUFVLEdBQUcsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUM3RixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqRCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekIsT0FBTyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztBQUN2RCxDQUFDLENBQUM7QUFFRiwrREFBK0Q7QUFDL0QsTUFBTSxpQkFBaUIsR0FBRyxHQUFrQixFQUFFO0lBQzVDLE1BQU0sSUFBSSxHQUFHLE9BQU8sTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUM1RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqRCxPQUFPLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7QUFDN0IsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLFlBQVksQ0FDcEQsSUFBSSxFQUNKO0lBQ0UsVUFBVSxFQUFFLGNBQWMsRUFBRTtJQUM1QixhQUFhLEVBQUUsaUJBQWlCLEVBQUU7SUFDbEMsZ0JBQWdCLEVBQUUsS0FBSztJQUN2QixXQUFXLEVBQUUsSUFBSTtJQUNqQixlQUFlLEVBQUUsSUFBSSxFQUFFLFdBQVc7SUFDbEMsS0FBSyxFQUFFLE9BQU87Q0FDZixDQUNGLENBQUM7QUFFRiw2QkFBNkI7QUFDN0IsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsV0FBVyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsWUFBWSxFQUFxQixFQUFFO0lBQ3hHLE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxRQUFRLEVBQUcsQ0FBQztJQUM5QyxPQUFPO1FBQ0wsR0FBRyxZQUFZO1FBQ2YsV0FBVyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVc7S0FDdkMsQ0FBQztBQUNKLENBQUMsQ0FBQyxDQUFDO0FBRUgseUJBQXlCO0FBQ3pCLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQVMsS0FBSyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQXFCLEVBQUU7SUFDdEgsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRyxDQUFDO0lBRTlDLDZEQUE2RDtJQUM3RCxJQUFJLFFBQVEsS0FBSyxTQUFTLElBQUksWUFBWSxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNwRSxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsZ0JBQWdCLENBQUMsY0FBYyxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2pFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNWLENBQUM7SUFFRCxzRUFBc0U7SUFDdEUsMENBQTBDO0lBQzFDLElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxZQUFZLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3BFLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxvQkFBb0IsQ0FBQyxjQUFjLENBQUMsOEJBQThCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDNUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsQ0FBQztJQUVELE9BQU87UUFDTCxHQUFHLFlBQVk7UUFDZixVQUFVLEVBQUUsUUFBUTtLQUNyQixDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUMifQ==
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90c193ZWIvYXBwc3RhdGUvdWkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN2QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQVd6Rix1Q0FBdUM7QUFDdkMsTUFBTSxjQUFjLEdBQUcsR0FBVyxFQUFFO0lBQ2xDLE1BQU0sSUFBSSxHQUFHLE9BQU8sTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUM1RSxNQUFNLFVBQVUsR0FBRyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzdGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QixPQUFPLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO0FBQ3ZELENBQUMsQ0FBQztBQUVGLCtEQUErRDtBQUMvRCxNQUFNLGlCQUFpQixHQUFHLEdBQWtCLEVBQUU7SUFDNUMsTUFBTSxJQUFJLEdBQUcsT0FBTyxNQUFNLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQzVFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pELE9BQU8sUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQztBQUM3QixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsTUFBTSxRQUFRLENBQUMsWUFBWSxDQUNwRCxJQUFJLEVBQ0o7SUFDRSxVQUFVLEVBQUUsY0FBYyxFQUFFO0lBQzVCLGFBQWEsRUFBRSxpQkFBaUIsRUFBRTtJQUNsQyxnQkFBZ0IsRUFBRSxLQUFLO0lBQ3ZCLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLGVBQWUsRUFBRSxJQUFJLEVBQUUsV0FBVztJQUNsQyxLQUFLLEVBQUUsT0FBTztDQUNmLENBQ0YsQ0FBQztBQUVGLDZCQUE2QjtBQUM3QixNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxXQUFXLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxZQUFZLEVBQXFCLEVBQUU7SUFDeEcsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRyxDQUFDO0lBQzlDLE9BQU87UUFDTCxHQUFHLFlBQVk7UUFDZixXQUFXLEVBQUUsQ0FBQyxZQUFZLENBQUMsV0FBVztLQUN2QyxDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUM7QUFFSCx5QkFBeUI7QUFDekIsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsV0FBVyxDQUFDLFlBQVksQ0FBUyxLQUFLLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBcUIsRUFBRTtJQUN0SCxNQUFNLFlBQVksR0FBRyxZQUFZLENBQUMsUUFBUSxFQUFHLENBQUM7SUFFOUMsc0VBQXNFO0lBQ3RFLDBDQUEwQztJQUMxQyxJQUFJLFFBQVEsS0FBSyxTQUFTLElBQUksWUFBWSxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUNwRSxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2Qsb0JBQW9CLENBQUMsY0FBYyxDQUFDLDhCQUE4QixFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzVFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNWLENBQUM7SUFFRCxPQUFPO1FBQ0wsR0FBRyxZQUFZO1FBQ2YsVUFBVSxFQUFFLFFBQVE7S0FDckIsQ0FBQztBQUNKLENBQUMsQ0FBQyxDQUFDIn0=
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@serve.zone/dcrouter",
3
3
  "private": false,
4
- "version": "17.1.4",
4
+ "version": "17.1.6",
5
5
  "description": "A multifaceted routing service handling mail and SMS delivery functions.",
6
6
  "type": "module",
7
7
  "bin": {
@@ -40,7 +40,7 @@
40
40
  "@push.rocks/smartbucket": "^4.6.1",
41
41
  "@push.rocks/smartchallenge": "^1.1.0",
42
42
  "@push.rocks/smartdata": "^7.3.1",
43
- "@push.rocks/smartdb": "^2.13.1",
43
+ "@push.rocks/smartdb": "^2.13.2",
44
44
  "@push.rocks/smartdns": "^7.12.1",
45
45
  "@push.rocks/smartfs": "^1.6.0",
46
46
  "@push.rocks/smartguard": "^3.1.2",
@@ -53,7 +53,7 @@
53
53
  "@push.rocks/smartnetwork": "^4.8.0",
54
54
  "@push.rocks/smartpath": "^6.0.0",
55
55
  "@push.rocks/smartpromise": "^4.2.4",
56
- "@push.rocks/smartproxy": "^27.17.6",
56
+ "@push.rocks/smartproxy": "^27.18.0",
57
57
  "@push.rocks/smartradius": "^1.3.0",
58
58
  "@push.rocks/smartrequest": "^5.0.4",
59
59
  "@push.rocks/smartrx": "^3.0.12",
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '17.1.4',
6
+ version: '17.1.6',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  }
@@ -590,7 +590,9 @@ export class DcRouter {
590
590
  .withStart(async () => {
591
591
  this.remoteIngressManager = new RemoteIngressManager();
592
592
  this.remoteIngressManager.setHubPublicIps([this.options.publicIp]);
593
- this.remoteIngressManager.setOnEdgesChanged((reason) => this.mailDnsSync.requestSync(reason));
593
+ this.remoteIngressManager.setOnEdgesChanged((reason) => (
594
+ this.mailDnsSync.requestEdgeEligibilityCheck(reason)
595
+ ));
594
596
  await this.remoteIngressManager.initialize();
595
597
  })
596
598
  .withStop(async () => {
@@ -816,10 +818,17 @@ export class DcRouter {
816
818
  // Mail DNS reconciliation starts last: it needs persistence, provider
817
819
  // state, the SMTP DKIM creator, and live tunnel topology. Earlier events
818
820
  // only mark the reconciler dirty and are consumed here.
821
+ const mailDnsSyncDependencies = [
822
+ 'DnsManager', 'EmailDomainManager', 'EmailServer', 'RemoteIngress',
823
+ ];
824
+ if (this.options.dnsNsDomains?.length && this.options.dnsScopes?.length) {
825
+ mailDnsSyncDependencies.push('DnsServer');
826
+ }
827
+
819
828
  this.serviceManager.addService(
820
829
  new plugins.taskbuffer.Service('MailDnsSync')
821
830
  .optional()
822
- .dependsOn('DnsManager', 'EmailDomainManager', 'EmailServer', 'RemoteIngress')
831
+ .dependsOn(...mailDnsSyncDependencies)
823
832
  .withStart(async () => {
824
833
  await this.mailDnsSync.start();
825
834
  })
@@ -102,4 +102,79 @@ export class IpIntelligenceDoc extends plugins.smartdata.SmartDataDbDoc<IpIntell
102
102
  public static async findAll(): Promise<IpIntelligenceDoc[]> {
103
103
  return await IpIntelligenceDoc.getInstances({});
104
104
  }
105
+
106
+ public static async findRecent(options: {
107
+ ipAddresses?: string[];
108
+ limit: number;
109
+ }): Promise<IpIntelligenceDoc[]> {
110
+ if (!Number.isSafeInteger(options.limit) || options.limit <= 0) {
111
+ throw new Error('IpIntelligenceDoc.findRecent requires a positive integer limit');
112
+ }
113
+
114
+ const filter = options.ipAddresses
115
+ ? { ipAddress: { $in: options.ipAddresses } }
116
+ : {};
117
+ const collection = (IpIntelligenceDoc as typeof IpIntelligenceDoc & {
118
+ collection: plugins.smartdata.SmartdataCollection<IpIntelligenceDoc>;
119
+ }).collection;
120
+ const cursor = await collection.getCursor(
121
+ filter,
122
+ IpIntelligenceDoc as unknown as typeof plugins.smartdata.SmartDataDbDoc,
123
+ );
124
+ cursor.mongodbCursor.sort({ lastSeenAt: -1, _id: -1 });
125
+ cursor.mongodbCursor.limit(options.limit);
126
+ try {
127
+ return await cursor.toArray();
128
+ } finally {
129
+ await cursor.close();
130
+ }
131
+ }
132
+
133
+ public static async countAll(): Promise<number> {
134
+ return await DcRouterDb.getInstance()
135
+ .getDb()
136
+ .mongoDb
137
+ .collection('IpIntelligenceDoc')
138
+ .countDocuments({});
139
+ }
140
+
141
+ public static async findOldestIds(options: {
142
+ lastSeenBefore?: number;
143
+ limit: number;
144
+ }): Promise<unknown[]> {
145
+ if (!Number.isSafeInteger(options.limit) || options.limit <= 0) {
146
+ throw new Error('IpIntelligenceDoc.findOldestIds requires a positive integer limit');
147
+ }
148
+ const collection = DcRouterDb.getInstance()
149
+ .getDb()
150
+ .mongoDb
151
+ .collection('IpIntelligenceDoc');
152
+ const filter = options.lastSeenBefore === undefined
153
+ ? {}
154
+ : { lastSeenAt: { $lt: options.lastSeenBefore } };
155
+ const cursor = collection
156
+ .find(filter, { projection: { _id: 1 } })
157
+ .sort({ lastSeenAt: 1, _id: 1 })
158
+ .limit(options.limit);
159
+ try {
160
+ const rows = await cursor.toArray();
161
+ return rows.map((row) => row._id);
162
+ } finally {
163
+ await cursor.close();
164
+ }
165
+ }
166
+
167
+ public static async deleteByDocumentIds(documentIds: unknown[]): Promise<number> {
168
+ if (documentIds.length === 0) return 0;
169
+ if (documentIds.length > 500 || documentIds.some((id) => id === undefined || id === null)) {
170
+ throw new Error('IpIntelligenceDoc.deleteByDocumentIds requires 1 to 500 document ids');
171
+ }
172
+ const deleteFilter: Record<string, any> = { _id: { $in: documentIds } };
173
+ const result = await DcRouterDb.getInstance()
174
+ .getDb()
175
+ .mongoDb
176
+ .collection('IpIntelligenceDoc')
177
+ .deleteMany(deleteFilter);
178
+ return result.deletedCount;
179
+ }
105
180
  }
@@ -150,9 +150,7 @@ export class DnsServerRuntime {
150
150
 
151
151
  // Hand the DnsServer to DnsManager so DB-backed local records on
152
152
  // dcrouter-hosted domains get registered too.
153
- if (this.dcRouterRef.dnsManager) {
154
- await this.dcRouterRef.dnsManager.attachDnsServer(dnsServer);
155
- }
153
+ await this.attachDnsServer(dnsServer);
156
154
  } catch (error) {
157
155
  dnsServer.removeAllListeners();
158
156
  await dnsServer.stop().catch((stopError: Error) => {
@@ -166,6 +164,14 @@ export class DnsServerRuntime {
166
164
  }
167
165
  }
168
166
 
167
+ private async attachDnsServer(
168
+ dnsServer: plugins.smartdns.dnsServerMod.DnsServer,
169
+ ): Promise<void> {
170
+ if (!this.dcRouterRef.dnsManager) return;
171
+ await this.dcRouterRef.dnsManager.attachDnsServer(dnsServer);
172
+ this.dcRouterRef.mailDnsSync?.requestSync('DNS server attached');
173
+ }
174
+
169
175
  /**
170
176
  * Create the DoH socket handler SmartProxy routes hand TLS sockets to.
171
177
  */
@@ -690,32 +690,49 @@ export class DnsManager {
690
690
  localByProviderId.set(providerId, record);
691
691
  }
692
692
  const remaining = new Set(existing);
693
+ let mirrorChanged = false;
693
694
  for (let index = 0; index < providerRecords.length; index++) {
694
695
  const pr = providerRecords[index];
695
696
  const providerId = providerIds[index];
696
697
  const match = localByProviderId.get(providerId);
697
698
  if (!match) {
698
699
  await this.createSyncedRecord(id, { ...pr, providerRecordId: providerId }, doc.createdBy);
700
+ mirrorChanged = true;
699
701
  continue;
700
702
  }
701
703
  remaining.delete(match);
702
- match.name = pr.name.toLowerCase();
704
+ const providerName = pr.name.toLowerCase();
705
+ const providerProxied = pr.proxied;
706
+ const changed = match.name !== providerName
707
+ || match.type !== pr.type
708
+ || match.value !== pr.value
709
+ || match.ttl !== pr.ttl
710
+ || (match.proxied ?? false) !== (providerProxied ?? false)
711
+ || match.source !== 'synced'
712
+ || match.providerRecordId !== providerId;
713
+ if (!changed) continue;
714
+
715
+ match.name = providerName;
703
716
  match.type = pr.type;
704
717
  match.value = pr.value;
705
718
  match.ttl = pr.ttl;
706
- match.proxied = pr.proxied;
719
+ match.proxied = providerProxied;
707
720
  match.source = 'synced';
708
721
  match.providerRecordId = providerId;
709
722
  match.updatedAt = Date.now();
710
723
  await match.save();
724
+ mirrorChanged = true;
711
725
  }
712
726
  for (const staleMirror of remaining) {
713
727
  if (staleMirror.source !== 'synced' || !staleMirror.providerRecordId?.trim()) continue;
714
728
  await staleMirror.delete();
729
+ mirrorChanged = true;
730
+ }
731
+ if (mirrorChanged) {
732
+ doc.lastSyncedAt = Date.now();
733
+ doc.updatedAt = doc.lastSyncedAt;
734
+ await doc.save();
715
735
  }
716
- doc.lastSyncedAt = Date.now();
717
- doc.updatedAt = doc.lastSyncedAt;
718
- await doc.save();
719
736
  return {
720
737
  success: true,
721
738
  recordCount: providerRecords.length,
@@ -16,6 +16,7 @@ import {
16
16
  MAIL_DNS_MAX_RETRY_INTERVAL_MS,
17
17
  MAIL_DNS_RETRY_INTERVAL_MS,
18
18
  } from './classes.mail-dns-sync.js';
19
+ import { projectMailDnsIntentStatus } from './mail-dns-status.js';
19
20
 
20
21
  export interface IEmailDomainManagerActionResult {
21
22
  success: boolean;
@@ -325,33 +326,39 @@ export class EmailDomainManager {
325
326
  type: intent.type,
326
327
  name: intent.name,
327
328
  value: intent.value,
328
- status: intent.status === 'valid'
329
- ? 'valid'
330
- : intent.status === 'conflict' || intent.status === 'failed'
331
- ? 'invalid'
332
- : 'missing',
329
+ status: projectMailDnsIntentStatus(intent),
333
330
  }));
334
331
  }
335
332
 
336
333
  public async provisionDnsRecords(id: string): Promise<IEmailDomainManagerActionResult> {
337
- const before = new Set(
338
- (await DnsRecordDoc.findAll()).filter((record) => record.managedBy === 'mail-dns-reconciler').map((record) => record.id),
339
- );
340
- await this.dcRouter.mailDnsSync?.sync(`manual provision: ${id}`);
341
- const doc = await EmailDomainDoc.findById(id);
334
+ const current = await EmailDomainDoc.findById(id);
335
+ if (!current) throw new Error(`Email domain not found: ${id}`);
336
+ const before = new Set((await DnsRecordDoc.findByDomainId(current.linkedDomainId))
337
+ .filter((record) => record.managedBy === 'mail-dns-reconciler').map((record) => record.id));
338
+ const mailDnsSync = this.dcRouter.mailDnsSync;
339
+ if (!mailDnsSync) throw new Error('MailDnsSync is unavailable');
340
+ const ticket = await mailDnsSync.syncDomain(id, `manual provision: ${id}`);
341
+ const doc = ticket.domain;
342
342
  if (!doc) throw new Error(`Email domain not found: ${id}`);
343
- const provisioned = (await DnsRecordDoc.findAll())
343
+ const provisioned = ticket.records
344
344
  .filter((record) => record.managedBy === 'mail-dns-reconciler' && !before.has(record.id)).length;
345
- return { ...this.resultForDoc(doc, !this.hasDnsMutationFailure(doc)), provisioned };
345
+ return { ...this.resultForDoc(doc, true), provisioned };
346
346
  }
347
347
 
348
348
  public async validateDns(id: string): Promise<IEmailDomainManagerActionResult> {
349
- await this.dcRouter.mailDnsSync?.sync(`manual validation: ${id}`);
350
- const doc = await EmailDomainDoc.findById(id);
349
+ const mailDnsSync = this.dcRouter.mailDnsSync;
350
+ if (!mailDnsSync) throw new Error('MailDnsSync is unavailable');
351
+ const ticket = await mailDnsSync.syncDomain(id, `manual validation: ${id}`);
352
+ const doc = ticket.domain;
351
353
  if (!doc) throw new Error(`Email domain not found: ${id}`);
352
- const records = await this.getRequiredDnsRecords(id);
354
+ const records = (doc.reconciliation?.intents || []).map((intent) => ({
355
+ type: intent.type,
356
+ name: intent.name,
357
+ value: intent.value,
358
+ status: projectMailDnsIntentStatus(intent),
359
+ }));
353
360
  return {
354
- ...this.resultForDoc(doc, doc.reconciliation?.lifecycleStatus === 'active'),
361
+ ...this.resultForDoc(doc, true),
355
362
  domain: this.docToInterface(doc),
356
363
  records,
357
364
  };