@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,202 @@
1
+ "use strict";
2
+ /**
3
+ * Email Authentication Verifier — parses SPF/DKIM/DMARC authentication
4
+ * results from inbound email messages.
5
+ *
6
+ * In a typical deployment, Postfix and its milters (e.g. OpenDKIM,
7
+ * opendmarc, pypolicyd-spf) perform the actual SPF, DKIM, and DMARC
8
+ * verification before depositing the message in the Mail Drop Directory.
9
+ * These results are recorded in the `Authentication-Results` header
10
+ * (RFC 8601).
11
+ *
12
+ * This verifier parses those headers from the raw message to extract
13
+ * structured `IEmailAuthenticationResult` metadata that the
14
+ * InboundProcessor stores alongside the message.
15
+ *
16
+ * @see Requirements 6.4, 6.5
17
+ * @module emailAuthVerifier
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.EmailAuthVerifier = void 0;
21
+ exports.defaultAuthResult = defaultAuthResult;
22
+ const VALID_SPF_STATUSES = new Set([
23
+ 'pass',
24
+ 'fail',
25
+ 'softfail',
26
+ 'neutral',
27
+ 'none',
28
+ 'temperror',
29
+ 'permerror',
30
+ ]);
31
+ const VALID_DKIM_STATUSES = new Set([
32
+ 'pass',
33
+ 'fail',
34
+ 'none',
35
+ 'temperror',
36
+ 'permerror',
37
+ ]);
38
+ const VALID_DMARC_STATUSES = new Set([
39
+ 'pass',
40
+ 'fail',
41
+ 'none',
42
+ 'temperror',
43
+ 'permerror',
44
+ ]);
45
+ // ─── Default result ─────────────────────────────────────────────────────────
46
+ /**
47
+ * Returns a default `IEmailAuthenticationResult` with all statuses set to `'none'`.
48
+ */
49
+ function defaultAuthResult() {
50
+ return {
51
+ spf: { status: 'none' },
52
+ dkim: { status: 'none' },
53
+ dmarc: { status: 'none' },
54
+ };
55
+ }
56
+ // ─── Implementation ─────────────────────────────────────────────────────────
57
+ /**
58
+ * Parses `Authentication-Results` headers from raw RFC 5322 messages to
59
+ * extract SPF, DKIM, and DMARC verification results.
60
+ *
61
+ * This is an adapter/stub that reads results already computed by
62
+ * Postfix milters. It does NOT perform cryptographic DKIM verification
63
+ * or DNS lookups itself.
64
+ *
65
+ * @see Requirements 6.4, 6.5
66
+ */
67
+ class EmailAuthVerifier {
68
+ /**
69
+ * Parse authentication results from the raw message headers.
70
+ *
71
+ * Extracts the `Authentication-Results` header value and parses
72
+ * individual method results (spf=, dkim=, dmarc=).
73
+ *
74
+ * @param rawMessage - Raw RFC 5322 message bytes
75
+ * @param _senderIp - Sender IP (unused; reserved for future direct verification)
76
+ * @returns Structured authentication results
77
+ */
78
+ verify(rawMessage, _senderIp) {
79
+ const headerValue = this.extractAuthResultsHeader(rawMessage);
80
+ if (!headerValue) {
81
+ return defaultAuthResult();
82
+ }
83
+ return this.parseAuthResultsHeader(headerValue);
84
+ }
85
+ /**
86
+ * Check whether the authentication result indicates a DMARC reject
87
+ * condition — i.e. DMARC status is `'fail'`.
88
+ *
89
+ * The caller (InboundProcessor) uses this to decide whether to move
90
+ * the message to the error directory with a 550-equivalent rejection.
91
+ *
92
+ * @param result - The parsed authentication result
93
+ * @returns `true` if DMARC failed (reject policy should apply)
94
+ *
95
+ * @see Requirement 6.5
96
+ */
97
+ static shouldRejectDmarc(result) {
98
+ return result.dmarc.status === 'fail';
99
+ }
100
+ // ─── Header extraction ──────────────────────────────────────────────
101
+ /**
102
+ * Extract the value of the first `Authentication-Results` header from
103
+ * the raw message bytes.
104
+ *
105
+ * RFC 5322 headers end at the first blank line (`\r\n\r\n` or `\n\n`).
106
+ * Header continuation (folding) is handled by joining lines that start
107
+ * with whitespace.
108
+ */
109
+ extractAuthResultsHeader(rawMessage) {
110
+ const text = typeof rawMessage === 'string'
111
+ ? rawMessage
112
+ : Buffer.isBuffer(rawMessage)
113
+ ? rawMessage.toString('utf-8')
114
+ : new TextDecoder().decode(rawMessage);
115
+ // Split headers from body at the first blank line.
116
+ const headerEndCrLf = text.indexOf('\r\n\r\n');
117
+ const headerEndLf = text.indexOf('\n\n');
118
+ let headerSection;
119
+ if (headerEndCrLf >= 0 &&
120
+ (headerEndLf < 0 || headerEndCrLf <= headerEndLf)) {
121
+ headerSection = text.substring(0, headerEndCrLf);
122
+ }
123
+ else if (headerEndLf >= 0) {
124
+ headerSection = text.substring(0, headerEndLf);
125
+ }
126
+ else {
127
+ // No blank line — treat entire content as headers.
128
+ headerSection = text;
129
+ }
130
+ // Unfold continuation lines (lines starting with whitespace are
131
+ // continuations of the previous header per RFC 5322 §2.2.3).
132
+ const unfolded = headerSection.replace(/\r?\n([ \t])/g, ' ');
133
+ // Split into individual header lines.
134
+ const lines = unfolded.split(/\r?\n/);
135
+ for (const line of lines) {
136
+ const match = line.match(/^Authentication-Results:\s*(.+)$/i);
137
+ if (match) {
138
+ return match[1].trim();
139
+ }
140
+ }
141
+ return null;
142
+ }
143
+ // ─── Header parsing ─────────────────────────────────────────────────
144
+ /**
145
+ * Parse an `Authentication-Results` header value into structured results.
146
+ *
147
+ * The header format (RFC 8601) is roughly:
148
+ * `authserv-id; method=status (details); method=status ...`
149
+ *
150
+ * We split on `;` and look for `spf=`, `dkim=`, `dmarc=` prefixes.
151
+ */
152
+ parseAuthResultsHeader(headerValue) {
153
+ const result = defaultAuthResult();
154
+ // Split on semicolons — first segment is the authserv-id, rest are results.
155
+ const segments = headerValue.split(';').map((s) => s.trim());
156
+ // Skip the first segment (authserv-id).
157
+ for (let i = 1; i < segments.length; i++) {
158
+ const segment = segments[i];
159
+ if (!segment)
160
+ continue;
161
+ this.parseMethodResult(segment, result);
162
+ }
163
+ return result;
164
+ }
165
+ /**
166
+ * Parse a single method result segment like `spf=pass (details here)`.
167
+ */
168
+ parseMethodResult(segment, result) {
169
+ // Match pattern: method=status with optional details in parentheses or after whitespace
170
+ // Examples:
171
+ // spf=pass (sender SPF authorized)
172
+ // dkim=pass header.d=example.com
173
+ // dmarc=fail (p=reject)
174
+ const methodMatch = segment.match(/^\s*(spf|dkim|dmarc)\s*=\s*(\S+)/i);
175
+ if (!methodMatch)
176
+ return;
177
+ const method = methodMatch[1].toLowerCase();
178
+ const rawStatus = methodMatch[2].toLowerCase();
179
+ // Extract optional details in parentheses.
180
+ const detailsMatch = segment.match(/\(([^)]*)\)/);
181
+ const details = detailsMatch ? detailsMatch[1].trim() : undefined;
182
+ switch (method) {
183
+ case 'spf':
184
+ if (VALID_SPF_STATUSES.has(rawStatus)) {
185
+ result.spf = { status: rawStatus, details };
186
+ }
187
+ break;
188
+ case 'dkim':
189
+ if (VALID_DKIM_STATUSES.has(rawStatus)) {
190
+ result.dkim = { status: rawStatus, details };
191
+ }
192
+ break;
193
+ case 'dmarc':
194
+ if (VALID_DMARC_STATUSES.has(rawStatus)) {
195
+ result.dmarc = { status: rawStatus, details };
196
+ }
197
+ break;
198
+ }
199
+ }
200
+ }
201
+ exports.EmailAuthVerifier = EmailAuthVerifier;
202
+ //# sourceMappingURL=emailAuthVerifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emailAuthVerifier.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/emailAuthVerifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Email Gateway Configuration
3
+ *
4
+ * Defines the `IEmailGatewayConfig` interface and a `loadGatewayConfig()` loader
5
+ * that reads values from `CoreConstants.SiteEmailDomain` and environment variables
6
+ * with sensible defaults.
7
+ *
8
+ * All Node.js-specific gateway configuration lives here in brightchain-api-lib.
9
+ * The shared `ISpamThresholds` interface is imported from brightchain-lib.
10
+ *
11
+ * @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
12
+ * @module emailGatewayConfig
13
+ */
14
+ import { type ISpamThresholds } from '@brightchain/brightchain-lib';
15
+ /**
16
+ * Complete configuration for the Email Gateway.
17
+ *
18
+ * Each field maps to an environment variable (noted in comments) with a
19
+ * default value applied by `loadGatewayConfig()` when the variable is unset.
20
+ *
21
+ * @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
22
+ */
23
+ export interface IEmailGatewayConfig {
24
+ /** Canonical email domain for this BrightChain instance (from CoreConstants.SiteEmailDomain). Req 8.1 */
25
+ canonicalDomain: string;
26
+ /** Postfix MTA hostname. env: GATEWAY_POSTFIX_HOST. Req 8.2 */
27
+ postfixHost: string;
28
+ /** Postfix MTA port. env: GATEWAY_POSTFIX_PORT. Req 8.2 */
29
+ postfixPort: number;
30
+ /** Optional Postfix authentication credentials. env: GATEWAY_POSTFIX_USER / GATEWAY_POSTFIX_PASS. Req 8.2 */
31
+ postfixAuth?: {
32
+ user: string;
33
+ pass: string;
34
+ };
35
+ /** Path to the DKIM private key file. env: GATEWAY_DKIM_KEY_PATH. Req 8.3 */
36
+ dkimKeyPath: string;
37
+ /** DKIM selector for DNS lookup. env: GATEWAY_DKIM_SELECTOR. Req 8.3 */
38
+ dkimSelector: string;
39
+ /** Directory where Postfix deposits inbound mail (Maildir format). env: GATEWAY_MAIL_DROP_DIR. Req 8.6 */
40
+ mailDropDirectory: string;
41
+ /** Directory for messages that fail inbound processing. env: GATEWAY_ERROR_DIR. Req 8.6 */
42
+ errorDirectory: string;
43
+ /** Maximum outbound message size in bytes. env: GATEWAY_MAX_MESSAGE_SIZE. Req 8.4 */
44
+ maxMessageSizeBytes: number;
45
+ /** TCP port for the Recipient Lookup Service (socketmap). env: GATEWAY_LOOKUP_PORT. Req 8.7 */
46
+ recipientLookupPort: number;
47
+ /** Cache TTL in seconds for positive recipient lookups. env: GATEWAY_LOOKUP_CACHE_TTL. Req 8.7 */
48
+ recipientLookupCacheTtlSeconds: number;
49
+ /** Anti-spam engine selection. env: GATEWAY_SPAM_ENGINE. Req 8.4 */
50
+ spamEngine: 'spamassassin' | 'rspamd';
51
+ /** Score thresholds for spam classification. env: GATEWAY_SPAM_PROBABLE / GATEWAY_SPAM_DEFINITE. Req 8.4 */
52
+ spamThresholds: ISpamThresholds;
53
+ /** Maximum concurrent outbound SMTP connections. env: GATEWAY_QUEUE_CONCURRENCY. Req 8.4 */
54
+ queueConcurrency: number;
55
+ /** Maximum number of delivery retry attempts. env: GATEWAY_RETRY_MAX_COUNT. Req 8.4 */
56
+ retryMaxCount: number;
57
+ /** Maximum total retry duration in milliseconds. env: GATEWAY_RETRY_MAX_DURATION. Req 8.4 */
58
+ retryMaxDurationMs: number;
59
+ /** Base interval in milliseconds for exponential back-off. env: GATEWAY_RETRY_BASE_INTERVAL. Req 8.4 */
60
+ retryBaseIntervalMs: number;
61
+ }
62
+ /**
63
+ * Load the Email Gateway configuration from `CoreConstants` and environment variables.
64
+ *
65
+ * Reads `CoreConstants.SiteEmailDomain` for the canonical domain (Req 8.1) and
66
+ * environment variables for all other settings, applying defaults where unset.
67
+ *
68
+ * @returns A fully populated `IEmailGatewayConfig`.
69
+ *
70
+ * @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
71
+ */
72
+ export declare function loadGatewayConfig(): IEmailGatewayConfig;
73
+ //# sourceMappingURL=emailGatewayConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emailGatewayConfig.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/emailGatewayConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,yGAAyG;IACzG,eAAe,EAAE,MAAM,CAAC;IAExB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IAEpB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IAEpB,6GAA6G;IAC7G,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAE7C,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IAEpB,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IAErB,0GAA0G;IAC1G,iBAAiB,EAAE,MAAM,CAAC;IAE1B,2FAA2F;IAC3F,cAAc,EAAE,MAAM,CAAC;IAEvB,qFAAqF;IACrF,mBAAmB,EAAE,MAAM,CAAC;IAE5B,+FAA+F;IAC/F,mBAAmB,EAAE,MAAM,CAAC;IAE5B,kGAAkG;IAClG,8BAA8B,EAAE,MAAM,CAAC;IAEvC,oEAAoE;IACpE,UAAU,EAAE,cAAc,GAAG,QAAQ,CAAC;IAEtC,4GAA4G;IAC5G,cAAc,EAAE,eAAe,CAAC;IAEhC,4FAA4F;IAC5F,gBAAgB,EAAE,MAAM,CAAC;IAEzB,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC;IAEtB,6FAA6F;IAC7F,kBAAkB,EAAE,MAAM,CAAC;IAE3B,wGAAwG;IACxG,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAmED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CAuDvD"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ /**
3
+ * Email Gateway Configuration
4
+ *
5
+ * Defines the `IEmailGatewayConfig` interface and a `loadGatewayConfig()` loader
6
+ * that reads values from `CoreConstants.SiteEmailDomain` and environment variables
7
+ * with sensible defaults.
8
+ *
9
+ * All Node.js-specific gateway configuration lives here in brightchain-api-lib.
10
+ * The shared `ISpamThresholds` interface is imported from brightchain-lib.
11
+ *
12
+ * @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
13
+ * @module emailGatewayConfig
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.loadGatewayConfig = loadGatewayConfig;
17
+ const brightchain_lib_1 = require("@brightchain/brightchain-lib");
18
+ /** Default mail drop directory path */
19
+ const DEFAULT_MAIL_DROP_DIR = '/var/spool/brightchain/incoming/';
20
+ /** Default error directory path */
21
+ const DEFAULT_ERROR_DIR = '/var/spool/brightchain/errors/';
22
+ /** Default maximum message size: 25 MB */
23
+ const DEFAULT_MAX_MESSAGE_SIZE = 25 * 1024 * 1024;
24
+ /** Default recipient lookup port */
25
+ const DEFAULT_LOOKUP_PORT = 2526;
26
+ /** Default recipient lookup cache TTL in seconds */
27
+ const DEFAULT_LOOKUP_CACHE_TTL = 300;
28
+ /** Default queue concurrency */
29
+ const DEFAULT_QUEUE_CONCURRENCY = 10;
30
+ /** Default retry max count */
31
+ const DEFAULT_RETRY_MAX_COUNT = 5;
32
+ /** Default retry max duration: 48 hours in ms */
33
+ const DEFAULT_RETRY_MAX_DURATION = 48 * 60 * 60 * 1000;
34
+ /** Default retry base interval: 60 seconds in ms */
35
+ const DEFAULT_RETRY_BASE_INTERVAL = 60_000;
36
+ /** Default probable spam score threshold */
37
+ const DEFAULT_SPAM_PROBABLE = 5.0;
38
+ /** Default definite spam score threshold */
39
+ const DEFAULT_SPAM_DEFINITE = 10.0;
40
+ /**
41
+ * Parse an integer from an environment variable, returning a default if unset or invalid.
42
+ */
43
+ function envInt(name, defaultValue) {
44
+ const raw = process.env[name];
45
+ if (raw === undefined || raw === '') {
46
+ return defaultValue;
47
+ }
48
+ const parsed = parseInt(raw, 10);
49
+ return Number.isNaN(parsed) ? defaultValue : parsed;
50
+ }
51
+ /**
52
+ * Parse a float from an environment variable, returning a default if unset or invalid.
53
+ */
54
+ function envFloat(name, defaultValue) {
55
+ const raw = process.env[name];
56
+ if (raw === undefined || raw === '') {
57
+ return defaultValue;
58
+ }
59
+ const parsed = parseFloat(raw);
60
+ return Number.isNaN(parsed) ? defaultValue : parsed;
61
+ }
62
+ /**
63
+ * Read a string environment variable, returning a default if unset.
64
+ */
65
+ function envString(name, defaultValue) {
66
+ const raw = process.env[name];
67
+ return raw !== undefined && raw !== '' ? raw : defaultValue;
68
+ }
69
+ /**
70
+ * Load the Email Gateway configuration from `CoreConstants` and environment variables.
71
+ *
72
+ * Reads `CoreConstants.SiteEmailDomain` for the canonical domain (Req 8.1) and
73
+ * environment variables for all other settings, applying defaults where unset.
74
+ *
75
+ * @returns A fully populated `IEmailGatewayConfig`.
76
+ *
77
+ * @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
78
+ */
79
+ function loadGatewayConfig() {
80
+ const postfixUser = process.env['GATEWAY_POSTFIX_USER'];
81
+ const postfixPass = process.env['GATEWAY_POSTFIX_PASS'];
82
+ return {
83
+ canonicalDomain: brightchain_lib_1.CoreConstants.SiteEmailDomain,
84
+ postfixHost: envString('GATEWAY_POSTFIX_HOST', 'localhost'),
85
+ postfixPort: envInt('GATEWAY_POSTFIX_PORT', 25),
86
+ postfixAuth: postfixUser && postfixPass
87
+ ? { user: postfixUser, pass: postfixPass }
88
+ : undefined,
89
+ dkimKeyPath: envString('GATEWAY_DKIM_KEY_PATH', '/etc/dkim/private.key'),
90
+ dkimSelector: envString('GATEWAY_DKIM_SELECTOR', 'default'),
91
+ mailDropDirectory: envString('GATEWAY_MAIL_DROP_DIR', DEFAULT_MAIL_DROP_DIR),
92
+ errorDirectory: envString('GATEWAY_ERROR_DIR', DEFAULT_ERROR_DIR),
93
+ maxMessageSizeBytes: envInt('GATEWAY_MAX_MESSAGE_SIZE', DEFAULT_MAX_MESSAGE_SIZE),
94
+ recipientLookupPort: envInt('GATEWAY_LOOKUP_PORT', DEFAULT_LOOKUP_PORT),
95
+ recipientLookupCacheTtlSeconds: envInt('GATEWAY_LOOKUP_CACHE_TTL', DEFAULT_LOOKUP_CACHE_TTL),
96
+ spamEngine: envString('GATEWAY_SPAM_ENGINE', 'spamassassin'),
97
+ spamThresholds: {
98
+ probableSpamScore: envFloat('GATEWAY_SPAM_PROBABLE', DEFAULT_SPAM_PROBABLE),
99
+ definiteSpamScore: envFloat('GATEWAY_SPAM_DEFINITE', DEFAULT_SPAM_DEFINITE),
100
+ },
101
+ queueConcurrency: envInt('GATEWAY_QUEUE_CONCURRENCY', DEFAULT_QUEUE_CONCURRENCY),
102
+ retryMaxCount: envInt('GATEWAY_RETRY_MAX_COUNT', DEFAULT_RETRY_MAX_COUNT),
103
+ retryMaxDurationMs: envInt('GATEWAY_RETRY_MAX_DURATION', DEFAULT_RETRY_MAX_DURATION),
104
+ retryBaseIntervalMs: envInt('GATEWAY_RETRY_BASE_INTERVAL', DEFAULT_RETRY_BASE_INTERVAL),
105
+ };
106
+ }
107
+ //# sourceMappingURL=emailGatewayConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emailGatewayConfig.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/emailGatewayConfig.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * EmailGatewayService — orchestrator that bridges BrightChain's internal
3
+ * gossip-based messaging with external SMTP email delivery via Postfix.
4
+ *
5
+ * Responsibilities:
6
+ * - Listen for gossip announcements containing outbound email
7
+ * - Extract message blocks from the Block Store
8
+ * - Detect external recipients by comparing domain against canonicalDomain
9
+ * - Enqueue outbound messages for SMTP delivery
10
+ *
11
+ * @see Requirements 1.1, 1.2, 1.4
12
+ * @module emailGatewayService
13
+ */
14
+ import type { IBlockStore, IEmailMetadata, IGossipService } from '@brightchain/brightchain-lib';
15
+ import { EmailMessageService, OutboundDeliveryStatus } from '@brightchain/brightchain-lib';
16
+ import type { IEmailGatewayConfig } from './emailGatewayConfig';
17
+ /**
18
+ * Minimal interface for the outbound email queue.
19
+ *
20
+ * The full `OutboundQueue` class (task 4.2) will implement this.
21
+ * Using an interface here keeps the orchestrator decoupled from the
22
+ * queue's internal persistence and concurrency details.
23
+ */
24
+ export interface IOutboundQueue {
25
+ /**
26
+ * Add a message to the outbound delivery queue.
27
+ *
28
+ * @param message - Outbound message payload with recipient, content, and retry metadata
29
+ */
30
+ enqueue(message: IOutboundQueueItem): Promise<void>;
31
+ }
32
+ /**
33
+ * A single item placed on the outbound delivery queue.
34
+ */
35
+ export interface IOutboundQueueItem {
36
+ /** RFC 5322 Message-ID */
37
+ messageId: string;
38
+ /** Sender email address */
39
+ from: string;
40
+ /** External recipient email addresses */
41
+ to: string[];
42
+ /** Email subject */
43
+ subject?: string;
44
+ /** Full email metadata for serialization */
45
+ metadata: IEmailMetadata;
46
+ /** Timestamp when the item was enqueued */
47
+ enqueuedAt: Date;
48
+ /** Current delivery status */
49
+ status: OutboundDeliveryStatus;
50
+ /** Number of delivery attempts so far */
51
+ retryCount: number;
52
+ /** Earliest time at which the next delivery attempt should be made */
53
+ nextAttemptAt?: Date;
54
+ }
55
+ /**
56
+ * Orchestrator service for the Email Gateway.
57
+ *
58
+ * Listens for gossip announcements that carry outbound email, extracts the
59
+ * message content from the Block Store, identifies external recipients by
60
+ * comparing their domain against the configured `canonicalDomain`, and
61
+ * enqueues qualifying messages in the OutboundQueue for SMTP delivery.
62
+ *
63
+ * Lifecycle:
64
+ * - `start()` registers the gossip announcement listener
65
+ * - `stop()` removes the listener and performs cleanup
66
+ *
67
+ * @see Requirements 1.1, 1.2, 1.4
68
+ */
69
+ export declare class EmailGatewayService {
70
+ private readonly config;
71
+ private readonly gossipService;
72
+ private readonly blockStore;
73
+ private readonly emailMessageService;
74
+ private outboundQueue?;
75
+ /** Bound reference kept so we can unsubscribe on stop(). */
76
+ private readonly boundAnnouncementHandler;
77
+ /** Whether the service is currently running. */
78
+ private running;
79
+ /**
80
+ * @param config - Gateway configuration (canonical domain, limits, etc.)
81
+ * @param gossipService - Gossip protocol service for subscribing to announcements
82
+ * @param blockStore - Block store for retrieving message content blocks
83
+ * @param emailMessageService - Email message service for retrieving email metadata
84
+ * @param outboundQueue - Queue for outbound SMTP delivery (optional; set later via `setOutboundQueue`)
85
+ */
86
+ constructor(config: IEmailGatewayConfig, gossipService: IGossipService, blockStore: IBlockStore, emailMessageService: EmailMessageService, outboundQueue?: IOutboundQueue | undefined);
87
+ /**
88
+ * Start the gateway service.
89
+ *
90
+ * Registers a gossip announcement listener that intercepts outbound
91
+ * email announcements and delegates them to the outbound queue.
92
+ */
93
+ start(): void;
94
+ /**
95
+ * Stop the gateway service.
96
+ *
97
+ * Removes the gossip listener and marks the service as stopped.
98
+ */
99
+ stop(): void;
100
+ /**
101
+ * Whether the service is currently running.
102
+ */
103
+ isRunning(): boolean;
104
+ /**
105
+ * Wire the outbound queue after construction.
106
+ *
107
+ * Useful when the queue is created after the gateway service (e.g.
108
+ * during staged initialisation).
109
+ */
110
+ setOutboundQueue(queue: IOutboundQueue): void;
111
+ /**
112
+ * Determine whether an email address is external (not on the canonical domain).
113
+ *
114
+ * Extracts the domain portion of the address and compares it
115
+ * case-insensitively against `config.canonicalDomain`.
116
+ *
117
+ * @param emailAddress - A full email address (e.g. `alice@example.com`)
118
+ * @returns `true` when the address belongs to an external domain
119
+ *
120
+ * @see Requirement 1.1 — detect recipients whose domain ≠ canonical domain
121
+ */
122
+ isExternalRecipient(emailAddress: string): boolean;
123
+ /**
124
+ * Partition a list of email addresses into internal and external groups.
125
+ *
126
+ * @param addresses - Array of email addresses
127
+ * @returns Object with `internal` and `external` arrays
128
+ *
129
+ * @see Requirement 1.4 — mixed internal/external recipient handling
130
+ */
131
+ partitionRecipients(addresses: string[]): {
132
+ internal: string[];
133
+ external: string[];
134
+ };
135
+ /**
136
+ * Handle a gossip message-delivery announcement.
137
+ *
138
+ * When an announcement carries `messageDelivery` metadata the handler:
139
+ * 1. Retrieves the email metadata from the EmailMessageService
140
+ * 2. Identifies external recipients
141
+ * 3. Enqueues the message in the OutboundQueue for SMTP delivery
142
+ *
143
+ * Internal-only messages are ignored — they are already delivered via gossip.
144
+ *
145
+ * @param announcement - The gossip BlockAnnouncement with messageDelivery metadata
146
+ *
147
+ * @see Requirement 1.2 — extract message from Block Store and enqueue
148
+ * @see Requirement 1.4 — route external recipients to gateway
149
+ */
150
+ private handleAnnouncement;
151
+ }
152
+ //# sourceMappingURL=emailGatewayService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emailGatewayService.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/emailGatewayService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAEV,WAAW,EACX,cAAc,EACd,cAAc,EACf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAOhE;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAElB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IAEb,yCAAyC;IACzC,EAAE,EAAE,MAAM,EAAE,CAAC;IAEb,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,4CAA4C;IAC5C,QAAQ,EAAE,cAAc,CAAC;IAEzB,2CAA2C;IAC3C,UAAU,EAAE,IAAI,CAAC;IAEjB,8BAA8B;IAC9B,MAAM,EAAE,sBAAsB,CAAC;IAE/B,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IAEnB,sEAAsE;IACtE,aAAa,CAAC,EAAE,IAAI,CAAC;CACtB;AAID;;;;;;;;;;;;;GAaG;AACH,qBAAa,mBAAmB;IAiB5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,aAAa,CAAC;IApBxB,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAE/B;IAEV,gDAAgD;IAChD,OAAO,CAAC,OAAO,CAAS;IAExB;;;;;;OAMG;gBAEgB,MAAM,EAAE,mBAAmB,EAC3B,aAAa,EAAE,cAAc,EAC7B,UAAU,EAAE,WAAW,EACvB,mBAAmB,EAAE,mBAAmB,EACjD,aAAa,CAAC,EAAE,cAAc,YAAA;IAQxC;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAQb;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;;OAKG;IACH,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAM7C;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAUlD;;;;;;;OAOG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG;QACxC,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB;IAeD;;;;;;;;;;;;;;OAcG;YACW,kBAAkB;CAoDjC"}