@brightchain/brightchain-api-lib 0.25.0 → 0.27.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 (130) hide show
  1. package/package.json +4 -3
  2. package/src/lib/appConstants.d.ts +1 -1
  3. package/src/lib/appConstants.js +1 -1
  4. package/src/lib/application.d.ts +3 -14
  5. package/src/lib/application.d.ts.map +1 -1
  6. package/src/lib/application.js +91 -34
  7. package/src/lib/application.js.map +1 -1
  8. package/src/lib/constants.d.ts.map +1 -1
  9. package/src/lib/constants.js +1 -1
  10. package/src/lib/constants.js.map +1 -1
  11. package/src/lib/databaseInit.d.ts +7 -11
  12. package/src/lib/databaseInit.d.ts.map +1 -1
  13. package/src/lib/databaseInit.js +41 -107
  14. package/src/lib/databaseInit.js.map +1 -1
  15. package/src/lib/datastore/block-document-store-factory.d.ts +3 -0
  16. package/src/lib/datastore/block-document-store-factory.d.ts.map +1 -1
  17. package/src/lib/datastore/block-document-store-factory.js +15 -18
  18. package/src/lib/datastore/block-document-store-factory.js.map +1 -1
  19. package/src/lib/datastore/block-document-store.d.ts +2 -191
  20. package/src/lib/datastore/block-document-store.d.ts.map +1 -1
  21. package/src/lib/datastore/block-document-store.js +4 -628
  22. package/src/lib/datastore/block-document-store.js.map +1 -1
  23. package/src/lib/datastore/document-store.d.ts +1 -62
  24. package/src/lib/datastore/document-store.d.ts.map +1 -1
  25. package/src/lib/datastore/memory-document-store.d.ts +1 -8
  26. package/src/lib/datastore/memory-document-store.d.ts.map +1 -1
  27. package/src/lib/datastore/memory-document-store.js +3 -214
  28. package/src/lib/datastore/memory-document-store.js.map +1 -1
  29. package/src/lib/environment.d.ts +4 -47
  30. package/src/lib/environment.d.ts.map +1 -1
  31. package/src/lib/environment.js +2 -136
  32. package/src/lib/environment.js.map +1 -1
  33. package/src/lib/interfaces/environment.d.ts +3 -25
  34. package/src/lib/interfaces/environment.d.ts.map +1 -1
  35. package/src/lib/interfaces/responses/emailGatewayResponses.d.ts +30 -0
  36. package/src/lib/interfaces/responses/emailGatewayResponses.d.ts.map +1 -0
  37. package/src/lib/interfaces/responses/emailGatewayResponses.js +3 -0
  38. package/src/lib/interfaces/responses/emailGatewayResponses.js.map +1 -0
  39. package/src/lib/interfaces/responses/index.d.ts +1 -0
  40. package/src/lib/interfaces/responses/index.d.ts.map +1 -1
  41. package/src/lib/middleware/index.d.ts +1 -1
  42. package/src/lib/middleware/index.d.ts.map +1 -1
  43. package/src/lib/middleware/index.js +3 -2
  44. package/src/lib/middleware/index.js.map +1 -1
  45. package/src/lib/middleware/validateBody.d.ts +1 -12
  46. package/src/lib/middleware/validateBody.d.ts.map +1 -1
  47. package/src/lib/middleware/validateBody.js +4 -32
  48. package/src/lib/middleware/validateBody.js.map +1 -1
  49. package/src/lib/middlewares.d.ts.map +1 -1
  50. package/src/lib/middlewares.js +7 -1
  51. package/src/lib/middlewares.js.map +1 -1
  52. package/src/lib/plugins/brightchain-database-plugin.d.ts +27 -79
  53. package/src/lib/plugins/brightchain-database-plugin.d.ts.map +1 -1
  54. package/src/lib/plugins/brightchain-database-plugin.js +32 -103
  55. package/src/lib/plugins/brightchain-database-plugin.js.map +1 -1
  56. package/src/lib/routers/app.d.ts.map +1 -1
  57. package/src/lib/routers/app.js +1 -0
  58. package/src/lib/routers/app.js.map +1 -1
  59. package/src/lib/services/emailGateway/antiSpamFilter.d.ts +229 -0
  60. package/src/lib/services/emailGateway/antiSpamFilter.d.ts.map +1 -0
  61. package/src/lib/services/emailGateway/antiSpamFilter.js +325 -0
  62. package/src/lib/services/emailGateway/antiSpamFilter.js.map +1 -0
  63. package/src/lib/services/emailGateway/bounceProcessor.d.ts +182 -0
  64. package/src/lib/services/emailGateway/bounceProcessor.d.ts.map +1 -0
  65. package/src/lib/services/emailGateway/bounceProcessor.js +391 -0
  66. package/src/lib/services/emailGateway/bounceProcessor.js.map +1 -0
  67. package/src/lib/services/emailGateway/emailAuthVerifier.d.ts +99 -0
  68. package/src/lib/services/emailGateway/emailAuthVerifier.d.ts.map +1 -0
  69. package/src/lib/services/emailGateway/emailAuthVerifier.js +202 -0
  70. package/src/lib/services/emailGateway/emailAuthVerifier.js.map +1 -0
  71. package/src/lib/services/emailGateway/emailGatewayConfig.d.ts +74 -0
  72. package/src/lib/services/emailGateway/emailGatewayConfig.d.ts.map +1 -0
  73. package/src/lib/services/emailGateway/emailGatewayConfig.js +107 -0
  74. package/src/lib/services/emailGateway/emailGatewayConfig.js.map +1 -0
  75. package/src/lib/services/emailGateway/emailGatewayService.d.ts +209 -0
  76. package/src/lib/services/emailGateway/emailGatewayService.d.ts.map +1 -0
  77. package/src/lib/services/emailGateway/emailGatewayService.js +254 -0
  78. package/src/lib/services/emailGateway/emailGatewayService.js.map +1 -0
  79. package/src/lib/services/emailGateway/gatewayObservability.d.ts +123 -0
  80. package/src/lib/services/emailGateway/gatewayObservability.d.ts.map +1 -0
  81. package/src/lib/services/emailGateway/gatewayObservability.js +186 -0
  82. package/src/lib/services/emailGateway/gatewayObservability.js.map +1 -0
  83. package/src/lib/services/emailGateway/inboundProcessor.d.ts +113 -0
  84. package/src/lib/services/emailGateway/inboundProcessor.d.ts.map +1 -0
  85. package/src/lib/services/emailGateway/inboundProcessor.js +298 -0
  86. package/src/lib/services/emailGateway/inboundProcessor.js.map +1 -0
  87. package/src/lib/services/emailGateway/index.d.ts +23 -0
  88. package/src/lib/services/emailGateway/index.d.ts.map +1 -0
  89. package/src/lib/services/emailGateway/index.js +26 -0
  90. package/src/lib/services/emailGateway/index.js.map +1 -0
  91. package/src/lib/services/emailGateway/outboundDeliveryWorker.d.ts +122 -0
  92. package/src/lib/services/emailGateway/outboundDeliveryWorker.d.ts.map +1 -0
  93. package/src/lib/services/emailGateway/outboundDeliveryWorker.js +110 -0
  94. package/src/lib/services/emailGateway/outboundDeliveryWorker.js.map +1 -0
  95. package/src/lib/services/emailGateway/outboundQueue.d.ts +135 -0
  96. package/src/lib/services/emailGateway/outboundQueue.d.ts.map +1 -0
  97. package/src/lib/services/emailGateway/outboundQueue.js +227 -0
  98. package/src/lib/services/emailGateway/outboundQueue.js.map +1 -0
  99. package/src/lib/services/emailGateway/outboundQueueStore.d.ts +110 -0
  100. package/src/lib/services/emailGateway/outboundQueueStore.d.ts.map +1 -0
  101. package/src/lib/services/emailGateway/outboundQueueStore.js +131 -0
  102. package/src/lib/services/emailGateway/outboundQueueStore.js.map +1 -0
  103. package/src/lib/services/emailGateway/recipientLookupService.d.ts +146 -0
  104. package/src/lib/services/emailGateway/recipientLookupService.d.ts.map +1 -0
  105. package/src/lib/services/emailGateway/recipientLookupService.js +307 -0
  106. package/src/lib/services/emailGateway/recipientLookupService.js.map +1 -0
  107. package/src/lib/services/emailGateway/retryBackoff.d.ts +79 -0
  108. package/src/lib/services/emailGateway/retryBackoff.d.ts.map +1 -0
  109. package/src/lib/services/emailGateway/retryBackoff.js +77 -0
  110. package/src/lib/services/emailGateway/retryBackoff.js.map +1 -0
  111. package/src/lib/services/index.d.ts +1 -0
  112. package/src/lib/services/index.d.ts.map +1 -1
  113. package/src/lib/services/index.js +1 -0
  114. package/src/lib/services/index.js.map +1 -1
  115. package/src/lib/services/quorumDatabaseAdapter.d.ts +7 -1
  116. package/src/lib/services/quorumDatabaseAdapter.d.ts.map +1 -1
  117. package/src/lib/services/quorumDatabaseAdapter.js +83 -0
  118. package/src/lib/services/quorumDatabaseAdapter.js.map +1 -1
  119. package/src/lib/services/sessionAdapter.d.ts +2 -61
  120. package/src/lib/services/sessionAdapter.d.ts.map +1 -1
  121. package/src/lib/services/sessionAdapter.js +2 -102
  122. package/src/lib/services/sessionAdapter.js.map +1 -1
  123. package/src/lib/shared-types.d.ts +7 -15
  124. package/src/lib/shared-types.d.ts.map +1 -1
  125. package/src/lib/types/backend-id.d.ts +1 -2
  126. package/src/lib/types/backend-id.d.ts.map +1 -1
  127. package/src/lib/validation/userValidation.d.ts +2 -43
  128. package/src/lib/validation/userValidation.d.ts.map +1 -1
  129. package/src/lib/validation/userValidation.js +6 -144
  130. package/src/lib/validation/userValidation.js.map +1 -1
