@serve.zone/dcrouter 16.5.0 → 17.1.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 (153) hide show
  1. package/.smartconfig.json +5 -2
  2. package/deno.json +1 -1
  3. package/dist_serve/bundle.js +1316 -1151
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/classes.dcrouter.d.ts +6 -1
  6. package/dist_ts/classes.dcrouter.js +119 -41
  7. package/dist_ts/db/classes.cache.cleaner.d.ts +3 -0
  8. package/dist_ts/db/classes.cache.cleaner.js +7 -3
  9. package/dist_ts/db/classes.dcrouter-db.js +1 -2
  10. package/dist_ts/db/documents/classes.cached.email.d.ts +41 -4
  11. package/dist_ts/db/documents/classes.cached.email.js +36 -5
  12. package/dist_ts/db/documents/classes.dns-record.doc.js +3 -1
  13. package/dist_ts/db/documents/classes.smartmta-storage.doc.d.ts +8 -0
  14. package/dist_ts/db/documents/classes.smartmta-storage.doc.js +91 -0
  15. package/dist_ts/db/documents/index.d.ts +1 -0
  16. package/dist_ts/db/documents/index.js +2 -1
  17. package/dist_ts/dns/classes.dns-server-runtime.d.ts +0 -1
  18. package/dist_ts/dns/classes.dns-server-runtime.js +4 -36
  19. package/dist_ts/dns/index.d.ts +1 -0
  20. package/dist_ts/dns/index.js +2 -1
  21. package/dist_ts/dns/manager.dns.d.ts +1 -0
  22. package/dist_ts/dns/manager.dns.js +49 -14
  23. package/dist_ts/dns/providers/cloudflare.provider.js +19 -4
  24. package/dist_ts/dns/txt-record-presentation.d.ts +20 -0
  25. package/dist_ts/dns/txt-record-presentation.js +131 -0
  26. package/dist_ts/email/classes.accepted-email-spool.d.ts +32 -3
  27. package/dist_ts/email/classes.accepted-email-spool.js +174 -13
  28. package/dist_ts/email/classes.email-domain.manager.d.ts +14 -1
  29. package/dist_ts/email/classes.email-domain.manager.js +151 -8
  30. package/dist_ts/email/classes.email-settings.manager.js +2 -1
  31. package/dist_ts/email/classes.mail-dns-sync.d.ts +31 -5
  32. package/dist_ts/email/classes.mail-dns-sync.js +508 -117
  33. package/dist_ts/email/classes.smartmta-blob-storage-manager.d.ts +27 -0
  34. package/dist_ts/email/classes.smartmta-blob-storage-manager.js +110 -0
  35. package/dist_ts/email/classes.smartmta-storage-manager.d.ts +6 -8
  36. package/dist_ts/email/classes.smartmta-storage-manager.js +63 -86
  37. package/dist_ts/email/classes.workapp-mail-manager.d.ts +1 -0
  38. package/dist_ts/email/classes.workapp-mail-manager.js +31 -4
  39. package/dist_ts/email/index.d.ts +4 -0
  40. package/dist_ts/email/index.js +5 -1
  41. package/dist_ts/email/mail-dns-txt-policy.d.ts +18 -0
  42. package/dist_ts/email/mail-dns-txt-policy.js +466 -0
  43. package/dist_ts/email/reconcile-mail-dns-singleton.d.ts +47 -0
  44. package/dist_ts/email/reconcile-mail-dns-singleton.js +159 -0
  45. package/dist_ts/email/smartmta-storage-policy.d.ts +9 -0
  46. package/dist_ts/email/smartmta-storage-policy.js +58 -0
  47. package/dist_ts/opsserver/classes.opsserver.d.ts +8 -0
  48. package/dist_ts/opsserver/classes.opsserver.js +34 -1
  49. package/dist_ts/opsserver/handlers/certificate.handler.js +25 -4
  50. package/dist_ts/opsserver/handlers/config.handler.js +9 -5
  51. package/dist_ts/opsserver/handlers/dns-provider.handler.js +19 -2
  52. package/dist_ts/opsserver/handlers/dns-record.handler.js +25 -4
  53. package/dist_ts/opsserver/handlers/domain.handler.js +37 -3
  54. package/dist_ts/opsserver/handlers/email-domain.handler.js +5 -7
  55. package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +1 -0
  56. package/dist_ts/opsserver/handlers/email-ops.handler.js +26 -7
  57. package/dist_ts/opsserver/handlers/index.d.ts +1 -0
  58. package/dist_ts/opsserver/handlers/index.js +2 -1
  59. package/dist_ts/opsserver/handlers/logs.handler.d.ts +1 -1
  60. package/dist_ts/opsserver/handlers/logs.handler.js +3 -3
  61. package/dist_ts/opsserver/handlers/realtime.handler.d.ts +37 -0
  62. package/dist_ts/opsserver/handlers/realtime.handler.js +154 -0
  63. package/dist_ts/opsserver/handlers/remoteingress.handler.js +22 -1
  64. package/dist_ts/opsserver/handlers/route-management.handler.js +47 -5
  65. package/dist_ts/opsserver/handlers/stats.handler.js +3 -5
  66. package/dist_ts/paths.d.ts +0 -11
  67. package/dist_ts/paths.js +1 -22
  68. package/dist_ts/plugins.d.ts +2 -35
  69. package/dist_ts/plugins.js +3 -63
  70. package/dist_ts_interfaces/data/email-domain.d.ts +14 -0
  71. package/dist_ts_interfaces/requests/config.d.ts +1 -1
  72. package/dist_ts_interfaces/requests/email-ops.d.ts +34 -1
  73. package/dist_ts_interfaces/requests/index.d.ts +1 -0
  74. package/dist_ts_interfaces/requests/index.js +2 -1
  75. package/dist_ts_interfaces/requests/realtime.d.ts +38 -0
  76. package/dist_ts_interfaces/requests/realtime.js +11 -0
  77. package/dist_ts_migrations/index.d.ts +8 -0
  78. package/dist_ts_migrations/index.js +489 -12
  79. package/dist_ts_web/00_commitinfo_data.js +1 -1
  80. package/dist_ts_web/appstate/certificates.js +9 -2
  81. package/dist_ts_web/appstate/domains.js +16 -5
  82. package/dist_ts_web/appstate/email-domains.d.ts +3 -0
  83. package/dist_ts_web/appstate/email-domains.js +47 -14
  84. package/dist_ts_web/appstate/email-ops.d.ts +1 -0
  85. package/dist_ts_web/appstate/email-ops.js +20 -2
  86. package/dist_ts_web/appstate/realtime.d.ts +27 -0
  87. package/dist_ts_web/appstate/realtime.js +71 -0
  88. package/dist_ts_web/appstate/remoteingress.js +9 -3
  89. package/dist_ts_web/appstate/routes.js +16 -5
  90. package/dist_ts_web/appstate/runtime.js +135 -7
  91. package/dist_ts_web/appstate.d.ts +1 -0
  92. package/dist_ts_web/appstate.js +2 -1
  93. package/dist_ts_web/elements/email/email-domain-creation-progress.d.ts +33 -0
  94. package/dist_ts_web/elements/email/email-domain-creation-progress.js +257 -0
  95. package/dist_ts_web/elements/email/ops-view-email-domains.js +233 -68
  96. package/dist_ts_web/elements/email/ops-view-emails.d.ts +4 -2
  97. package/dist_ts_web/elements/email/ops-view-emails.js +25 -13
  98. package/dist_ts_web/elements/overview/ops-view-config.js +5 -5
  99. package/package.json +23 -19
  100. package/ts/00_commitinfo_data.ts +1 -1
  101. package/ts/classes.dcrouter.ts +136 -44
  102. package/ts/db/classes.cache.cleaner.ts +18 -3
  103. package/ts/db/classes.dcrouter-db.ts +0 -2
  104. package/ts/db/documents/classes.cached.email.ts +78 -4
  105. package/ts/db/documents/classes.dns-record.doc.ts +1 -0
  106. package/ts/db/documents/classes.smartmta-storage.doc.ts +25 -0
  107. package/ts/db/documents/index.ts +1 -0
  108. package/ts/dns/classes.dns-server-runtime.ts +9 -45
  109. package/ts/dns/index.ts +1 -0
  110. package/ts/dns/manager.dns.ts +50 -16
  111. package/ts/dns/providers/cloudflare.provider.ts +21 -3
  112. package/ts/dns/txt-record-presentation.ts +134 -0
  113. package/ts/email/classes.accepted-email-spool.ts +220 -14
  114. package/ts/email/classes.email-domain.manager.ts +201 -7
  115. package/ts/email/classes.email-settings.manager.ts +1 -0
  116. package/ts/email/classes.mail-dns-sync.ts +588 -122
  117. package/ts/email/classes.smartmta-blob-storage-manager.ts +139 -0
  118. package/ts/email/classes.smartmta-storage-manager.ts +86 -83
  119. package/ts/email/classes.workapp-mail-manager.ts +47 -4
  120. package/ts/email/index.ts +4 -0
  121. package/ts/email/mail-dns-txt-policy.ts +505 -0
  122. package/ts/email/reconcile-mail-dns-singleton.ts +224 -0
  123. package/ts/email/smartmta-storage-policy.ts +73 -0
  124. package/ts/opsserver/classes.opsserver.ts +42 -0
  125. package/ts/opsserver/handlers/certificate.handler.ts +24 -3
  126. package/ts/opsserver/handlers/config.handler.ts +9 -5
  127. package/ts/opsserver/handlers/dns-provider.handler.ts +18 -1
  128. package/ts/opsserver/handlers/dns-record.handler.ts +24 -3
  129. package/ts/opsserver/handlers/domain.handler.ts +36 -2
  130. package/ts/opsserver/handlers/email-domain.handler.ts +4 -5
  131. package/ts/opsserver/handlers/email-ops.handler.ts +29 -6
  132. package/ts/opsserver/handlers/index.ts +1 -0
  133. package/ts/opsserver/handlers/logs.handler.ts +2 -2
  134. package/ts/opsserver/handlers/realtime.handler.ts +222 -0
  135. package/ts/opsserver/handlers/remoteingress.handler.ts +21 -0
  136. package/ts/opsserver/handlers/route-management.handler.ts +46 -4
  137. package/ts/opsserver/handlers/stats.handler.ts +2 -4
  138. package/ts/paths.ts +0 -25
  139. package/ts/plugins.ts +2 -69
  140. package/ts_web/00_commitinfo_data.ts +1 -1
  141. package/ts_web/appstate/certificates.ts +6 -1
  142. package/ts_web/appstate/domains.ts +11 -4
  143. package/ts_web/appstate/email-domains.ts +68 -14
  144. package/ts_web/appstate/email-ops.ts +20 -1
  145. package/ts_web/appstate/realtime.ts +109 -0
  146. package/ts_web/appstate/remoteingress.ts +6 -2
  147. package/ts_web/appstate/routes.ts +11 -4
  148. package/ts_web/appstate/runtime.ts +176 -7
  149. package/ts_web/appstate.ts +1 -0
  150. package/ts_web/elements/email/email-domain-creation-progress.ts +340 -0
  151. package/ts_web/elements/email/ops-view-email-domains.ts +273 -74
  152. package/ts_web/elements/email/ops-view-emails.ts +23 -16
  153. package/ts_web/elements/overview/ops-view-config.ts +4 -4
