@brightchain/brightchain-api-lib 0.24.1 → 0.26.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 (244) hide show
  1. package/package.json +4 -3
  2. package/src/lib/application.d.ts +3 -14
  3. package/src/lib/application.d.ts.map +1 -1
  4. package/src/lib/application.js +121 -44
  5. package/src/lib/application.js.map +1 -1
  6. package/src/lib/auth/aclDocumentStore.d.ts +90 -0
  7. package/src/lib/auth/aclDocumentStore.d.ts.map +1 -0
  8. package/src/lib/auth/aclDocumentStore.js +155 -0
  9. package/src/lib/auth/aclDocumentStore.js.map +1 -0
  10. package/src/lib/auth/index.d.ts +4 -0
  11. package/src/lib/auth/index.d.ts.map +1 -1
  12. package/src/lib/auth/index.js +4 -0
  13. package/src/lib/auth/index.js.map +1 -1
  14. package/src/lib/auth/writeAclApiRouter.d.ts +32 -0
  15. package/src/lib/auth/writeAclApiRouter.d.ts.map +1 -0
  16. package/src/lib/auth/writeAclApiRouter.js +348 -0
  17. package/src/lib/auth/writeAclApiRouter.js.map +1 -0
  18. package/src/lib/auth/writeAclAuditLogger.d.ts +94 -0
  19. package/src/lib/auth/writeAclAuditLogger.d.ts.map +1 -0
  20. package/src/lib/auth/writeAclAuditLogger.js +143 -0
  21. package/src/lib/auth/writeAclAuditLogger.js.map +1 -0
  22. package/src/lib/auth/writeProofMiddleware.d.ts +39 -0
  23. package/src/lib/auth/writeProofMiddleware.d.ts.map +1 -0
  24. package/src/lib/auth/writeProofMiddleware.js +56 -0
  25. package/src/lib/auth/writeProofMiddleware.js.map +1 -0
  26. package/src/lib/availability/aclDocumentSyncHandler.d.ts +39 -0
  27. package/src/lib/availability/aclDocumentSyncHandler.d.ts.map +1 -0
  28. package/src/lib/availability/aclDocumentSyncHandler.js +81 -0
  29. package/src/lib/availability/aclDocumentSyncHandler.js.map +1 -0
  30. package/src/lib/availability/gossipService.d.ts +4 -1
  31. package/src/lib/availability/gossipService.d.ts.map +1 -1
  32. package/src/lib/availability/gossipService.js +15 -1
  33. package/src/lib/availability/gossipService.js.map +1 -1
  34. package/src/lib/availability/headUpdateSyncHandler.d.ts +32 -0
  35. package/src/lib/availability/headUpdateSyncHandler.d.ts.map +1 -0
  36. package/src/lib/availability/headUpdateSyncHandler.js +78 -0
  37. package/src/lib/availability/headUpdateSyncHandler.js.map +1 -0
  38. package/src/lib/availability/index.d.ts +2 -0
  39. package/src/lib/availability/index.d.ts.map +1 -1
  40. package/src/lib/availability/index.js +2 -0
  41. package/src/lib/availability/index.js.map +1 -1
  42. package/src/lib/constants.d.ts.map +1 -1
  43. package/src/lib/constants.js +2 -0
  44. package/src/lib/constants.js.map +1 -1
  45. package/src/lib/controllers/api/brighthub/connectionController.d.ts +6 -0
  46. package/src/lib/controllers/api/brighthub/connectionController.d.ts.map +1 -1
  47. package/src/lib/controllers/api/brighthub/connectionController.js +158 -11
  48. package/src/lib/controllers/api/brighthub/connectionController.js.map +1 -1
  49. package/src/lib/controllers/api/brighthub/messagingController.d.ts +6 -0
  50. package/src/lib/controllers/api/brighthub/messagingController.d.ts.map +1 -1
  51. package/src/lib/controllers/api/brighthub/messagingController.js +190 -58
  52. package/src/lib/controllers/api/brighthub/messagingController.js.map +1 -1
  53. package/src/lib/controllers/api/brighthub/postController.d.ts +12 -3
  54. package/src/lib/controllers/api/brighthub/postController.d.ts.map +1 -1
  55. package/src/lib/controllers/api/brighthub/postController.js +60 -0
  56. package/src/lib/controllers/api/brighthub/postController.js.map +1 -1
  57. package/src/lib/controllers/api/brighthub/timelineController.d.ts +19 -0
  58. package/src/lib/controllers/api/brighthub/timelineController.d.ts.map +1 -1
  59. package/src/lib/controllers/api/brighthub/timelineController.js +133 -0
  60. package/src/lib/controllers/api/brighthub/timelineController.js.map +1 -1
  61. package/src/lib/controllers/api/emails.d.ts +4 -1
  62. package/src/lib/controllers/api/emails.d.ts.map +1 -1
  63. package/src/lib/controllers/api/emails.js +28 -1
  64. package/src/lib/controllers/api/emails.js.map +1 -1
  65. package/src/lib/controllers/api/user.d.ts.map +1 -1
  66. package/src/lib/controllers/api/user.js +10 -0
  67. package/src/lib/controllers/api/user.js.map +1 -1
  68. package/src/lib/databaseInit.d.ts +7 -11
  69. package/src/lib/databaseInit.d.ts.map +1 -1
  70. package/src/lib/databaseInit.js +41 -97
  71. package/src/lib/databaseInit.js.map +1 -1
  72. package/src/lib/datastore/block-document-store-factory.d.ts +3 -0
  73. package/src/lib/datastore/block-document-store-factory.d.ts.map +1 -1
  74. package/src/lib/datastore/block-document-store-factory.js +15 -18
  75. package/src/lib/datastore/block-document-store-factory.js.map +1 -1
  76. package/src/lib/datastore/block-document-store.d.ts +2 -191
  77. package/src/lib/datastore/block-document-store.d.ts.map +1 -1
  78. package/src/lib/datastore/block-document-store.js +4 -628
  79. package/src/lib/datastore/block-document-store.js.map +1 -1
  80. package/src/lib/datastore/document-store.d.ts +1 -62
  81. package/src/lib/datastore/document-store.d.ts.map +1 -1
  82. package/src/lib/datastore/memory-document-store.d.ts +1 -8
  83. package/src/lib/datastore/memory-document-store.d.ts.map +1 -1
  84. package/src/lib/datastore/memory-document-store.js +3 -214
  85. package/src/lib/datastore/memory-document-store.js.map +1 -1
  86. package/src/lib/environment.d.ts +3 -20
  87. package/src/lib/environment.d.ts.map +1 -1
  88. package/src/lib/environment.js +2 -45
  89. package/src/lib/environment.js.map +1 -1
  90. package/src/lib/factories/blockStoreFactory.d.ts.map +1 -1
  91. package/src/lib/factories/blockStoreFactory.js +4 -1
  92. package/src/lib/factories/blockStoreFactory.js.map +1 -1
  93. package/src/lib/interfaces/environment.d.ts +23 -2
  94. package/src/lib/interfaces/environment.d.ts.map +1 -1
  95. package/src/lib/interfaces/responses/brighthub/api-post-response.d.ts +8 -1
  96. package/src/lib/interfaces/responses/brighthub/api-post-response.d.ts.map +1 -1
  97. package/src/lib/middleware/index.d.ts +1 -1
  98. package/src/lib/middleware/index.d.ts.map +1 -1
  99. package/src/lib/middleware/index.js +3 -2
  100. package/src/lib/middleware/index.js.map +1 -1
  101. package/src/lib/middleware/validateBody.d.ts +1 -12
  102. package/src/lib/middleware/validateBody.d.ts.map +1 -1
  103. package/src/lib/middleware/validateBody.js +4 -32
  104. package/src/lib/middleware/validateBody.js.map +1 -1
  105. package/src/lib/middlewares.d.ts.map +1 -1
  106. package/src/lib/middlewares.js +7 -1
  107. package/src/lib/middlewares.js.map +1 -1
  108. package/src/lib/plugins/brightchain-database-plugin.d.ts +27 -79
  109. package/src/lib/plugins/brightchain-database-plugin.d.ts.map +1 -1
  110. package/src/lib/plugins/brightchain-database-plugin.js +27 -97
  111. package/src/lib/plugins/brightchain-database-plugin.js.map +1 -1
  112. package/src/lib/routers/api.d.ts +18 -1
  113. package/src/lib/routers/api.d.ts.map +1 -1
  114. package/src/lib/routers/api.js +24 -1
  115. package/src/lib/routers/api.js.map +1 -1
  116. package/src/lib/routers/app.d.ts.map +1 -1
  117. package/src/lib/routers/app.js +5 -2
  118. package/src/lib/routers/app.js.map +1 -1
  119. package/src/lib/services/auth.d.ts.map +1 -1
  120. package/src/lib/services/auth.js +37 -3
  121. package/src/lib/services/auth.js.map +1 -1
  122. package/src/lib/services/blockStore.d.ts +8 -1
  123. package/src/lib/services/blockStore.d.ts.map +1 -1
  124. package/src/lib/services/blockStore.js +19 -7
  125. package/src/lib/services/blockStore.js.map +1 -1
  126. package/src/lib/services/brightChainBackupCodeService.d.ts +42 -39
  127. package/src/lib/services/brightChainBackupCodeService.d.ts.map +1 -1
  128. package/src/lib/services/brightChainBackupCodeService.js +86 -61
  129. package/src/lib/services/brightChainBackupCodeService.js.map +1 -1
  130. package/src/lib/services/brighthub/collectionAdapter.d.ts +81 -0
  131. package/src/lib/services/brighthub/collectionAdapter.d.ts.map +1 -0
  132. package/src/lib/services/brighthub/collectionAdapter.js +127 -0
  133. package/src/lib/services/brighthub/collectionAdapter.js.map +1 -0
  134. package/src/lib/services/brighthub/connectionService.d.ts.map +1 -1
  135. package/src/lib/services/brighthub/connectionService.js +3 -0
  136. package/src/lib/services/brighthub/connectionService.js.map +1 -1
  137. package/src/lib/services/brighthub/messagingService.d.ts +4 -0
  138. package/src/lib/services/brighthub/messagingService.d.ts.map +1 -1
  139. package/src/lib/services/brighthub/messagingService.js +25 -4
  140. package/src/lib/services/brighthub/messagingService.js.map +1 -1
  141. package/src/lib/services/brighthub/notificationService.d.ts.map +1 -1
  142. package/src/lib/services/brighthub/notificationService.js +35 -20
  143. package/src/lib/services/brighthub/notificationService.js.map +1 -1
  144. package/src/lib/services/brighthub/postService.d.ts +7 -1
  145. package/src/lib/services/brighthub/postService.d.ts.map +1 -1
  146. package/src/lib/services/brighthub/postService.js +22 -1
  147. package/src/lib/services/brighthub/postService.js.map +1 -1
  148. package/src/lib/services/brighthub/userProfileService.d.ts +19 -1
  149. package/src/lib/services/brighthub/userProfileService.d.ts.map +1 -1
  150. package/src/lib/services/brighthub/userProfileService.js +74 -0
  151. package/src/lib/services/brighthub/userProfileService.js.map +1 -1
  152. package/src/lib/services/emailGateway/antiSpamFilter.d.ts +229 -0
  153. package/src/lib/services/emailGateway/antiSpamFilter.d.ts.map +1 -0
  154. package/src/lib/services/emailGateway/antiSpamFilter.js +325 -0
  155. package/src/lib/services/emailGateway/antiSpamFilter.js.map +1 -0
  156. package/src/lib/services/emailGateway/bounceProcessor.d.ts +171 -0
  157. package/src/lib/services/emailGateway/bounceProcessor.d.ts.map +1 -0
  158. package/src/lib/services/emailGateway/bounceProcessor.js +378 -0
  159. package/src/lib/services/emailGateway/bounceProcessor.js.map +1 -0
  160. package/src/lib/services/emailGateway/emailAuthVerifier.d.ts +99 -0
  161. package/src/lib/services/emailGateway/emailAuthVerifier.d.ts.map +1 -0
  162. package/src/lib/services/emailGateway/emailAuthVerifier.js +202 -0
  163. package/src/lib/services/emailGateway/emailAuthVerifier.js.map +1 -0
  164. package/src/lib/services/emailGateway/emailGatewayConfig.d.ts +73 -0
  165. package/src/lib/services/emailGateway/emailGatewayConfig.d.ts.map +1 -0
  166. package/src/lib/services/emailGateway/emailGatewayConfig.js +107 -0
  167. package/src/lib/services/emailGateway/emailGatewayConfig.js.map +1 -0
  168. package/src/lib/services/emailGateway/emailGatewayService.d.ts +152 -0
  169. package/src/lib/services/emailGateway/emailGatewayService.d.ts.map +1 -0
  170. package/src/lib/services/emailGateway/emailGatewayService.js +201 -0
  171. package/src/lib/services/emailGateway/emailGatewayService.js.map +1 -0
  172. package/src/lib/services/emailGateway/gatewayObservability.d.ts +123 -0
  173. package/src/lib/services/emailGateway/gatewayObservability.d.ts.map +1 -0
  174. package/src/lib/services/emailGateway/gatewayObservability.js +186 -0
  175. package/src/lib/services/emailGateway/gatewayObservability.js.map +1 -0
  176. package/src/lib/services/emailGateway/inboundProcessor.d.ts +113 -0
  177. package/src/lib/services/emailGateway/inboundProcessor.d.ts.map +1 -0
  178. package/src/lib/services/emailGateway/inboundProcessor.js +298 -0
  179. package/src/lib/services/emailGateway/inboundProcessor.js.map +1 -0
  180. package/src/lib/services/emailGateway/index.d.ts +23 -0
  181. package/src/lib/services/emailGateway/index.d.ts.map +1 -0
  182. package/src/lib/services/emailGateway/index.js +26 -0
  183. package/src/lib/services/emailGateway/index.js.map +1 -0
  184. package/src/lib/services/emailGateway/outboundDeliveryWorker.d.ts +111 -0
  185. package/src/lib/services/emailGateway/outboundDeliveryWorker.d.ts.map +1 -0
  186. package/src/lib/services/emailGateway/outboundDeliveryWorker.js +97 -0
  187. package/src/lib/services/emailGateway/outboundDeliveryWorker.js.map +1 -0
  188. package/src/lib/services/emailGateway/outboundQueue.d.ts +135 -0
  189. package/src/lib/services/emailGateway/outboundQueue.d.ts.map +1 -0
  190. package/src/lib/services/emailGateway/outboundQueue.js +227 -0
  191. package/src/lib/services/emailGateway/outboundQueue.js.map +1 -0
  192. package/src/lib/services/emailGateway/outboundQueueStore.d.ts +110 -0
  193. package/src/lib/services/emailGateway/outboundQueueStore.d.ts.map +1 -0
  194. package/src/lib/services/emailGateway/outboundQueueStore.js +131 -0
  195. package/src/lib/services/emailGateway/outboundQueueStore.js.map +1 -0
  196. package/src/lib/services/emailGateway/recipientLookupService.d.ts +135 -0
  197. package/src/lib/services/emailGateway/recipientLookupService.d.ts.map +1 -0
  198. package/src/lib/services/emailGateway/recipientLookupService.js +294 -0
  199. package/src/lib/services/emailGateway/recipientLookupService.js.map +1 -0
  200. package/src/lib/services/emailGateway/retryBackoff.d.ts +79 -0
  201. package/src/lib/services/emailGateway/retryBackoff.d.ts.map +1 -0
  202. package/src/lib/services/emailGateway/retryBackoff.js +77 -0
  203. package/src/lib/services/emailGateway/retryBackoff.js.map +1 -0
  204. package/src/lib/services/eventNotificationSystem.d.ts.map +1 -1
  205. package/src/lib/services/eventNotificationSystem.js.map +1 -1
  206. package/src/lib/services/index.d.ts +2 -1
  207. package/src/lib/services/index.d.ts.map +1 -1
  208. package/src/lib/services/index.js +2 -1
  209. package/src/lib/services/index.js.map +1 -1
  210. package/src/lib/services/quorumDatabaseAdapter.d.ts +7 -1
  211. package/src/lib/services/quorumDatabaseAdapter.d.ts.map +1 -1
  212. package/src/lib/services/quorumDatabaseAdapter.js +83 -0
  213. package/src/lib/services/quorumDatabaseAdapter.js.map +1 -1
  214. package/src/lib/services/sessionAdapter.d.ts +2 -61
  215. package/src/lib/services/sessionAdapter.d.ts.map +1 -1
  216. package/src/lib/services/sessionAdapter.js +2 -102
  217. package/src/lib/services/sessionAdapter.js.map +1 -1
  218. package/src/lib/shared-types.d.ts +7 -15
  219. package/src/lib/shared-types.d.ts.map +1 -1
  220. package/src/lib/stores/availabilityAwareBlockStore.d.ts +4 -3
  221. package/src/lib/stores/availabilityAwareBlockStore.d.ts.map +1 -1
  222. package/src/lib/stores/availabilityAwareBlockStore.js +5 -2
  223. package/src/lib/stores/availabilityAwareBlockStore.js.map +1 -1
  224. package/src/lib/stores/cloudBlockStoreBase.d.ts +2 -1
  225. package/src/lib/stores/cloudBlockStoreBase.d.ts.map +1 -1
  226. package/src/lib/stores/cloudBlockStoreBase.js +34 -13
  227. package/src/lib/stores/cloudBlockStoreBase.js.map +1 -1
  228. package/src/lib/stores/diskBlockAsyncStore.d.ts +21 -1
  229. package/src/lib/stores/diskBlockAsyncStore.d.ts.map +1 -1
  230. package/src/lib/stores/diskBlockAsyncStore.js +48 -17
  231. package/src/lib/stores/diskBlockAsyncStore.js.map +1 -1
  232. package/src/lib/stores/diskBlockStore.d.ts +10 -2
  233. package/src/lib/stores/diskBlockStore.d.ts.map +1 -1
  234. package/src/lib/stores/diskBlockStore.js +43 -19
  235. package/src/lib/stores/diskBlockStore.js.map +1 -1
  236. package/src/lib/types/backend-id.d.ts +1 -2
  237. package/src/lib/types/backend-id.d.ts.map +1 -1
  238. package/src/lib/utils/emailValidation.d.ts.map +1 -1
  239. package/src/lib/utils/emailValidation.js +2 -1
  240. package/src/lib/utils/emailValidation.js.map +1 -1
  241. package/src/lib/validation/userValidation.d.ts +2 -43
  242. package/src/lib/validation/userValidation.d.ts.map +1 -1
  243. package/src/lib/validation/userValidation.js +6 -144
  244. package/src/lib/validation/userValidation.js.map +1 -1
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ /**
3
+ * InboundProcessor — watches the Mail Drop Directory for new Maildir-format
4
+ * files deposited by Postfix, parses each message via EmailParser, stores
5
+ * content in the Block Store, creates metadata via EmailMessageService, and
6
+ * announces delivery to the recipient via the Gossip Protocol.
7
+ *
8
+ * On success the processed file is deleted from the Mail Drop Directory.
9
+ * On failure the file is moved to a configurable error directory and the
10
+ * failure reason is logged.
11
+ *
12
+ * A Set of processed filenames provides idempotency — the same file will
13
+ * not be processed twice even if the watcher fires duplicate events.
14
+ *
15
+ * @see Requirements 4.4, 4.5, 4.6, 4.7, 4.8, 4.9
16
+ * @module inboundProcessor
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.InboundProcessor = void 0;
20
+ const tslib_1 = require("tslib");
21
+ const fs = tslib_1.__importStar(require("fs"));
22
+ const path = tslib_1.__importStar(require("path"));
23
+ const brightchain_lib_1 = require("@brightchain/brightchain-lib");
24
+ const emailAuthVerifier_1 = require("./emailAuthVerifier");
25
+ // ─── InboundProcessor ───────────────────────────────────────────────────────
26
+ /**
27
+ * Watches the Mail Drop Directory for new inbound email files and processes
28
+ * them into the BrightChain internal messaging system.
29
+ *
30
+ * Processing pipeline per file:
31
+ * 1. Read raw file content
32
+ * 2. Parse RFC 5322 message via EmailParser
33
+ * 3. Store content in Block Store
34
+ * 4. Create metadata via EmailMessageService
35
+ * 5. Announce to recipient via Gossip Protocol
36
+ * 6. Delete file on success / move to error directory on failure
37
+ *
38
+ * @see Requirements 4.4, 4.5, 4.6, 4.7, 4.8, 4.9
39
+ */
40
+ class InboundProcessor {
41
+ config;
42
+ emailMessageService;
43
+ blockStore;
44
+ gossipService;
45
+ parser;
46
+ /** Authentication verifier for SPF/DKIM/DMARC. Req 6.4, 6.5 */
47
+ authVerifier;
48
+ /** fs.watch handle — `null` when stopped. */
49
+ watcher = null;
50
+ /** Whether the processor is currently running. */
51
+ running = false;
52
+ /** Filenames that have already been processed (idempotency guard). Req 4.7 */
53
+ processedFiles = new Set();
54
+ constructor(config, emailParser, emailMessageService, blockStore, gossipService, authVerifier) {
55
+ this.config = config;
56
+ this.emailMessageService = emailMessageService;
57
+ this.blockStore = blockStore;
58
+ this.gossipService = gossipService;
59
+ this.parser = emailParser ?? new brightchain_lib_1.EmailParser();
60
+ this.authVerifier = authVerifier ?? new emailAuthVerifier_1.EmailAuthVerifier();
61
+ }
62
+ // ─── Lifecycle ──────────────────────────────────────────────────────
63
+ /**
64
+ * Start watching the Mail Drop Directory for new files.
65
+ *
66
+ * Creates the mail drop and error directories if they do not exist,
67
+ * then sets up an `fs.watch` listener that triggers processing for
68
+ * every new or renamed file.
69
+ *
70
+ * @see Requirement 4.5 — watch via inotify / fs.watch
71
+ */
72
+ start() {
73
+ if (this.running) {
74
+ return;
75
+ }
76
+ // Ensure directories exist.
77
+ fs.mkdirSync(this.config.mailDropDirectory, { recursive: true });
78
+ fs.mkdirSync(this.config.errorDirectory, { recursive: true });
79
+ // Process any files already present in the directory.
80
+ this.processExistingFiles();
81
+ // Watch for new files.
82
+ this.watcher = fs.watch(this.config.mailDropDirectory, (eventType, filename) => {
83
+ if (filename && (eventType === 'rename' || eventType === 'change')) {
84
+ // Small delay to allow the file to be fully written.
85
+ setTimeout(() => {
86
+ void this.processFile(filename);
87
+ }, 100);
88
+ }
89
+ });
90
+ this.running = true;
91
+ }
92
+ /**
93
+ * Stop watching the Mail Drop Directory.
94
+ */
95
+ stop() {
96
+ if (!this.running) {
97
+ return;
98
+ }
99
+ if (this.watcher) {
100
+ this.watcher.close();
101
+ this.watcher = null;
102
+ }
103
+ this.running = false;
104
+ }
105
+ /**
106
+ * Whether the processor is currently running.
107
+ */
108
+ isRunning() {
109
+ return this.running;
110
+ }
111
+ // ─── File Processing ────────────────────────────────────────────────
112
+ /**
113
+ * Process all files already present in the Mail Drop Directory.
114
+ * Called once on startup to handle files deposited while the processor
115
+ * was not running.
116
+ */
117
+ processExistingFiles() {
118
+ let entries;
119
+ try {
120
+ entries = fs.readdirSync(this.config.mailDropDirectory);
121
+ }
122
+ catch {
123
+ return;
124
+ }
125
+ for (const filename of entries) {
126
+ const fullPath = path.join(this.config.mailDropDirectory, filename);
127
+ try {
128
+ const stat = fs.statSync(fullPath);
129
+ if (stat.isFile()) {
130
+ void this.processFile(filename);
131
+ }
132
+ }
133
+ catch {
134
+ // Skip entries we cannot stat.
135
+ }
136
+ }
137
+ }
138
+ /**
139
+ * Process a single inbound email file.
140
+ *
141
+ * Idempotency: if the file has already been processed (tracked in
142
+ * `processedFiles`) the call is a no-op. Req 4.7
143
+ *
144
+ * @param filename - The filename (not full path) within the Mail Drop Directory
145
+ *
146
+ * @see Requirement 4.6 — parse, store, create metadata
147
+ * @see Requirement 4.7 — delete on success
148
+ * @see Requirement 4.8 — move to error directory on failure
149
+ * @see Requirement 4.9 — announce via gossip
150
+ */
151
+ async processFile(filename) {
152
+ // Idempotency guard (Req 4.7).
153
+ if (this.processedFiles.has(filename)) {
154
+ return;
155
+ }
156
+ const filePath = path.join(this.config.mailDropDirectory, filename);
157
+ // Verify the file still exists (it may have been removed between
158
+ // the watcher event and this handler running).
159
+ if (!fs.existsSync(filePath)) {
160
+ return;
161
+ }
162
+ // Mark as in-progress immediately to prevent duplicate processing
163
+ // from concurrent watcher events.
164
+ this.processedFiles.add(filename);
165
+ try {
166
+ // 1. Read raw file content.
167
+ const rawContent = fs.readFileSync(filePath);
168
+ // 2. Parse RFC 5322 message via EmailParser (Req 4.6).
169
+ const metadata = await this.parser.parse(rawContent);
170
+ // 2b. Verify SPF/DKIM/DMARC authentication results (Req 6.4).
171
+ const authResult = this.authVerifier.verify(rawContent);
172
+ // 2c. Reject messages failing DMARC with reject policy (Req 6.5).
173
+ if (emailAuthVerifier_1.EmailAuthVerifier.shouldRejectDmarc(authResult)) {
174
+ throw new Error(`DMARC verification failed (550 reject): ${authResult.dmarc.details ?? 'policy=reject'}`);
175
+ }
176
+ // 3. Store content in Block Store.
177
+ const blockId = metadata.messageId;
178
+ await this.blockStore.put(blockId, rawContent);
179
+ // 4. Create metadata via EmailMessageService (Req 4.6).
180
+ // We use sendEmail with the parsed metadata to go through the
181
+ // standard storage and delivery pipeline.
182
+ const recipientAddresses = [
183
+ ...metadata.to.map((m) => m.address),
184
+ ...(metadata.cc ?? []).map((m) => m.address),
185
+ ];
186
+ await this.emailMessageService.sendEmail({
187
+ from: metadata.from,
188
+ to: metadata.to,
189
+ cc: metadata.cc,
190
+ bcc: metadata.bcc,
191
+ subject: metadata.subject,
192
+ messageId: metadata.messageId,
193
+ date: metadata.date,
194
+ inReplyTo: metadata.inReplyTo,
195
+ references: metadata.references,
196
+ contentType: metadata.contentType,
197
+ parts: metadata.parts,
198
+ textBody: this.extractTextBody(metadata),
199
+ htmlBody: this.extractHtmlBody(metadata),
200
+ customHeaders: this.mergeAuthHeaders(metadata.customHeaders, authResult),
201
+ });
202
+ // 5. Announce to recipients via Gossip Protocol (Req 4.9).
203
+ await this.gossipService.announceMessage(metadata.cblBlockIds ?? [blockId], {
204
+ messageId: metadata.messageId,
205
+ recipientIds: recipientAddresses,
206
+ priority: 'normal',
207
+ blockIds: metadata.cblBlockIds ?? [blockId],
208
+ cblBlockId: metadata.blockId ?? blockId,
209
+ ackRequired: true,
210
+ });
211
+ // 6. Delete processed file on success (Req 4.7).
212
+ fs.unlinkSync(filePath);
213
+ }
214
+ catch (err) {
215
+ // On failure: move to error directory and log reason (Req 4.8).
216
+ const reason = err instanceof Error ? err.message : String(err);
217
+ try {
218
+ const errorPath = path.join(this.config.errorDirectory, filename);
219
+ fs.renameSync(filePath, errorPath);
220
+ }
221
+ catch {
222
+ // If we can't move the file, leave it in place — it won't be
223
+ // reprocessed because it's already in processedFiles.
224
+ }
225
+ // Log the failure reason.
226
+ console.error(`[InboundProcessor] Failed to process ${filename}: ${reason}`);
227
+ // Remove from processedFiles so a retry can be attempted if the
228
+ // file is re-deposited.
229
+ this.processedFiles.delete(filename);
230
+ }
231
+ }
232
+ // ─── Helpers ────────────────────────────────────────────────────────
233
+ /**
234
+ * Merge authentication results into custom headers as a serialized
235
+ * `X-BrightChain-Auth-Results` header so the auth metadata is
236
+ * preserved alongside the message.
237
+ *
238
+ * @see Requirement 6.4
239
+ */
240
+ mergeAuthHeaders(existing, authResult) {
241
+ const merged = new Map(existing);
242
+ const summary = [
243
+ `spf=${authResult.spf.status}`,
244
+ `dkim=${authResult.dkim.status}`,
245
+ `dmarc=${authResult.dmarc.status}`,
246
+ ].join('; ');
247
+ merged.set('X-BrightChain-Auth-Results', [summary]);
248
+ return merged;
249
+ }
250
+ /**
251
+ * Extract plain-text body from parsed email metadata.
252
+ */
253
+ extractTextBody(metadata) {
254
+ if (metadata.parts && metadata.parts.length > 0) {
255
+ for (const part of metadata.parts) {
256
+ if (part.contentType?.type === 'text' &&
257
+ part.contentType?.subtype === 'plain' &&
258
+ part.body) {
259
+ return typeof part.body === 'string'
260
+ ? part.body
261
+ : new TextDecoder().decode(part.body);
262
+ }
263
+ }
264
+ }
265
+ return undefined;
266
+ }
267
+ /**
268
+ * Extract HTML body from parsed email metadata.
269
+ */
270
+ extractHtmlBody(metadata) {
271
+ if (metadata.parts && metadata.parts.length > 0) {
272
+ for (const part of metadata.parts) {
273
+ if (part.contentType?.type === 'text' &&
274
+ part.contentType?.subtype === 'html' &&
275
+ part.body) {
276
+ return typeof part.body === 'string'
277
+ ? part.body
278
+ : new TextDecoder().decode(part.body);
279
+ }
280
+ }
281
+ }
282
+ return undefined;
283
+ }
284
+ /**
285
+ * Get the set of processed filenames (for testing / inspection).
286
+ */
287
+ getProcessedFiles() {
288
+ return this.processedFiles;
289
+ }
290
+ /**
291
+ * Clear the processed files set (for testing).
292
+ */
293
+ clearProcessedFiles() {
294
+ this.processedFiles.clear();
295
+ }
296
+ }
297
+ exports.InboundProcessor = InboundProcessor;
298
+ //# sourceMappingURL=inboundProcessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inboundProcessor.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/inboundProcessor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Email Gateway module barrel export.
3
+ *
4
+ * Re-exports all public gateway components so consumers can import from
5
+ * `@brightchain/brightchain-api-lib` (via the services barrel) with a
6
+ * single import path.
7
+ *
8
+ * @see Requirements 11.2, 11.3
9
+ * @module emailGateway
10
+ */
11
+ export * from './antiSpamFilter';
12
+ export * from './bounceProcessor';
13
+ export * from './emailAuthVerifier';
14
+ export * from './emailGatewayConfig';
15
+ export * from './emailGatewayService';
16
+ export * from './gatewayObservability';
17
+ export * from './inboundProcessor';
18
+ export * from './outboundDeliveryWorker';
19
+ export * from './outboundQueue';
20
+ export * from './outboundQueueStore';
21
+ export * from './recipientLookupService';
22
+ export * from './retryBackoff';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * Email Gateway module barrel export.
4
+ *
5
+ * Re-exports all public gateway components so consumers can import from
6
+ * `@brightchain/brightchain-api-lib` (via the services barrel) with a
7
+ * single import path.
8
+ *
9
+ * @see Requirements 11.2, 11.3
10
+ * @module emailGateway
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const tslib_1 = require("tslib");
14
+ tslib_1.__exportStar(require("./antiSpamFilter"), exports);
15
+ tslib_1.__exportStar(require("./bounceProcessor"), exports);
16
+ tslib_1.__exportStar(require("./emailAuthVerifier"), exports);
17
+ tslib_1.__exportStar(require("./emailGatewayConfig"), exports);
18
+ tslib_1.__exportStar(require("./emailGatewayService"), exports);
19
+ tslib_1.__exportStar(require("./gatewayObservability"), exports);
20
+ tslib_1.__exportStar(require("./inboundProcessor"), exports);
21
+ tslib_1.__exportStar(require("./outboundDeliveryWorker"), exports);
22
+ tslib_1.__exportStar(require("./outboundQueue"), exports);
23
+ tslib_1.__exportStar(require("./outboundQueueStore"), exports);
24
+ tslib_1.__exportStar(require("./recipientLookupService"), exports);
25
+ tslib_1.__exportStar(require("./retryBackoff"), exports);
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,2DAAiC;AACjC,4DAAkC;AAClC,8DAAoC;AACpC,+DAAqC;AACrC,gEAAsC;AACtC,iEAAuC;AACvC,6DAAmC;AACnC,mEAAyC;AACzC,0DAAgC;AAChC,+DAAqC;AACrC,mEAAyC;AACzC,yDAA+B"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * OutboundDeliveryWorker — dequeues messages from the OutboundQueue,
3
+ * serializes them to RFC 5322 format, applies DKIM signing, and
4
+ * delegates delivery to Postfix via sendmail or LMTP.
5
+ *
6
+ * The worker registers itself as the OutboundQueue's handler so that
7
+ * each dequeued item flows through the delivery pipeline:
8
+ * 1. Enforce max message size
9
+ * 2. Serialize IEmailMetadata → RFC 5322 via EmailSerializer
10
+ * 3. Apply DKIM signature
11
+ * 4. Send via Postfix transport
12
+ * 5. Update queue status on success/failure
13
+ *
14
+ * Transport and DKIM signing are injected as interfaces so the worker
15
+ * can be tested without real Postfix or key material.
16
+ *
17
+ * @see Requirements 2.1, 2.2, 2.3, 2.4, 2.5, 6.1
18
+ * @module outboundDeliveryWorker
19
+ */
20
+ import type { IEmailGatewayConfig } from './emailGatewayConfig';
21
+ import type { IOutboundQueueItem } from './emailGatewayService';
22
+ import type { OutboundQueue } from './outboundQueue';
23
+ import type { IOutboundQueueStore } from './outboundQueueStore';
24
+ /**
25
+ * Result returned by the Postfix transport after attempting delivery.
26
+ */
27
+ export interface IPostfixTransportResult {
28
+ /** Whether the delivery succeeded. */
29
+ success: boolean;
30
+ /** SMTP response code (e.g. 250 for success, 4xx for temp failure, 5xx for permanent). */
31
+ responseCode: number;
32
+ /** Human-readable response message from the MTA. */
33
+ responseMessage: string;
34
+ }
35
+ /**
36
+ * Interface for delegating email delivery to Postfix via sendmail or LMTP.
37
+ *
38
+ * Implementations wrap the actual transport mechanism (child_process sendmail,
39
+ * LMTP socket, etc.) behind a simple async interface.
40
+ *
41
+ * @see Requirement 2.4
42
+ */
43
+ export interface IPostfixTransport {
44
+ /**
45
+ * Send a raw RFC 5322 message to the specified recipients.
46
+ *
47
+ * @param from - Envelope sender address
48
+ * @param to - Envelope recipient addresses
49
+ * @param rawMessage - Complete RFC 5322 message bytes (with DKIM signature)
50
+ * @returns Delivery result with SMTP response code
51
+ */
52
+ send(from: string, to: string[], rawMessage: Uint8Array): Promise<IPostfixTransportResult>;
53
+ }
54
+ /**
55
+ * Interface for applying DKIM signatures to outbound messages.
56
+ *
57
+ * Implementations read the private key from the configured path and
58
+ * produce a signed message with the DKIM-Signature header prepended.
59
+ *
60
+ * @see Requirement 6.1
61
+ */
62
+ export interface IDkimSigner {
63
+ /**
64
+ * Sign a raw RFC 5322 message with DKIM.
65
+ *
66
+ * @param rawMessage - The unsigned RFC 5322 message bytes
67
+ * @param domain - The signing domain (canonical domain)
68
+ * @param selector - The DKIM selector for DNS lookup
69
+ * @returns The signed message bytes with DKIM-Signature header prepended
70
+ */
71
+ sign(rawMessage: Uint8Array, domain: string, selector: string): Promise<Uint8Array>;
72
+ }
73
+ /**
74
+ * Worker that processes outbound email delivery from the queue.
75
+ *
76
+ * Registers as the OutboundQueue's handler and processes each dequeued
77
+ * item through the serialization → DKIM → transport pipeline.
78
+ *
79
+ * @see Requirements 2.1, 2.2, 2.3, 2.4, 2.5, 6.1
80
+ */
81
+ export declare class OutboundDeliveryWorker {
82
+ private readonly queue;
83
+ private readonly store;
84
+ private readonly config;
85
+ private readonly transport;
86
+ private readonly dkimSigner;
87
+ private readonly serializer;
88
+ /**
89
+ * @param queue - The outbound queue to register as handler on
90
+ * @param store - Queue store for updating item status on success/failure
91
+ * @param config - Gateway configuration (max message size, DKIM settings)
92
+ * @param transport - Postfix transport for actual SMTP delivery
93
+ * @param dkimSigner - DKIM signer for message authentication
94
+ */
95
+ constructor(queue: OutboundQueue, store: IOutboundQueueStore, config: IEmailGatewayConfig, transport: IPostfixTransport, dkimSigner: IDkimSigner);
96
+ /**
97
+ * Handle a single dequeued outbound queue item.
98
+ *
99
+ * Pipeline:
100
+ * 1. Serialize IEmailMetadata → RFC 5322 via EmailSerializer
101
+ * 2. Enforce max message size (Req 2.5)
102
+ * 3. Apply DKIM signature (Req 6.1)
103
+ * 4. Delegate to Postfix transport (Req 2.4)
104
+ * 5. Mark completed or failed in the store
105
+ *
106
+ * @param item - The dequeued outbound queue item
107
+ * @throws Re-throws transport errors so the OutboundQueue can requeue
108
+ */
109
+ handleItem(item: IOutboundQueueItem): Promise<void>;
110
+ }
111
+ //# sourceMappingURL=outboundDeliveryWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outboundDeliveryWorker.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/outboundDeliveryWorker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAIhE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,0FAA0F;IAC1F,YAAY,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;OAOG;IACH,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EAAE,EACZ,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,uBAAuB,CAAC,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;;OAOG;IACH,IAAI,CACF,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAAC;CACxB;AAID;;;;;;;GAOG;AACH,qBAAa,sBAAsB;IAW/B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAd7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAE7C;;;;;;OAMG;gBAEgB,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,iBAAiB,EAC5B,UAAU,EAAE,WAAW;IAO1C;;;;;;;;;;;;OAYG;IACG,UAAU,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CAuC1D"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ /**
3
+ * OutboundDeliveryWorker — dequeues messages from the OutboundQueue,
4
+ * serializes them to RFC 5322 format, applies DKIM signing, and
5
+ * delegates delivery to Postfix via sendmail or LMTP.
6
+ *
7
+ * The worker registers itself as the OutboundQueue's handler so that
8
+ * each dequeued item flows through the delivery pipeline:
9
+ * 1. Enforce max message size
10
+ * 2. Serialize IEmailMetadata → RFC 5322 via EmailSerializer
11
+ * 3. Apply DKIM signature
12
+ * 4. Send via Postfix transport
13
+ * 5. Update queue status on success/failure
14
+ *
15
+ * Transport and DKIM signing are injected as interfaces so the worker
16
+ * can be tested without real Postfix or key material.
17
+ *
18
+ * @see Requirements 2.1, 2.2, 2.3, 2.4, 2.5, 6.1
19
+ * @module outboundDeliveryWorker
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.OutboundDeliveryWorker = void 0;
23
+ const brightchain_lib_1 = require("@brightchain/brightchain-lib");
24
+ // ─── OutboundDeliveryWorker ─────────────────────────────────────────────────
25
+ /**
26
+ * Worker that processes outbound email delivery from the queue.
27
+ *
28
+ * Registers as the OutboundQueue's handler and processes each dequeued
29
+ * item through the serialization → DKIM → transport pipeline.
30
+ *
31
+ * @see Requirements 2.1, 2.2, 2.3, 2.4, 2.5, 6.1
32
+ */
33
+ class OutboundDeliveryWorker {
34
+ queue;
35
+ store;
36
+ config;
37
+ transport;
38
+ dkimSigner;
39
+ serializer;
40
+ /**
41
+ * @param queue - The outbound queue to register as handler on
42
+ * @param store - Queue store for updating item status on success/failure
43
+ * @param config - Gateway configuration (max message size, DKIM settings)
44
+ * @param transport - Postfix transport for actual SMTP delivery
45
+ * @param dkimSigner - DKIM signer for message authentication
46
+ */
47
+ constructor(queue, store, config, transport, dkimSigner) {
48
+ this.queue = queue;
49
+ this.store = store;
50
+ this.config = config;
51
+ this.transport = transport;
52
+ this.dkimSigner = dkimSigner;
53
+ this.serializer = new brightchain_lib_1.EmailSerializer();
54
+ // Register this worker as the queue's handler.
55
+ this.queue.setHandler(this.handleItem.bind(this));
56
+ }
57
+ /**
58
+ * Handle a single dequeued outbound queue item.
59
+ *
60
+ * Pipeline:
61
+ * 1. Serialize IEmailMetadata → RFC 5322 via EmailSerializer
62
+ * 2. Enforce max message size (Req 2.5)
63
+ * 3. Apply DKIM signature (Req 6.1)
64
+ * 4. Delegate to Postfix transport (Req 2.4)
65
+ * 5. Mark completed or failed in the store
66
+ *
67
+ * @param item - The dequeued outbound queue item
68
+ * @throws Re-throws transport errors so the OutboundQueue can requeue
69
+ */
70
+ async handleItem(item) {
71
+ // 1. Serialize metadata to RFC 5322
72
+ const rawMessage = this.serializer.serialize(item.metadata);
73
+ // 2. Enforce max message size (Req 2.5)
74
+ if (rawMessage.byteLength > this.config.maxMessageSizeBytes) {
75
+ await this.store.markFailed(item.messageId, `Message size ${rawMessage.byteLength} bytes exceeds maximum ${this.config.maxMessageSizeBytes} bytes`);
76
+ return;
77
+ }
78
+ // 3. Apply DKIM signature (Req 6.1)
79
+ const signedMessage = await this.dkimSigner.sign(rawMessage, this.config.canonicalDomain, this.config.dkimSelector);
80
+ // 4. Delegate to Postfix transport (Req 2.4)
81
+ const result = await this.transport.send(item.from, item.to, signedMessage);
82
+ // 5. Update status based on transport result
83
+ if (result.success) {
84
+ await this.store.markCompleted(item.messageId);
85
+ }
86
+ else if (result.responseCode >= 500) {
87
+ // Permanent failure (5xx) — mark failed, do not retry
88
+ await this.store.markFailed(item.messageId, `Permanent failure (${result.responseCode}): ${result.responseMessage}`);
89
+ }
90
+ else {
91
+ // Temporary failure (4xx) — throw so OutboundQueue requeues with retry logic
92
+ throw new Error(`Temporary failure (${result.responseCode}): ${result.responseMessage}`);
93
+ }
94
+ }
95
+ }
96
+ exports.OutboundDeliveryWorker = OutboundDeliveryWorker;
97
+ //# sourceMappingURL=outboundDeliveryWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outboundDeliveryWorker.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/outboundDeliveryWorker.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,kEAA+D;AAqE/D,+EAA+E;AAE/E;;;;;;;GAOG;AACH,MAAa,sBAAsB;IAWd;IACA;IACA;IACA;IACA;IAdF,UAAU,CAAkB;IAE7C;;;;;;OAMG;IACH,YACmB,KAAoB,EACpB,KAA0B,EAC1B,MAA2B,EAC3B,SAA4B,EAC5B,UAAuB;QAJvB,UAAK,GAAL,KAAK,CAAe;QACpB,UAAK,GAAL,KAAK,CAAqB;QAC1B,WAAM,GAAN,MAAM,CAAqB;QAC3B,cAAS,GAAT,SAAS,CAAmB;QAC5B,eAAU,GAAV,UAAU,CAAa;QAExC,IAAI,CAAC,UAAU,GAAG,IAAI,iCAAe,EAAE,CAAC;QACxC,+CAA+C;QAC/C,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,UAAU,CAAC,IAAwB;QACvC,oCAAoC;QACpC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE5D,wCAAwC;QACxC,IAAI,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC5D,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CACzB,IAAI,CAAC,SAAS,EACd,gBAAgB,UAAU,CAAC,UAAU,0BAA0B,IAAI,CAAC,MAAM,CAAC,mBAAmB,QAAQ,CACvG,CAAC;YACF,OAAO;QACT,CAAC;QAED,oCAAoC;QACpC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAC9C,UAAU,EACV,IAAI,CAAC,MAAM,CAAC,eAAe,EAC3B,IAAI,CAAC,MAAM,CAAC,YAAY,CACzB,CAAC;QAEF,6CAA6C;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QAE5E,6CAA6C;QAC7C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,MAAM,CAAC,YAAY,IAAI,GAAG,EAAE,CAAC;YACtC,sDAAsD;YACtD,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CACzB,IAAI,CAAC,SAAS,EACd,sBAAsB,MAAM,CAAC,YAAY,MAAM,MAAM,CAAC,eAAe,EAAE,CACxE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,6EAA6E;YAC7E,MAAM,IAAI,KAAK,CACb,sBAAsB,MAAM,CAAC,YAAY,MAAM,MAAM,CAAC,eAAe,EAAE,CACxE,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AA1ED,wDA0EC"}