@@ -0,0 +1,307 @@
1
+ "use strict";
2
+ /**
3
+ * RecipientLookupService — TCP socketmap server for Postfix recipient validation.
4
+ *
5
+ * Implements the Postfix `socketmap` lookup protocol over TCP so that Postfix
6
+ * can validate whether a recipient address corresponds to a registered
7
+ * BrightChain user *before* accepting the message (preventing backscatter).
8
+ *
9
+ * Protocol (simplified):
10
+ * Client sends: `<name> <key>\n` (e.g. `virtual alice@brightchain.org\n`)
11
+ * Server responds: `OK <value>\n` | `NOTFOUND \n` | `TEMP <reason>\n`
12
+ *
13
+ * The service:
14
+ * - Listens on a configurable TCP port (default 2526) on localhost
15
+ * - Queries a user-registry dependency for the local part at the canonical domain
16
+ * - Caches positive results in an LRU cache with configurable TTL (default 300 s)
17
+ * - Responds within 5 seconds (timeout handling)
18
+ *
19
+ * @see Requirements 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 4.1, 4.2, 4.3
20
+ * @module recipientLookupService
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.RecipientLookupService = exports.RecipientLookupCache = void 0;
24
+ const tslib_1 = require("tslib");
25
+ const net = tslib_1.__importStar(require("net"));
26
+ /**
27
+ * Simple LRU cache for positive recipient lookup results.
28
+ *
29
+ * Only positive (`OK`) results are cached — negative and temporary results
30
+ * are always re-queried so that newly registered users are found promptly.
31
+ *
32
+ * @see Requirement 13.6
33
+ */
34
+ class RecipientLookupCache {
35
+ maxSize;
36
+ ttlMs;
37
+ cache = new Map();
38
+ constructor(maxSize, ttlMs) {
39
+ this.maxSize = maxSize;
40
+ this.ttlMs = ttlMs;
41
+ }
42
+ /**
43
+ * Retrieve a cached positive result for `key`.
44
+ *
45
+ * @returns `true` if the key is cached and not expired, `false` otherwise.
46
+ */
47
+ get(key) {
48
+ const entry = this.cache.get(key);
49
+ if (!entry) {
50
+ return false;
51
+ }
52
+ if (Date.now() >= entry.expiresAt) {
53
+ this.cache.delete(key);
54
+ return false;
55
+ }
56
+ // Move to end (most-recently used) by re-inserting.
57
+ this.cache.delete(key);
58
+ this.cache.set(key, entry);
59
+ return true;
60
+ }
61
+ /**
62
+ * Store a positive lookup result for `key`.
63
+ */
64
+ set(key) {
65
+ // If already present, delete first so insertion order is refreshed.
66
+ if (this.cache.has(key)) {
67
+ this.cache.delete(key);
68
+ }
69
+ // Evict the least-recently used entry if at capacity.
70
+ if (this.cache.size >= this.maxSize) {
71
+ const oldest = this.cache.keys().next().value;
72
+ if (oldest !== undefined) {
73
+ this.cache.delete(oldest);
74
+ }
75
+ }
76
+ this.cache.set(key, { expiresAt: Date.now() + this.ttlMs });
77
+ }
78
+ /** Number of entries currently in the cache. */
79
+ get size() {
80
+ return this.cache.size;
81
+ }
82
+ /** Remove all entries. */
83
+ clear() {
84
+ this.cache.clear();
85
+ }
86
+ }
87
+ exports.RecipientLookupCache = RecipientLookupCache;
88
+ // ─── Constants ──────────────────────────────────────────────────────────────
89
+ /** Maximum time (ms) to wait for a registry lookup before returning TEMP. */
90
+ const LOOKUP_TIMEOUT_MS = 5_000;
91
+ /** Default maximum number of entries in the LRU cache. */
92
+ const DEFAULT_CACHE_MAX_SIZE = 10_000;
93
+ // ─── RecipientLookupService ─────────────────────────────────────────────────
94
+ /**
95
+ * TCP socketmap server that Postfix queries to validate recipient addresses
96
+ * against the BrightChain user registry.
97
+ *
98
+ * Implements `IRecipientLookupService` from brightchain-lib for the `lookup`
99
+ * contract, and adds TCP server lifecycle (`start` / `stop`).
100
+ *
101
+ * @see Requirements 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7
102
+ */
103
+ class RecipientLookupService {
104
+ config;
105
+ userRegistry;
106
+ server = null;
107
+ cache;
108
+ port;
109
+ canonicalDomain;
110
+ constructor(config, userRegistry) {
111
+ this.config = config;
112
+ this.userRegistry = userRegistry;
113
+ this.port = config.recipientLookupPort;
114
+ this.canonicalDomain = config.canonicalDomain.toLowerCase();
115
+ this.cache = new RecipientLookupCache(DEFAULT_CACHE_MAX_SIZE, config.recipientLookupCacheTtlSeconds * 1_000);
116
+ }
117
+ /**
118
+ * Update the canonical domain used for recipient validation.
119
+ *
120
+ * Clears the lookup cache since cached entries may belong to the old domain.
121
+ *
122
+ * @param newDomain - The new canonical domain
123
+ *
124
+ * @see Requirement 8.5 — hot-reload canonical domain without restart
125
+ */
126
+ updateCanonicalDomain(newDomain) {
127
+ this.canonicalDomain = newDomain.toLowerCase();
128
+ this.cache.clear();
129
+ }
130
+ // ─── IRecipientLookupService ────────────────────────────────────────
131
+ /**
132
+ * Look up whether `emailAddress` corresponds to a registered BrightChain
133
+ * user at the canonical domain.
134
+ *
135
+ * 1. Check the LRU cache for a positive hit.
136
+ * 2. Query the user registry (with a 5-second timeout).
137
+ * 3. Cache positive results.
138
+ *
139
+ * @returns `'OK'` | `'NOTFOUND'` | `'TEMP'`
140
+ *
141
+ * @see Requirements 13.2, 13.3, 13.4, 13.5, 13.6
142
+ */
143
+ async lookup(emailAddress) {
144
+ const normalised = emailAddress.toLowerCase().trim();
145
+ // Validate that the address belongs to the canonical domain.
146
+ const atIndex = normalised.lastIndexOf('@');
147
+ if (atIndex === -1) {
148
+ return 'NOTFOUND';
149
+ }
150
+ const domain = normalised.slice(atIndex + 1);
151
+ if (domain !== this.canonicalDomain) {
152
+ return 'NOTFOUND';
153
+ }
154
+ // 1. Cache hit → return OK immediately (Req 13.6).
155
+ if (this.cache.get(normalised)) {
156
+ return 'OK';
157
+ }
158
+ // 2. Query registry with timeout (Req 4.3 — respond within 5 s).
159
+ try {
160
+ const found = await this.withTimeout(this.userRegistry.hasUser(normalised), LOOKUP_TIMEOUT_MS);
161
+ if (found) {
162
+ this.cache.set(normalised);
163
+ return 'OK';
164
+ }
165
+ return 'NOTFOUND';
166
+ }
167
+ catch {
168
+ // Registry unreachable or timeout → TEMP (Req 13.5).
169
+ return 'TEMP';
170
+ }
171
+ }
172
+ // ─── TCP Server Lifecycle ───────────────────────────────────────────
173
+ /**
174
+ * Start the TCP socketmap server on the configured port (localhost only).
175
+ *
176
+ * @see Requirement 13.1
177
+ */
178
+ start() {
179
+ return new Promise((resolve, reject) => {
180
+ if (this.server) {
181
+ resolve();
182
+ return;
183
+ }
184
+ this.server = net.createServer((socket) => this.handleConnection(socket));
185
+ this.server.on('error', (err) => {
186
+ reject(err);
187
+ });
188
+ this.server.listen(this.port, '127.0.0.1', () => {
189
+ resolve();
190
+ });
191
+ });
192
+ }
193
+ /**
194
+ * Stop the TCP server and clear the cache.
195
+ */
196
+ stop() {
197
+ return new Promise((resolve) => {
198
+ this.cache.clear();
199
+ if (!this.server) {
200
+ resolve();
201
+ return;
202
+ }
203
+ this.server.close(() => {
204
+ this.server = null;
205
+ resolve();
206
+ });
207
+ });
208
+ }
209
+ /** Whether the TCP server is currently listening. */
210
+ isRunning() {
211
+ return this.server !== null && this.server.listening;
212
+ }
213
+ /** Expose cache for testing purposes. */
214
+ getCache() {
215
+ return this.cache;
216
+ }
217
+ // ─── Connection Handler ─────────────────────────────────────────────
218
+ /**
219
+ * Handle a single TCP connection from Postfix.
220
+ *
221
+ * Postfix socketmap protocol:
222
+ * Request: `<mapname> <key>\n`
223
+ * Response: `OK <value>\n` | `NOTFOUND \n` | `TEMP <reason>\n`
224
+ *
225
+ * The connection may carry multiple newline-delimited requests.
226
+ */
227
+ handleConnection(socket) {
228
+ let buffer = '';
229
+ socket.setEncoding('utf-8');
230
+ socket.on('data', (data) => {
231
+ buffer += data;
232
+ // Process all complete lines in the buffer.
233
+ let newlineIdx;
234
+ while ((newlineIdx = buffer.indexOf('\n')) !== -1) {
235
+ const line = buffer.slice(0, newlineIdx).trim();
236
+ buffer = buffer.slice(newlineIdx + 1);
237
+ if (line.length === 0) {
238
+ continue;
239
+ }
240
+ this.handleRequest(line)
241
+ .then((response) => {
242
+ if (!socket.destroyed) {
243
+ socket.write(response + '\n');
244
+ }
245
+ })
246
+ .catch(() => {
247
+ if (!socket.destroyed) {
248
+ socket.write('TEMP internal error\n');
249
+ }
250
+ });
251
+ }
252
+ });
253
+ socket.on('error', () => {
254
+ // Silently handle socket errors (e.g. client disconnect).
255
+ });
256
+ }
257
+ /**
258
+ * Parse a socketmap request line and return the response string.
259
+ *
260
+ * @param line - A single request line, e.g. `virtual alice@brightchain.org`
261
+ * @returns The response string, e.g. `OK alice@brightchain.org`
262
+ */
263
+ async handleRequest(line) {
264
+ // Format: `<mapname> <key>`
265
+ const spaceIdx = line.indexOf(' ');
266
+ if (spaceIdx === -1) {
267
+ return 'TEMP malformed request';
268
+ }
269
+ const key = line.slice(spaceIdx + 1).trim();
270
+ if (key.length === 0) {
271
+ return 'TEMP malformed request';
272
+ }
273
+ const result = await this.lookup(key);
274
+ switch (result) {
275
+ case 'OK':
276
+ return `OK ${key}`;
277
+ case 'NOTFOUND':
278
+ return 'NOTFOUND ';
279
+ case 'TEMP':
280
+ return 'TEMP registry unavailable';
281
+ }
282
+ }
283
+ // ─── Helpers ────────────────────────────────────────────────────────
284
+ /**
285
+ * Race a promise against a timeout.
286
+ *
287
+ * @throws If the timeout fires first.
288
+ */
289
+ withTimeout(promise, ms) {
290
+ return new Promise((resolve, reject) => {
291
+ const timer = setTimeout(() => {
292
+ reject(new Error(`Lookup timed out after ${ms}ms`));
293
+ }, ms);
294
+ promise
295
+ .then((value) => {
296
+ clearTimeout(timer);
297
+ resolve(value);
298
+ })
299
+ .catch((err) => {
300
+ clearTimeout(timer);
301
+ reject(err);
302
+ });
303
+ });
304
+ }
305
+ }
306
+ exports.RecipientLookupService = RecipientLookupService;
307
+ //# sourceMappingURL=recipientLookupService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipientLookupService.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/recipientLookupService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Retry Back-Off Utilities — exponential back-off with jitter for outbound
3
+ * email delivery retries.
4
+ *
5
+ * Provides pure utility functions that the OutboundDeliveryWorker and
6
+ * OutboundQueue use to compute retry delays and determine whether a
7
+ * message should be retried or permanently failed.
8
+ *
9
+ * Back-off formula: baseInterval × 2^retryCount + random jitter (0–25%)
10
+ *
11
+ * @see Requirements 3.1, 3.2, 3.3, 3.4, 3.5
12
+ * @module retryBackoff
13
+ */
14
+ /**
15
+ * Configuration for retry back-off behaviour.
16
+ *
17
+ * Extracted from `IEmailGatewayConfig` so the utility functions remain
18
+ * decoupled from the full gateway config.
19
+ */
20
+ export interface IRetryConfig {
21
+ /** Maximum number of delivery retry attempts (default: 5). Req 3.3 */
22
+ retryMaxCount: number;
23
+ /** Maximum total retry duration in milliseconds (default: 48h). Req 3.3 */
24
+ retryMaxDurationMs: number;
25
+ /** Base interval in milliseconds for exponential back-off (default: 60000). Req 3.2 */
26
+ retryBaseIntervalMs: number;
27
+ }
28
+ /**
29
+ * Minimal item shape needed by `shouldRetry`.
30
+ */
31
+ export interface IRetryableItem {
32
+ /** Number of delivery attempts made so far. */
33
+ retryCount: number;
34
+ /** Timestamp when the item was first enqueued. */
35
+ enqueuedAt: Date;
36
+ }
37
+ /**
38
+ * Compute the exponential back-off delay for a retry attempt.
39
+ *
40
+ * Formula: `baseIntervalMs × 2^retryCount + jitter`
41
+ * where jitter is a random value between 0% and 25% of the base delay.
42
+ *
43
+ * @param baseIntervalMs - Base interval in milliseconds (e.g. 60000)
44
+ * @param retryCount - Current retry attempt number (0-based: first retry = 0)
45
+ * @param randomFn - Optional random function for deterministic testing (default: Math.random)
46
+ * @returns Delay in milliseconds before the next retry attempt
47
+ *
48
+ * @see Requirement 3.2
49
+ */
50
+ export declare function computeBackoffDelay(baseIntervalMs: number, retryCount: number, randomFn?: () => number): number;
51
+ /**
52
+ * Determine whether a queue item should be retried or permanently failed.
53
+ *
54
+ * An item should be retried when BOTH conditions are met:
55
+ * 1. `retryCount < config.retryMaxCount`
56
+ * 2. Time since `enqueuedAt` has not exceeded `config.retryMaxDurationMs`
57
+ *
58
+ * @param item - The queue item to evaluate
59
+ * @param config - Retry configuration limits
60
+ * @param nowMs - Current time in epoch milliseconds (default: Date.now())
61
+ * @returns `true` if the item is eligible for another retry attempt
62
+ *
63
+ * @see Requirements 3.3, 3.4
64
+ */
65
+ export declare function shouldRetry(item: IRetryableItem, config: IRetryConfig, nowMs?: number): boolean;
66
+ /**
67
+ * Compute the `nextAttemptAt` timestamp for a requeued item.
68
+ *
69
+ * Convenience wrapper that combines `computeBackoffDelay` with the
70
+ * current time to produce an absolute `Date`.
71
+ *
72
+ * @param baseIntervalMs - Base interval in milliseconds
73
+ * @param retryCount - Current retry count (before increment)
74
+ * @param nowMs - Current time in epoch milliseconds (default: Date.now())
75
+ * @param randomFn - Optional random function for deterministic testing
76
+ * @returns The `Date` at which the next attempt should be made
77
+ */
78
+ export declare function computeNextAttemptAt(baseIntervalMs: number, retryCount: number, nowMs?: number, randomFn?: () => number): Date;
79
+ //# sourceMappingURL=retryBackoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryBackoff.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/retryBackoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IAEtB,2EAA2E;IAC3E,kBAAkB,EAAE,MAAM,CAAC;IAE3B,uFAAuF;IACvF,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IAEnB,kDAAkD;IAClD,UAAU,EAAE,IAAI,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAM,MAAoB,GACnC,MAAM,CAIR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,YAAY,EACpB,KAAK,GAAE,MAAmB,GACzB,OAAO,CAST;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,MAAmB,EAC1B,QAAQ,CAAC,EAAE,MAAM,MAAM,GACtB,IAAI,CAGN"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * Retry Back-Off Utilities — exponential back-off with jitter for outbound
4
+ * email delivery retries.
5
+ *
6
+ * Provides pure utility functions that the OutboundDeliveryWorker and
7
+ * OutboundQueue use to compute retry delays and determine whether a
8
+ * message should be retried or permanently failed.
9
+ *
10
+ * Back-off formula: baseInterval × 2^retryCount + random jitter (0–25%)
11
+ *
12
+ * @see Requirements 3.1, 3.2, 3.3, 3.4, 3.5
13
+ * @module retryBackoff
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.computeBackoffDelay = computeBackoffDelay;
17
+ exports.shouldRetry = shouldRetry;
18
+ exports.computeNextAttemptAt = computeNextAttemptAt;
19
+ /**
20
+ * Compute the exponential back-off delay for a retry attempt.
21
+ *
22
+ * Formula: `baseIntervalMs × 2^retryCount + jitter`
23
+ * where jitter is a random value between 0% and 25% of the base delay.
24
+ *
25
+ * @param baseIntervalMs - Base interval in milliseconds (e.g. 60000)
26
+ * @param retryCount - Current retry attempt number (0-based: first retry = 0)
27
+ * @param randomFn - Optional random function for deterministic testing (default: Math.random)
28
+ * @returns Delay in milliseconds before the next retry attempt
29
+ *
30
+ * @see Requirement 3.2
31
+ */
32
+ function computeBackoffDelay(baseIntervalMs, retryCount, randomFn = Math.random) {
33
+ const baseDelay = baseIntervalMs * Math.pow(2, retryCount);
34
+ const jitter = baseDelay * 0.25 * randomFn();
35
+ return baseDelay + jitter;
36
+ }
37
+ /**
38
+ * Determine whether a queue item should be retried or permanently failed.
39
+ *
40
+ * An item should be retried when BOTH conditions are met:
41
+ * 1. `retryCount < config.retryMaxCount`
42
+ * 2. Time since `enqueuedAt` has not exceeded `config.retryMaxDurationMs`
43
+ *
44
+ * @param item - The queue item to evaluate
45
+ * @param config - Retry configuration limits
46
+ * @param nowMs - Current time in epoch milliseconds (default: Date.now())
47
+ * @returns `true` if the item is eligible for another retry attempt
48
+ *
49
+ * @see Requirements 3.3, 3.4
50
+ */
51
+ function shouldRetry(item, config, nowMs = Date.now()) {
52
+ if (item.retryCount >= config.retryMaxCount) {
53
+ return false;
54
+ }
55
+ const age = nowMs - item.enqueuedAt.getTime();
56
+ if (age > config.retryMaxDurationMs) {
57
+ return false;
58
+ }
59
+ return true;
60
+ }
61
+ /**
62
+ * Compute the `nextAttemptAt` timestamp for a requeued item.
63
+ *
64
+ * Convenience wrapper that combines `computeBackoffDelay` with the
65
+ * current time to produce an absolute `Date`.
66
+ *
67
+ * @param baseIntervalMs - Base interval in milliseconds
68
+ * @param retryCount - Current retry count (before increment)
69
+ * @param nowMs - Current time in epoch milliseconds (default: Date.now())
70
+ * @param randomFn - Optional random function for deterministic testing
71
+ * @returns The `Date` at which the next attempt should be made
72
+ */
73
+ function computeNextAttemptAt(baseIntervalMs, retryCount, nowMs = Date.now(), randomFn) {
74
+ const delay = computeBackoffDelay(baseIntervalMs, retryCount, randomFn);
75
+ return new Date(nowMs + delay);
76
+ }
77
+ //# sourceMappingURL=retryBackoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryBackoff.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/retryBackoff.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;AA2CH,kDAQC;AAgBD,kCAaC;AAcD,oDAQC;AAxED;;;;;;;;;;;;GAYG;AACH,SAAgB,mBAAmB,CACjC,cAAsB,EACtB,UAAkB,EAClB,WAAyB,IAAI,CAAC,MAAM;IAEpC,MAAM,SAAS,GAAG,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,QAAQ,EAAE,CAAC;IAC7C,OAAO,SAAS,GAAG,MAAM,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,WAAW,CACzB,IAAoB,EACpB,MAAoB,EACpB,QAAgB,IAAI,CAAC,GAAG,EAAE;IAE1B,IAAI,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAC9C,IAAI,GAAG,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,oBAAoB,CAClC,cAAsB,EACtB,UAAkB,EAClB,QAAgB,IAAI,CAAC,GAAG,EAAE,EAC1B,QAAuB;IAEvB,MAAM,KAAK,GAAG,mBAAmB,CAAC,cAAc,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IACxE,OAAO,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;AACjC,CAAC"}
@@ -12,6 +12,7 @@ export * from './contentAwareBlocksService';
12
12
  export * from './contentIngestionService';