@@ -0,0 +1,131 @@
1
+ const textEncoder = new TextEncoder();
2
+ const textDecoder = new TextDecoder('utf-8', { fatal: true });
3
+ function appendCharacterBytes(target, character) {
4
+ target.push(...textEncoder.encode(character));
5
+ }
6
+ /**
7
+ * Decode the representation returned by DNS provider APIs for TXT records.
8
+ *
9
+ * Cloudflare uses RFC 1035 presentation syntax (one or more adjacent quoted
10
+ * character strings). Some older API responses and dcrouter mirrors contain
11
+ * the already-decoded payload, so an unquoted input is accepted as canonical.
12
+ * A value that starts as presentation syntax must parse completely; malformed
13
+ * quoting or escaping is never repaired by stripping quote characters.
14
+ */
15
+ export function decodeTxtRecordContent(input) {
16
+ const source = input.trim();
17
+ if (!source.startsWith('"')) {
18
+ return { ok: true, value: source, wasPresentation: false };
19
+ }
20
+ const bytes = [];
21
+ let index = 0;
22
+ let chunkCount = 0;
23
+ while (index < source.length) {
24
+ while (/\s/.test(source[index] || ''))
25
+ index++;
26
+ if (index >= source.length)
27
+ break;
28
+ if (source[index] !== '"') {
29
+ return { ok: false, error: `Unexpected TXT presentation content at offset ${index}` };
30
+ }
31
+ chunkCount++;
32
+ index++;
33
+ let closed = false;
34
+ while (index < source.length) {
35
+ const character = source[index];
36
+ if (character === '"') {
37
+ index++;
38
+ closed = true;
39
+ break;
40
+ }
41
+ if (character === '\\') {
42
+ index++;
43
+ if (index >= source.length) {
44
+ return { ok: false, error: 'TXT presentation ends with an incomplete escape' };
45
+ }
46
+ if (/\d/.test(source[index])) {
47
+ const decimalEscape = source.slice(index, index + 3);
48
+ if (!/^\d{3}$/.test(decimalEscape)) {
49
+ return { ok: false, error: `Invalid TXT decimal escape at offset ${index - 1}` };
50
+ }
51
+ const byte = Number.parseInt(decimalEscape, 10);
52
+ if (byte > 255) {
53
+ return { ok: false, error: `TXT decimal escape exceeds 255 at offset ${index - 1}` };
54
+ }
55
+ bytes.push(byte);
56
+ index += 3;
57
+ continue;
58
+ }
59
+ const escapedCodePoint = source.codePointAt(index);
60
+ if (escapedCodePoint === undefined) {
61
+ return { ok: false, error: `Invalid TXT escape at offset ${index - 1}` };
62
+ }
63
+ const escapedCharacter = String.fromCodePoint(escapedCodePoint);
64
+ appendCharacterBytes(bytes, escapedCharacter);
65
+ index += escapedCharacter.length;
66
+ continue;
67
+ }
68
+ const codePoint = source.codePointAt(index);
69
+ if (codePoint === undefined) {
70
+ return { ok: false, error: `Invalid TXT character at offset ${index}` };
71
+ }
72
+ const nextCharacter = String.fromCodePoint(codePoint);
73
+ appendCharacterBytes(bytes, nextCharacter);
74
+ index += nextCharacter.length;
75
+ }
76
+ if (!closed) {
77
+ return { ok: false, error: 'TXT presentation contains an unterminated character string' };
78
+ }
79
+ while (/\s/.test(source[index] || ''))
80
+ index++;
81
+ if (index < source.length && source[index] !== '"') {
82
+ return { ok: false, error: `Unexpected TXT presentation content at offset ${index}` };
83
+ }
84
+ }
85
+ if (chunkCount === 0) {
86
+ return { ok: false, error: 'TXT presentation contains no character strings' };
87
+ }
88
+ try {
89
+ return { ok: true, value: textDecoder.decode(Uint8Array.from(bytes)), wasPresentation: true };
90
+ }
91
+ catch {
92
+ return { ok: false, error: 'TXT presentation is not valid UTF-8' };
93
+ }
94
+ }
95
+ function escapeTxtChunk(chunk) {
96
+ let result = '';
97
+ for (const character of chunk) {
98
+ const codePoint = character.codePointAt(0);
99
+ if (character === '"' || character === '\\') {
100
+ result += `\\${character}`;
101
+ }
102
+ else if (codePoint < 32 || codePoint === 127) {
103
+ for (const byte of textEncoder.encode(character)) {
104
+ result += `\\${byte.toString(10).padStart(3, '0')}`;
105
+ }
106
+ }
107
+ else {
108
+ result += character;
109
+ }
110
+ }
111
+ return result;
112
+ }
113
+ /** Encode a canonical TXT payload as Cloudflare/RFC 1035 presentation text. */
114
+ export function encodeCloudflareTxtContent(value) {
115
+ const chunks = [];
116
+ let current = '';
117
+ let currentBytes = 0;
118
+ for (const character of value) {
119
+ const characterBytes = textEncoder.encode(character).length;
120
+ if (currentBytes > 0 && currentBytes + characterBytes > 255) {
121
+ chunks.push(current);
122
+ current = '';
123
+ currentBytes = 0;
124
+ }
125
+ current += character;
126
+ currentBytes += characterBytes;
127
+ }
128
+ chunks.push(current);
129
+ return chunks.map((chunk) => `"${escapeTxtChunk(chunk)}"`).join(' ');
130
+ }
131
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHh0LXJlY29yZC1wcmVzZW50YXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9kbnMvdHh0LXJlY29yZC1wcmVzZW50YXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsTUFBTSxXQUFXLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztBQUN0QyxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUU5RCxTQUFTLG9CQUFvQixDQUFDLE1BQWdCLEVBQUUsU0FBaUI7SUFDL0QsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsS0FBYTtJQUNsRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM1QixPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUM3RCxDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBQzNCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNkLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztJQUNuQixPQUFPLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDN0IsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7WUFBRSxLQUFLLEVBQUUsQ0FBQztRQUMvQyxJQUFJLEtBQUssSUFBSSxNQUFNLENBQUMsTUFBTTtZQUFFLE1BQU07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
@@ -1,9 +1,11 @@
1
1
  import * as plugins from '../plugins.js';