13
13
  export * from './diskQuorumService';
14
14
  export * from './email';
15
+ export * from './emailGateway';
15
16
  export * from './eventNotificationSystem';
16
17
  export * from './fakeEmailService';
17
18
  export { WasmFecService } from './fec';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC"}
@@ -16,6 +16,7 @@ tslib_1.__exportStar(require("./contentAwareBlocksService"), exports);
16
16
  tslib_1.__exportStar(require("./contentIngestionService"), exports);
17
17
  tslib_1.__exportStar(require("./diskQuorumService"), exports);
18
18
  tslib_1.__exportStar(require("./email"), exports);
19
+ tslib_1.__exportStar(require("./emailGateway"), exports);
19
20
  tslib_1.__exportStar(require("./eventNotificationSystem"), exports);
20
21
  tslib_1.__exportStar(require("./fakeEmailService"), exports);
21
22
  var fec_1 = require("./fec");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/index.ts"],"names":[],"mappings":";;;;AAAA,iDAAuB;AACvB,iDAAuB;AACvB,mDAAyB;AACzB,gEAAsC;AACtC,uDAA6B;AAC7B,4EAAkD;AAClD,yEAA+C;AAC/C,sDAA4B;AAC5B,kEAAwC;AACxC,8DAAoC;AACpC,sEAA4C;AAC5C,oEAA0C;AAC1C,8DAAoC;AACpC,kDAAwB;AACxB,oEAA0C;AAC1C,6DAAmC;AACnC,6BAAuC;AAA9B,qGAAA,cAAc,OAAA;AACvB,8DAAoC;AACpC,4DAAkC;AAClC,wEAA8C;AAC9C,0EAAgD;AAChD,kEAAwC;AACxC,+DAAqC;AACrC,4DAAkC;AAClC,mDAAyB;AACzB,kEAAwC;AACxC,+DAAqC;AACrC,wDAA8B;AAC9B,iDAAuB;AACvB,6DAAmC;AACnC,2DAAiC;AACjC,6DAAmC;AACnC,mEAAyC;AACzC,kEAAwC;AACxC,sEAA4C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/index.ts"],"names":[],"mappings":";;;;AAAA,iDAAuB;AACvB,iDAAuB;AACvB,mDAAyB;AACzB,gEAAsC;AACtC,uDAA6B;AAC7B,4EAAkD;AAClD,yEAA+C;AAC/C,sDAA4B;AAC5B,kEAAwC;AACxC,8DAAoC;AACpC,sEAA4C;AAC5C,oEAA0C;AAC1C,8DAAoC;AACpC,kDAAwB;AACxB,yDAA+B;AAC/B,oEAA0C;AAC1C,6DAAmC;AACnC,6BAAuC;AAA9B,qGAAA,cAAc,OAAA;AACvB,8DAAoC;AACpC,4DAAkC;AAClC,wEAA8C;AAC9C,0EAAgD;AAChD,kEAAwC;AACxC,+DAAqC;AACrC,4DAAkC;AAClC,mDAAyB;AACzB,kEAAwC;AACxC,+DAAqC;AACrC,wDAA8B;AAC9B,iDAAuB;AACvB,6DAAmC;AACnC,2DAAiC;AACjC,6DAAmC;AACnC,mEAAyC;AACzC,kEAAwC;AACxC,sEAA4C"}
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * @see Requirements 9, 10
11
11
  */
12
- import { AliasRecord, ChainedAuditLogEntry, IdentityRecoveryRecord, IQuorumDatabase, IQuorumMember, OperationalState, Proposal, QuorumAuditLogEntry, QuorumDataRecord, QuorumEpoch, RedistributionJournalEntry, StatuteOfLimitationsConfig, Vote } from '@brightchain/brightchain-lib';
12
+ import { AliasRecord, ChainedAuditLogEntry, IdentityRecoveryRecord, IQuorumDatabase, IQuorumMember, OperationalState, Proposal, QuorumAuditLogEntry, QuorumDataRecord, QuorumEpoch, RedistributionJournalEntry, StatuteOfLimitationsConfig, Vote, IBanRecord } from '@brightchain/brightchain-lib';
13
13
  import type { BrightDb } from '@brightchain/db';
14
14
  import { IIdProvider, PlatformID } from '@digitaldefiance/ecies-lib';
15
15
  /** Dedicated pool ID for quorum data isolation */
@@ -57,5 +57,11 @@ export declare class QuorumDatabaseAdapter<TID extends PlatformID = Uint8Array>
57
57
  getOperationalState(): Promise<OperationalState | null>;
58
58
  withTransaction<R>(fn: () => Promise<R>): Promise<R>;
59
59
  isAvailable(): Promise<boolean>;