2
- import type { TCachedEmailDirection } from '../db/documents/classes.cached.email.js';
3
- import type { IExtendedSmtpSession, IMessageAcceptanceContext, IMessageAcceptanceDecision } from '@push.rocks/smartmta';
2
+ import { CachedEmail } from '../db/index.js';
3
+ import type { ICachedEmailSmtpTransaction, TCachedEmailDirection } from '../db/documents/classes.cached.email.js';
4
+ import type { IExtendedSmtpSession, IMessageAcceptanceContext, IMessageAcceptanceDecision, UnifiedEmailServer } from '@push.rocks/smartmta';
4
5
  import type { DcRouter } from '../classes.dcrouter.js';
5
6
  export declare const DCROUTER_CACHE_ID_HEADER = "X-Dcrouter-Cached-Email-Id";
6
7
  export type TSmartMtaQueueItemLike = {
8
+ id?: string;
7
9
  processingResult?: {
8
10
  headers?: Record<string, string>;
9
11
  email?: {
@@ -14,7 +16,17 @@ export type TSmartMtaQueueItemLike = {
14
16
  attempts?: number;
15
17
  nextAttempt?: Date;
16
18
  lastError?: string;
19
+ smtpTransactions?: ICachedEmailSmtpTransaction[];
17
20
  };
21
+ export interface IEmailQueuePersistedEvent {
22
+ cachedEmailId: string;
23
+ status: string;
24
+ reason: string;
25
+ }
26
+ export interface ISmtpTransactionPersistedEvent {
27
+ cachedEmailId: string;
28
+ transaction: ICachedEmailSmtpTransaction;
29
+ }
18
30
  export interface IAcceptRawEmailOptions {
19
31
  rawMessage: string | plugins.buffer.Buffer;
20
32
  envelope: {
@@ -40,6 +52,9 @@ export declare class AcceptedEmailSpool {
40
52
  private processing;
41
53
  private stopping;
42
54
  private queueUpdatePromises;
55
+ private cachedEmailUpdateChains;
56
+ private smtpTransactionListeners;
57
+ private emailQueuePersistedListeners;
43
58
  constructor(dcRouterRef: DcRouter);
44
59
  acceptMessage(context: IMessageAcceptanceContext, processAfterAccept?: boolean): Promise<IMessageAcceptanceDecision>;
45
60
  acceptRawMessage(optionsArg: IAcceptRawEmailOptions): Promise<IMessageAcceptanceDecision & {
@@ -53,8 +68,16 @@ export declare class AcceptedEmailSpool {
53
68
  stop(): Promise<void>;
54
69
  /** Kick off a spool run unless one is already in flight. */
55
70
  run(): void;
56
- trackQueueUpdate(item: TSmartMtaQueueItemLike, status: 'queued' | 'deferred' | 'delivered' | 'failed', failureMessage: string): void;
71
+ trackQueueUpdate(item: TSmartMtaQueueItemLike, status: 'queued' | 'deferred' | 'delivered' | 'failed', failureMessage: string): Promise<void>;
72
+ trackSmtpTransaction(transactionArg: ICachedEmailSmtpTransaction, emailServerArg: UnifiedEmailServer): Promise<void>;
73
+ /** Subscribe to updates only after the SMTP transaction is durably stored. */
74
+ onSmtpTransactionPersisted(listenerArg: (eventArg: ISmtpTransactionPersistedEvent) => void | Promise<void>): () => void;
75
+ /** Subscribe to queue state changes only after the CachedEmail row is durable. */
76
+ onEmailQueuePersisted(listenerArg: (eventArg: IEmailQueuePersistedEvent) => void | Promise<void>): () => void;
77
+ private notifyEmailQueuePersisted;
57
78
  drainQueueUpdates(): Promise<void>;
79
+ /** Reconcile persisted queue traces after restart before queue recovery runs. */
80
+ recoverSmtpTransactionHistory(emailServerArg: UnifiedEmailServer): Promise<void>;
58
81
  /** Requeue emails left in 'queued' state by a previous process as pending. */
59
82
  recoverQueuedEmails(): Promise<void>;
60
83
  private processSpool;
@@ -73,6 +96,12 @@ export declare class AcceptedEmailSpool {
73
96
  private getLiveQueueItemForCachedEmail;
74
97
  private getHeaderValue;
75
98
  private updateSmartMtaRouteData;
99
+ readRawMessage(cachedEmailArg: CachedEmail): Promise<plugins.buffer.Buffer>;
100
+ deleteRawMessage(cachedEmailArg: CachedEmail): Promise<void>;
101
+ private persistRawMessage;
102
+ private runCachedEmailUpdate;
103
+ private trackUpdatePromise;
104
+ private appendSmtpTransaction;
76
105
  private removeHeader;
77
106
  private throwIfMessageAcceptanceAborted;
78
107
  }