60
+ saveBanRecord(record: IBanRecord<TID>): Promise<void>;
61
+ deleteBanRecord(memberId: TID): Promise<void>;
62
+ getBanRecord(memberId: TID): Promise<IBanRecord<TID> | null>;
63
+ getAllBanRecords(): Promise<IBanRecord<TID>[]>;
64
+ getMemberAdmissionProposerId(memberId: TID): Promise<TID | null>;
65
+ private deserializeBanRecord;
60
66
  }
61
67
  //# sourceMappingURL=quorumDatabaseAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"quorumDatabaseAdapter.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/quorumDatabaseAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"quorumDatabaseAdapter.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/quorumDatabaseAdapter.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,7 @@ const COLLECTION_AUDIT_LOG = 'audit_log';
24
24
  const COLLECTION_REDISTRIBUTION_JOURNAL = 'redistribution_journal';
25
25
  const COLLECTION_STATUTE_CONFIG = 'statute_config';
26
26
  const COLLECTION_OPERATIONAL_STATE = 'operational_state';
27
+ const COLLECTION_BAN_RECORDS = 'ban_records';
27
28
  /** Dedicated pool ID for quorum data isolation */
28
29
  exports.QUORUM_SYSTEM_POOL_ID = 'quorum-system';
29
30
  // ─── Serialization Helpers ──────────────────────────────────────────────────
@@ -735,6 +736,88 @@ class QuorumDatabaseAdapter {
735
736
  return false;
736
737
  }
737
738
  }
739
+ // === Ban Records ===
740
+ async saveBanRecord(record) {
741
+ const col = this.db.collection(COLLECTION_BAN_RECORDS);
742
+ const memberId = this.idProvider.idToString(record.memberId);
743
+ const data = {
744
+ memberId: memberId,
745
+ reason: record.reason,
746
+ proposalId: this.idProvider.idToString(record.proposalId),
747
+ epoch: record.epoch,
748
+ bannedAt: record.bannedAt.toISOString(),
749
+ evidenceBlockIds: record.evidenceBlockIds,
750
+ approvalSignatures: record.approvalSignatures.map((sig) => ({
751
+ memberId: this.idProvider.idToString(sig.memberId),
752
+ signature: serializeUint8Array(sig.signature),
753
+ })),
754
+ requiredSignatures: record.requiredSignatures,
755
+ };
756
+ const existing = await col.findOne({ memberId });
757
+ if (existing) {
758
+ await col.updateOne({ memberId }, { $set: { data } });
759
+ }
760
+ else {
761
+ await col.insertOne({ memberId, data });
762
+ }
763
+ }
764
+ async deleteBanRecord(memberId) {
765
+ const col = this.db.collection(COLLECTION_BAN_RECORDS);
766
+ const id = this.idProvider.idToString(memberId);
767
+ await col.deleteOne({ memberId: id });
768
+ }
769
+ async getBanRecord(memberId) {
770
+ const col = this.db.collection(COLLECTION_BAN_RECORDS);
771
+ const id = this.idProvider.idToString(memberId);
772
+ const doc = await col.findOne({ memberId: id });
773
+ if (!doc)
774
+ return null;
775
+ return this.deserializeBanRecord(doc.data);
776
+ }
777
+ async getAllBanRecords() {
778
+ const col = this.db.collection(COLLECTION_BAN_RECORDS);
779
+ const docs = await col.find({}).toArray();
780
+ return docs.map((doc) => this.deserializeBanRecord(doc.data));
781
+ }
782
+ async getMemberAdmissionProposerId(memberId) {
783
+ // Look up the ADD_MEMBER proposal that admitted this member.
784
+ // If no such proposal exists, the member is a founder.
785
+ const col = this.db.collection(COLLECTION_PROPOSALS);
786
+ const memberIdStr = this.idProvider.idToString(memberId);
787
+ const docs = await col
788
+ .find({})
789
+ .toArray();
790
+ for (const doc of docs) {
791
+ const data = doc.data;
792
+ if (data['actionType'] === 'ADD_MEMBER' &&
793
+ data['status'] === 'APPROVED') {
794
+ const payload = data['actionPayload'];
795
+ if (payload && payload['targetMemberId'] === memberIdStr) {
796
+ const proposerId = data['proposerMemberId'];
797
+ if (proposerId) {
798
+ return this.idProvider.idFromString(proposerId);
799
+ }
800
+ }
801
+ }
802
+ }
803
+ return null;
804
+ }
805
+ deserializeBanRecord(data) {
806
+ const sigs = data['approvalSignatures'] ?? [];
807
+ return {
808
+ memberId: this.idProvider.idFromString(data['memberId']),
809
+ reason: data['reason'],
810
+ proposalId: this.idProvider.idFromString(data['proposalId']),
811
+ epoch: data['epoch'],
812
+ bannedAt: new Date(data['bannedAt']),
813
+ evidenceBlockIds: data['evidenceBlockIds'],
814
+ approvalSignatures: sigs.map((sig) => ({
815
+ memberId: this.idProvider.idFromString(sig.memberId),
816
+ signature: deserializeUint8Array(sig.signature),
817
+ })),
818
+ requiredSignatures: data['requiredSignatures'],
819
+ };
820
+ }
738
821
  }
739
822
  exports.QuorumDatabaseAdapter = QuorumDatabaseAdapter;
740
823
  //# sourceMappingURL=quorumDatabaseAdapter.js.map