@cosmicdrift/kumiko-bundled-features 0.392.2 → 0.394.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 (380) hide show
  1. package/dist/account-security/feature.d.ts +2 -0
  2. package/dist/account-security/feature.js +3 -1
  3. package/dist/audit/event-classification.js +1 -0
  4. package/dist/auth-email-password/handlers/change-password.write.d.ts +1 -1
  5. package/dist/auth-email-password/handlers/confirm-account-unlock.write.d.ts +1 -1
  6. package/dist/auth-email-password/handlers/invite-accept-with-login.write.d.ts +1 -1
  7. package/dist/auth-email-password/handlers/invite-accept.write.d.ts +1 -1
  8. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  9. package/dist/auth-email-password/handlers/invite-signup-complete.write.d.ts +1 -1
  10. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  11. package/dist/auth-email-password/handlers/logout.write.d.ts +1 -1
  12. package/dist/auth-email-password/handlers/request-account-unlock.write.d.ts +1 -1
  13. package/dist/auth-email-password/handlers/request-email-verification.write.d.ts +1 -1
  14. package/dist/auth-email-password/handlers/request-password-reset.write.d.ts +1 -1
  15. package/dist/auth-email-password/handlers/reset-password.write.d.ts +1 -1
  16. package/dist/auth-email-password/handlers/signup-confirm.write.d.ts +1 -1
  17. package/dist/auth-email-password/handlers/signup-request.write.d.ts +1 -1
  18. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  19. package/dist/auth-email-password/handlers/token-request-handler.d.ts +1 -1
  20. package/dist/auth-email-password/handlers/verify-email.write.d.ts +1 -1
  21. package/dist/auth-email-password/web/auth-client.d.ts +3 -7
  22. package/dist/auth-email-password/web/auth-client.js +3 -24
  23. package/dist/auth-email-password/web/auth-gate.d.ts +2 -4
  24. package/dist/auth-email-password/web/auth-redirect.d.ts +2 -2
  25. package/dist/auth-email-password/web/auth-redirect.js +3 -12
  26. package/dist/auth-email-password/web/index.d.ts +2 -1
  27. package/dist/auth-email-password/web/index.js +1 -0
  28. package/dist/auth-email-password/web/login-failure.d.ts +9 -0
  29. package/dist/auth-email-password/web/login-failure.js +32 -0
  30. package/dist/auth-email-password/web/login-url.d.ts +5 -0
  31. package/dist/auth-email-password/web/login-url.js +13 -0
  32. package/dist/auth-email-password/web/static-login.d.ts +42 -0
  33. package/dist/auth-email-password/web/static-login.js +122 -0
  34. package/dist/auth-mfa/handlers/disable.write.d.ts +1 -1
  35. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.d.ts +1 -1
  36. package/dist/auth-mfa/handlers/enable-confirm.write.d.ts +1 -1
  37. package/dist/auth-mfa/handlers/enable-start-preauth.write.d.ts +1 -1
  38. package/dist/auth-mfa/handlers/enable-start.write.d.ts +1 -1
  39. package/dist/auth-mfa/handlers/regenerate-recovery.write.d.ts +1 -1
  40. package/dist/auth-mfa/handlers/verify.write.d.ts +1 -1
  41. package/dist/auth-mfa/web/mfa-client.js +4 -43
  42. package/dist/billing-foundation/checkout-core.d.ts +2 -1
  43. package/dist/billing-foundation/checkout-core.js +2 -11
  44. package/dist/billing-foundation/events.d.ts +1 -0
  45. package/dist/billing-foundation/events.js +2 -0
  46. package/dist/billing-foundation/feature.js +1 -1
  47. package/dist/billing-foundation/handlers/create-checkout-session.write.js +9 -2
  48. package/dist/billing-foundation/handlers/process-payment-event.write.d.ts +1 -0
  49. package/dist/billing-foundation/handlers/process-payment-event.write.js +2 -0
  50. package/dist/billing-foundation/index.d.ts +1 -1
  51. package/dist/billing-foundation/one-off-checkout-gate.d.ts +9 -0
  52. package/dist/billing-foundation/one-off-checkout-gate.js +30 -0
  53. package/dist/billing-foundation/one-off-customer.d.ts +6 -0
  54. package/dist/billing-foundation/one-off-customer.js +12 -0
  55. package/dist/billing-foundation/plan-catalog.js +1 -0
  56. package/dist/billing-foundation/types.d.ts +25 -0
  57. package/dist/billing-foundation/web/billing-plans-panel.js +1 -0
  58. package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +7 -3
  59. package/dist/billing-foundation/web/plan-switch-recurring.d.ts +16 -0
  60. package/dist/billing-foundation/web/plan-switch-recurring.js +10 -0
  61. package/dist/billing-foundation/webhook-handler.js +1 -0
  62. package/dist/cap-overview/handlers/caps-usage.query.js +3 -3
  63. package/dist/cap-overview/types.d.ts +2 -0
  64. package/dist/channel-in-app/handlers/mark-all-read.write.d.ts +1 -1
  65. package/dist/channel-in-app/handlers/mark-read.write.d.ts +1 -1
  66. package/dist/compliance-profiles/handlers/set-profile.write.d.ts +1 -1
  67. package/dist/compliance-profiles/web/compliance-profile-catalog.js +8 -1
  68. package/dist/config/handlers/reset.write.d.ts +1 -1
  69. package/dist/config/handlers/set.write.d.ts +1 -1
  70. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +1 -1
  71. package/dist/delivery/handlers/resubscribe-address.write.d.ts +1 -1
  72. package/dist/delivery/handlers/resubscribe-user.write.d.ts +1 -1
  73. package/dist/delivery/handlers/set-preference.write.d.ts +1 -1
  74. package/dist/delivery/handlers/unsubscribe-address.write.d.ts +1 -1
  75. package/dist/delivery/handlers/unsubscribe-user.write.d.ts +1 -1
  76. package/dist/feature-toggles/handlers/set.write.d.ts +1 -1
  77. package/dist/file-foundation/read-file-ref-content.d.ts +2 -0
  78. package/dist/file-foundation/read-file-ref-content.js +9 -3
  79. package/dist/form-draft/handlers/discard.write.d.ts +1 -1
  80. package/dist/form-draft/handlers/save.write.d.ts +1 -1
  81. package/dist/inbound-mail-foundation/account-health.d.ts +17 -0
  82. package/dist/inbound-mail-foundation/account-health.js +101 -0
  83. package/dist/inbound-mail-foundation/account-poll-schedule.d.ts +19 -0
  84. package/dist/inbound-mail-foundation/account-poll-schedule.js +44 -0
  85. package/dist/inbound-mail-foundation/account-poll.d.ts +24 -0
  86. package/dist/inbound-mail-foundation/account-poll.js +157 -0
  87. package/dist/inbound-mail-foundation/account-record.d.ts +1 -0
  88. package/dist/inbound-mail-foundation/account-record.js +1 -0
  89. package/dist/inbound-mail-foundation/account-wake.d.ts +3 -0
  90. package/dist/inbound-mail-foundation/account-wake.js +17 -0
  91. package/dist/inbound-mail-foundation/connect-callback-verify.d.ts +10 -0
  92. package/dist/inbound-mail-foundation/connect-callback-verify.js +31 -0
  93. package/dist/inbound-mail-foundation/connect-route-responses.d.ts +13 -0
  94. package/dist/inbound-mail-foundation/connect-route-responses.js +16 -0
  95. package/dist/inbound-mail-foundation/connect-routes.js +52 -33
  96. package/dist/inbound-mail-foundation/constants.d.ts +50 -2
  97. package/dist/inbound-mail-foundation/constants.js +53 -3
  98. package/dist/inbound-mail-foundation/content-refetch.d.ts +14 -0
  99. package/dist/inbound-mail-foundation/content-refetch.js +93 -0
  100. package/dist/inbound-mail-foundation/describe-error.d.ts +1 -0
  101. package/dist/inbound-mail-foundation/describe-error.js +5 -0
  102. package/dist/inbound-mail-foundation/entities.d.ts +26 -0
  103. package/dist/inbound-mail-foundation/entities.js +43 -3
  104. package/dist/inbound-mail-foundation/events.d.ts +97 -0
  105. package/dist/inbound-mail-foundation/events.js +57 -2
  106. package/dist/inbound-mail-foundation/feature.d.ts +5 -2
  107. package/dist/inbound-mail-foundation/feature.js +122 -106
  108. package/dist/inbound-mail-foundation/file-storage-failure.d.ts +8 -0
  109. package/dist/inbound-mail-foundation/file-storage-failure.js +19 -0
  110. package/dist/inbound-mail-foundation/handlers/account-address.d.ts +16 -0
  111. package/dist/inbound-mail-foundation/handlers/account-address.js +51 -0
  112. package/dist/inbound-mail-foundation/handlers/acknowledge-quarantine.write.d.ts +8 -0
  113. package/dist/inbound-mail-foundation/handlers/acknowledge-quarantine.write.js +39 -0
  114. package/dist/inbound-mail-foundation/handlers/attach-message-content.write.d.ts +60 -0
  115. package/dist/inbound-mail-foundation/handlers/attach-message-content.write.js +128 -0
  116. package/dist/inbound-mail-foundation/handlers/connect-account.write.d.ts +3 -2
  117. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +97 -56
  118. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.d.ts +2 -1
  119. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +55 -42
  120. package/dist/inbound-mail-foundation/handlers/ingest-message-prepare.d.ts +26 -0
  121. package/dist/inbound-mail-foundation/handlers/ingest-message-prepare.js +131 -0
  122. package/dist/inbound-mail-foundation/handlers/ingest-message-schema.d.ts +64 -0
  123. package/dist/inbound-mail-foundation/handlers/ingest-message-schema.js +39 -0
  124. package/dist/inbound-mail-foundation/handlers/ingest-message.write.d.ts +74 -21
  125. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +57 -134
  126. package/dist/inbound-mail-foundation/handlers/list-accounts.query.d.ts +2 -1
  127. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +60 -26
  128. package/dist/inbound-mail-foundation/handlers/list-messages.query.d.ts +2 -1
  129. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +43 -29
  130. package/dist/inbound-mail-foundation/handlers/list-quarantine.query.d.ts +3 -0
  131. package/dist/inbound-mail-foundation/handlers/list-quarantine.query.js +75 -0
  132. package/dist/inbound-mail-foundation/handlers/mark-credential-stored.write.d.ts +7 -0
  133. package/dist/inbound-mail-foundation/handlers/mark-credential-stored.write.js +38 -0
  134. package/dist/inbound-mail-foundation/handlers/message-content.d.ts +70 -0
  135. package/dist/inbound-mail-foundation/handlers/message-content.js +137 -0
  136. package/dist/inbound-mail-foundation/handlers/message-content.query.d.ts +19 -0
  137. package/dist/inbound-mail-foundation/handlers/message-content.query.js +59 -0
  138. package/dist/inbound-mail-foundation/handlers/message-detail.query.d.ts +3 -0
  139. package/dist/inbound-mail-foundation/handlers/message-detail.query.js +23 -0
  140. package/dist/inbound-mail-foundation/handlers/reactivate-account.write.d.ts +8 -0
  141. package/dist/inbound-mail-foundation/handlers/reactivate-account.write.js +84 -0
  142. package/dist/inbound-mail-foundation/handlers/retry-quarantined-message.write.d.ts +8 -0
  143. package/dist/inbound-mail-foundation/handlers/retry-quarantined-message.write.js +34 -0
  144. package/dist/inbound-mail-foundation/handlers/scope-visibility.d.ts +10 -2
  145. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +27 -8
  146. package/dist/inbound-mail-foundation/handlers/set-trusted-authserv-id.write.d.ts +13 -0
  147. package/dist/inbound-mail-foundation/handlers/set-trusted-authserv-id.write.js +54 -0
  148. package/dist/inbound-mail-foundation/handlers/thread-rollup.d.ts +24 -0
  149. package/dist/inbound-mail-foundation/handlers/thread-rollup.js +98 -0
  150. package/dist/inbound-mail-foundation/handlers/trusted-authserv-id.d.ts +3 -0
  151. package/dist/inbound-mail-foundation/handlers/trusted-authserv-id.js +3 -0
  152. package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +13 -3
  153. package/dist/inbound-mail-foundation/handlers/update-account.write.js +62 -46
  154. package/dist/inbound-mail-foundation/i18n.js +72 -2
  155. package/dist/inbound-mail-foundation/inbound-oauth-flow.d.ts +43 -0
  156. package/dist/inbound-mail-foundation/inbound-oauth-flow.js +1 -0
  157. package/dist/inbound-mail-foundation/index.d.ts +19 -6
  158. package/dist/inbound-mail-foundation/index.js +17 -6
  159. package/dist/inbound-mail-foundation/ingest-failures.d.ts +77 -0
  160. package/dist/inbound-mail-foundation/ingest-failures.js +79 -0
  161. package/dist/inbound-mail-foundation/ingest-payload.d.ts +7 -0
  162. package/dist/inbound-mail-foundation/ingest-payload.js +34 -0
  163. package/dist/inbound-mail-foundation/mail-roles.d.ts +21 -0
  164. package/dist/inbound-mail-foundation/mail-roles.js +83 -0
  165. package/dist/inbound-mail-foundation/normalize-inbound-message.d.ts +17 -0
  166. package/dist/inbound-mail-foundation/normalize-inbound-message.js +90 -0
  167. package/dist/inbound-mail-foundation/oauth-access-token.d.ts +3 -1
  168. package/dist/inbound-mail-foundation/oauth-access-token.js +13 -2
  169. package/dist/inbound-mail-foundation/outbound-attachment-access.d.ts +5 -0
  170. package/dist/inbound-mail-foundation/outbound-attachment-access.js +16 -0
  171. package/dist/inbound-mail-foundation/outbound-attachments.d.ts +18 -0
  172. package/dist/inbound-mail-foundation/outbound-attachments.js +77 -0
  173. package/dist/inbound-mail-foundation/outbound-mail.d.ts +15 -1
  174. package/dist/inbound-mail-foundation/outbound-mail.js +4 -0
  175. package/dist/inbound-mail-foundation/probe.js +1 -1
  176. package/dist/inbound-mail-foundation/projection.d.ts +28 -0
  177. package/dist/inbound-mail-foundation/projection.js +25 -3
  178. package/dist/inbound-mail-foundation/provider-errors.d.ts +28 -0
  179. package/dist/inbound-mail-foundation/provider-errors.js +66 -0
  180. package/dist/inbound-mail-foundation/quarantine-entities.d.ts +61 -0
  181. package/dist/inbound-mail-foundation/quarantine-entities.js +47 -0
  182. package/dist/inbound-mail-foundation/quarantine-header-import.d.ts +9 -0
  183. package/dist/inbound-mail-foundation/quarantine-header-import.js +53 -0
  184. package/dist/inbound-mail-foundation/quarantine-retry.d.ts +13 -0
  185. package/dist/inbound-mail-foundation/quarantine-retry.js +97 -0
  186. package/dist/inbound-mail-foundation/quarantine-screens.d.ts +4 -0
  187. package/dist/inbound-mail-foundation/quarantine-screens.js +57 -0
  188. package/dist/inbound-mail-foundation/quarantine.d.ts +13 -0
  189. package/dist/inbound-mail-foundation/quarantine.js +46 -0
  190. package/dist/inbound-mail-foundation/retention-job.d.ts +2 -0
  191. package/dist/inbound-mail-foundation/retention-job.js +62 -0
  192. package/dist/inbound-mail-foundation/retention-sweep.d.ts +4 -0
  193. package/dist/inbound-mail-foundation/retention-sweep.js +35 -8
  194. package/dist/inbound-mail-foundation/screens.d.ts +14 -2
  195. package/dist/inbound-mail-foundation/screens.js +217 -79
  196. package/dist/inbound-mail-foundation/send-from-account.d.ts +11 -1
  197. package/dist/inbound-mail-foundation/send-from-account.js +19 -2
  198. package/dist/inbound-mail-foundation/sender-auth.d.ts +63 -0
  199. package/dist/inbound-mail-foundation/sender-auth.js +198 -0
  200. package/dist/inbound-mail-foundation/supervisor-ingest.d.ts +43 -0
  201. package/dist/inbound-mail-foundation/supervisor-ingest.js +195 -0
  202. package/dist/inbound-mail-foundation/sync-account-now.d.ts +22 -0
  203. package/dist/inbound-mail-foundation/sync-account-now.js +29 -0
  204. package/dist/inbound-mail-foundation/sync-cursor-store.d.ts +9 -0
  205. package/dist/inbound-mail-foundation/sync-cursor-store.js +54 -0
  206. package/dist/inbound-mail-foundation/syncable-accounts.d.ts +16 -0
  207. package/dist/inbound-mail-foundation/syncable-accounts.js +79 -0
  208. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +5 -1
  209. package/dist/inbound-mail-foundation/types.d.ts +61 -62
  210. package/dist/inbound-mail-foundation/types.js +0 -54
  211. package/dist/inbound-mail-foundation/wake-consumer.d.ts +2 -0
  212. package/dist/inbound-mail-foundation/wake-consumer.js +30 -0
  213. package/dist/inbound-mail-foundation/watch-catch-up.d.ts +19 -0
  214. package/dist/inbound-mail-foundation/watch-catch-up.js +33 -0
  215. package/dist/inbound-mail-foundation/watch-lease.d.ts +15 -0
  216. package/dist/inbound-mail-foundation/watch-lease.js +81 -0
  217. package/dist/inbound-mail-foundation/watch-supervisor-types.d.ts +83 -0
  218. package/dist/inbound-mail-foundation/watch-supervisor-types.js +1 -0
  219. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +1 -53
  220. package/dist/inbound-mail-foundation/watch-supervisor.js +123 -290
  221. package/dist/inbound-mail-foundation/web/client-plugin.d.ts +14 -0
  222. package/dist/inbound-mail-foundation/web/client-plugin.js +40 -0
  223. package/dist/inbound-mail-foundation/web/constants.d.ts +5 -0
  224. package/dist/inbound-mail-foundation/web/constants.js +6 -0
  225. package/dist/inbound-mail-foundation/web/index.d.ts +1 -0
  226. package/dist/inbound-mail-foundation/web/index.js +1 -0
  227. package/dist/inbound-provider-imap/connect-mailbox.d.ts +28 -5
  228. package/dist/inbound-provider-imap/connect-mailbox.js +91 -41
  229. package/dist/inbound-provider-imap/connect-my-mailbox.d.ts +13 -0
  230. package/dist/inbound-provider-imap/connect-my-mailbox.js +25 -0
  231. package/dist/inbound-provider-imap/constants.d.ts +12 -1
  232. package/dist/inbound-provider-imap/constants.js +12 -1
  233. package/dist/inbound-provider-imap/credential-document.js +2 -2
  234. package/dist/inbound-provider-imap/download-batch.d.ts +6 -0
  235. package/dist/inbound-provider-imap/download-batch.js +24 -0
  236. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  237. package/dist/inbound-provider-imap/feature.js +49 -32
  238. package/dist/inbound-provider-imap/fetch-content.d.ts +4 -0
  239. package/dist/inbound-provider-imap/fetch-content.js +68 -0
  240. package/dist/inbound-provider-imap/i18n.js +18 -2
  241. package/dist/inbound-provider-imap/imap-client.d.ts +27 -23
  242. package/dist/inbound-provider-imap/imap-client.js +30 -68
  243. package/dist/inbound-provider-imap/index.d.ts +2 -1
  244. package/dist/inbound-provider-imap/index.js +2 -1
  245. package/dist/inbound-provider-imap/mime-content.d.ts +11 -0
  246. package/dist/inbound-provider-imap/mime-content.js +66 -0
  247. package/dist/inbound-provider-imap/parse-message.d.ts +35 -0
  248. package/dist/inbound-provider-imap/parse-message.js +113 -0
  249. package/dist/inbound-provider-imap/reconnect-account.d.ts +17 -0
  250. package/dist/inbound-provider-imap/reconnect-account.js +18 -0
  251. package/dist/inbound-provider-imap/reconnect-mailbox.d.ts +14 -0
  252. package/dist/inbound-provider-imap/reconnect-mailbox.js +71 -0
  253. package/dist/inbound-provider-imap/reconnect-prefill.query.d.ts +3 -0
  254. package/dist/inbound-provider-imap/reconnect-prefill.query.js +34 -0
  255. package/dist/inbound-provider-imap/screens.d.ts +6 -1
  256. package/dist/inbound-provider-imap/screens.js +174 -41
  257. package/dist/inbound-provider-imap/send-mail.d.ts +2 -2
  258. package/dist/inbound-provider-imap/send-mail.js +8 -1
  259. package/dist/inbound-provider-imap/sender-auth-headers.d.ts +3 -0
  260. package/dist/inbound-provider-imap/sender-auth-headers.js +18 -0
  261. package/dist/inbound-provider-inmemory/feature.d.ts +15 -0
  262. package/dist/inbound-provider-inmemory/feature.js +57 -2
  263. package/dist/inbound-provider-inmemory/index.d.ts +1 -1
  264. package/dist/inbound-provider-inmemory/index.js +1 -1
  265. package/dist/jobs/handlers/consumer.write.d.ts +4 -4
  266. package/dist/jobs/handlers/retry.write.d.ts +1 -1
  267. package/dist/jobs/handlers/trigger.write.d.ts +1 -1
  268. package/dist/managed-pages/handlers/set.write.d.ts +1 -1
  269. package/dist/managed-pages/web/i18n.js +1 -0
  270. package/dist/personal-access-tokens/handlers/create.write.d.ts +1 -1
  271. package/dist/personal-access-tokens/handlers/revoke.write.d.ts +1 -1
  272. package/dist/readiness/handlers/run-probes.write.d.ts +1 -1
  273. package/dist/secrets/handlers/delete.write.d.ts +1 -1
  274. package/dist/secrets/handlers/set.write.d.ts +1 -1
  275. package/dist/sessions/handlers/revoke-all-for-user.write.d.ts +1 -1
  276. package/dist/sessions/handlers/revoke-all-others.write.d.ts +1 -1
  277. package/dist/sessions/handlers/revoke.write.d.ts +1 -1
  278. package/dist/subscription-paddle/checkout-config.query.d.ts +3 -0
  279. package/dist/subscription-paddle/checkout-config.query.js +14 -0
  280. package/dist/subscription-paddle/checkout-methods.d.ts +6 -0
  281. package/dist/subscription-paddle/checkout-methods.js +85 -0
  282. package/dist/subscription-paddle/checkout-page.d.ts +19 -0
  283. package/dist/subscription-paddle/checkout-page.js +126 -0
  284. package/dist/subscription-paddle/client.d.ts +24 -0
  285. package/dist/subscription-paddle/client.js +60 -0
  286. package/dist/subscription-paddle/constants.d.ts +16 -0
  287. package/dist/subscription-paddle/constants.js +25 -0
  288. package/dist/subscription-paddle/feature.d.ts +49 -0
  289. package/dist/subscription-paddle/feature.js +192 -0
  290. package/dist/subscription-paddle/index.d.ts +2 -0
  291. package/dist/subscription-paddle/index.js +4 -0
  292. package/dist/subscription-paddle/plan-switch-methods.d.ts +6 -0
  293. package/dist/subscription-paddle/plan-switch-methods.js +114 -0
  294. package/dist/subscription-paddle/price-methods.d.ts +15 -0
  295. package/dist/subscription-paddle/price-methods.js +105 -0
  296. package/dist/subscription-paddle/runtime.d.ts +42 -0
  297. package/dist/subscription-paddle/runtime.js +109 -0
  298. package/dist/subscription-paddle/subscription-state.d.ts +34 -0
  299. package/dist/subscription-paddle/subscription-state.js +48 -0
  300. package/dist/subscription-paddle/tenant-binding.d.ts +8 -0
  301. package/dist/subscription-paddle/tenant-binding.js +26 -0
  302. package/dist/subscription-paddle/verify-webhook.d.ts +4 -0
  303. package/dist/subscription-paddle/verify-webhook.js +55 -0
  304. package/dist/subscription-paddle/webhook-events.d.ts +9 -0
  305. package/dist/subscription-paddle/webhook-events.js +124 -0
  306. package/dist/template-resolver/handlers/collection-item.query.js +2 -2
  307. package/dist/template-resolver/handlers/collection-list.query.js +4 -2
  308. package/dist/template-resolver/handlers/collection-set.write.d.ts +1 -1
  309. package/dist/template-resolver/handlers/collection-shared.d.ts +11 -0
  310. package/dist/template-resolver/handlers/collection-shared.js +16 -0
  311. package/dist/template-resolver/handlers/copy-locale.write.d.ts +1 -1
  312. package/dist/template-resolver/handlers/discard-draft.write.d.ts +2 -2
  313. package/dist/template-resolver/handlers/import-bundle-system.write.d.ts +1 -1
  314. package/dist/template-resolver/handlers/import-bundle.write.d.ts +1 -1
  315. package/dist/template-resolver/handlers/patch-draft.write.d.ts +1 -1
  316. package/dist/template-resolver/handlers/reset-to-system.write.d.ts +1 -1
  317. package/dist/template-resolver/handlers/resource-link-pdf.write.d.ts +1 -1
  318. package/dist/template-resolver/handlers/resource-remove.write.d.ts +1 -1
  319. package/dist/template-resolver/handlers/resource-upload.write.d.ts +1 -1
  320. package/dist/template-resolver/handlers/send-test.write.d.ts +1 -1
  321. package/dist/template-resolver/handlers/set.write.d.ts +1 -1
  322. package/dist/template-resolver/handlers/toggle-status.write.d.ts +4 -4
  323. package/dist/template-resolver/handlers/upsert-system.write.d.ts +1 -1
  324. package/dist/template-resolver/handlers/upsert-tenant.write.d.ts +1 -1
  325. package/dist/template-resolver/web/client-plugin.d.ts +4 -0
  326. package/dist/template-resolver/web/client-plugin.js +134 -52
  327. package/dist/template-resolver/web/i18n.js +1 -1
  328. package/dist/tenant/handlers/add-member.write.d.ts +1 -1
  329. package/dist/tenant/handlers/cancel-invitation.write.d.ts +1 -1
  330. package/dist/tenant/handlers/create.write.d.ts +1 -1
  331. package/dist/tenant/handlers/remove-member.write.d.ts +1 -1
  332. package/dist/tenant/handlers/toggle-enabled.write.d.ts +2 -2
  333. package/dist/tenant/handlers/update-member-roles.write.d.ts +1 -1
  334. package/dist/tenant/handlers/update.write.d.ts +1 -1
  335. package/dist/tenant-handover/handlers/claim.write.d.ts +1 -1
  336. package/dist/tenant-lifecycle/handlers/cancel-destruction.write.d.ts +1 -1
  337. package/dist/tenant-lifecycle/handlers/request-destruction.write.d.ts +1 -1
  338. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +1 -1
  339. package/dist/user/handlers/create.write.d.ts +1 -1
  340. package/dist/user/handlers/update.write.d.ts +1 -1
  341. package/dist/user-data-rights/handlers/cancel-deletion.write.d.ts +1 -1
  342. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.d.ts +1 -1
  343. package/dist/user-data-rights/handlers/lift-restriction.write.d.ts +1 -1
  344. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +1 -1
  345. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +1 -1
  346. package/dist/user-data-rights/handlers/request-export.write.d.ts +1 -1
  347. package/dist/user-data-rights/handlers/restrict-account.write.d.ts +1 -1
  348. package/dist/user-data-rights/handlers/run-forget-cleanup.write.d.ts +1 -1
  349. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +2 -1
  350. package/dist/user-profile/handlers/change-email.write.d.ts +1 -1
  351. package/dist/waitlist/handlers/export-purge.write.d.ts +2 -2
  352. package/dist/waitlist/handlers/invite.write.d.ts +1 -1
  353. package/dist/waitlist/handlers/reject.write.d.ts +1 -1
  354. package/dist/waitlist/handlers/submit.write.d.ts +1 -1
  355. package/package.json +33 -17
  356. package/src/account-security/changes.json +6 -0
  357. package/src/auth-email-password/changes.json +6 -0
  358. package/src/billing-foundation/changes.json +30 -0
  359. package/src/cap-overview/changes.json +6 -0
  360. package/src/files/changes.json +18 -0
  361. package/src/inbound-mail-foundation/changes.json +155 -0
  362. package/src/inbound-provider-imap/changes.json +42 -0
  363. package/src/jobs/changes.json +18 -0
  364. package/src/subscription-paddle/changes.json +15 -0
  365. package/src/template-resolver/changes.json +12 -0
  366. package/dist/subscription-dodo/client.d.ts +0 -17
  367. package/dist/subscription-dodo/client.js +0 -31
  368. package/dist/subscription-dodo/constants.d.ts +0 -12
  369. package/dist/subscription-dodo/constants.js +0 -19
  370. package/dist/subscription-dodo/feature.d.ts +0 -37
  371. package/dist/subscription-dodo/feature.js +0 -144
  372. package/dist/subscription-dodo/index.d.ts +0 -2
  373. package/dist/subscription-dodo/index.js +0 -4
  374. package/dist/subscription-dodo/plugin-methods.d.ts +0 -23
  375. package/dist/subscription-dodo/plugin-methods.js +0 -260
  376. package/dist/subscription-dodo/runtime.d.ts +0 -27
  377. package/dist/subscription-dodo/runtime.js +0 -89
  378. package/dist/subscription-dodo/verify-webhook.d.ts +0 -37
  379. package/dist/subscription-dodo/verify-webhook.js +0 -189
  380. package/src/subscription-dodo/changes.json +0 -14
@@ -0,0 +1,53 @@
1
+ // A quarantined mail stays visible: its headers (and the original, when file storage is there) are
2
+ // imported as a message without content, marked "unavailable / quarantined". The import is best
3
+ // effort: the quarantine row already moves the cursor on, and a retry can still load the content.
4
+ import { InboundMailFoundationHandlers } from "./constants.js";
5
+ import { ingestPayloadOf } from "./ingest-payload.js";
6
+ import { INBOUND_MISSING_SENDER, normalizeRawInboundMessage } from "./normalize-inbound-message.js";
7
+ const EPOCH_ISO = "1970-01-01T00:00:00Z";
8
+ export function headerOnlyOf(msg) {
9
+ const { text: _text, html: _html, attachments: _a, skippedAttachments: _s, ...envelope } = msg;
10
+ return { ...envelope, text: "", html: null, attachments: [], skippedAttachments: [] };
11
+ }
12
+ /** Null when the provider reported no headers for the mail: nothing meaningful to show. */
13
+ export function headerOnlyOfRejected(entry) {
14
+ const { headers } = entry;
15
+ if (!headers)
16
+ return null;
17
+ return {
18
+ providerMessageId: entry.providerMessageId,
19
+ messageIdHeader: headers.messageIdHeader,
20
+ providerThreadId: null,
21
+ references: [],
22
+ from: headers.from === "" ? INBOUND_MISSING_SENDER : headers.from,
23
+ to: headers.to,
24
+ cc: headers.cc,
25
+ subject: headers.subject,
26
+ snippet: "",
27
+ receivedAtIso: headers.receivedAtIso === "" ? EPOCH_ISO : headers.receivedAtIso,
28
+ rawMime: entry.rawMime ?? null,
29
+ scope: "inbox",
30
+ };
31
+ }
32
+ export async function importQuarantinedHeaders(deps, account, headerOnly) {
33
+ // skip: no header data to import for this mail
34
+ if (!headerOnly)
35
+ return;
36
+ try {
37
+ const result = await deps.dispatchWrite({
38
+ handlerQn: InboundMailFoundationHandlers.ingestMessage,
39
+ tenantId: account.tenantId,
40
+ payload: ingestPayloadOf(account, normalizeRawInboundMessage(headerOnly), {
41
+ providerCursor: "quarantine",
42
+ bodyRef: "",
43
+ contentUnavailableReason: "quarantined",
44
+ }),
45
+ });
46
+ if (!result.isSuccess) {
47
+ deps.log(`inbound-mail: account ${account.id} header import of a quarantined mail was rejected`);
48
+ }
49
+ }
50
+ catch {
51
+ deps.log(`inbound-mail: account ${account.id} header import of a quarantined mail failed`);
52
+ }
53
+ }
@@ -0,0 +1,13 @@
1
+ import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
+ import type { DispatchWrite } from "./supervisor-ingest.ts";
3
+ import type { InboundMailContext, InboundMailProviderPlugin, MailAccountRecord } from "./types.ts";
4
+ export declare function retryQuarantinedMessages(args: {
5
+ readonly db: DbConnection;
6
+ readonly dispatchWrite: DispatchWrite;
7
+ readonly providerCtx: InboundMailContext;
8
+ readonly account: MailAccountRecord;
9
+ readonly plugin: InboundMailProviderPlugin;
10
+ readonly accessToken?: string | undefined;
11
+ readonly signal?: AbortSignal | undefined;
12
+ readonly log: (line: string) => void;
13
+ }): Promise<void>;
@@ -0,0 +1,97 @@
1
+ // Quarantine retry: mails flagged by retry-quarantined-message are loaded from the provider again
2
+ // after a successful sync. A mail that now goes through leaves the quarantine; one that fails again
3
+ // stays in it (flag reset, so it is not retried on every tick). An outage (provider, KMS, file
4
+ // storage) is not the mail's failure: the flag stays and the retry runs after the recovery.
5
+ import { ENCRYPTION_UNAVAILABLE_CODE } from "@cosmicdrift/kumiko-framework/crypto";
6
+ import { deleteMany, selectMany, updateMany } from "@cosmicdrift/kumiko-framework/db";
7
+ import { errorCodeOf } from "@cosmicdrift/kumiko-types/type-guards";
8
+ import { inboundMessageAggregateId } from "./aggregate-id.js";
9
+ import { InboundMailFoundationHandlers } from "./constants.js";
10
+ import { describeError } from "./describe-error.js";
11
+ import { isFileStorageWriteFailure } from "./file-storage-failure.js";
12
+ import { clearIngestFailures } from "./ingest-failures.js";
13
+ import { ingestPayloadOf } from "./ingest-payload.js";
14
+ import { normalizeRawInboundMessage, } from "./normalize-inbound-message.js";
15
+ import { inboundMessagesProjectionTable } from "./projection.js";
16
+ import { quarantineTable } from "./quarantine-entities.js";
17
+ const RETRY_BUDGET_PER_TICK = 20;
18
+ function isOutageFailure(error) {
19
+ return isFileStorageWriteFailure(error) || errorCodeOf(error) === ENCRYPTION_UNAVAILABLE_CODE;
20
+ }
21
+ // A mail with a header-only entry gets its content attached, one without any entry is ingested in full.
22
+ function reloadMessage(dispatchWrite, account, msg, hasHeaderRow) {
23
+ return hasHeaderRow
24
+ ? dispatchWrite({
25
+ handlerQn: InboundMailFoundationHandlers.attachMessageContent,
26
+ tenantId: account.tenantId,
27
+ payload: {
28
+ accountId: account.id,
29
+ providerMessageId: msg.providerMessageId,
30
+ outcome: "fetched",
31
+ bodyText: msg.bodyText,
32
+ bodyTextTruncated: msg.bodyTextTruncated,
33
+ ...(msg.rawMime != null && { rawMime: msg.rawMime }),
34
+ ...(msg.bodyHtml !== null && { bodyHtml: msg.bodyHtml }),
35
+ attachments: msg.attachments,
36
+ skippedAttachments: msg.skippedAttachments,
37
+ },
38
+ })
39
+ : dispatchWrite({
40
+ handlerQn: InboundMailFoundationHandlers.ingestMessage,
41
+ tenantId: account.tenantId,
42
+ payload: ingestPayloadOf(account, msg, {
43
+ providerCursor: "quarantine-retry",
44
+ bodyRef: "",
45
+ }),
46
+ });
47
+ }
48
+ export async function retryQuarantinedMessages(args) {
49
+ const { db, account, plugin, dispatchWrite, log } = args;
50
+ // skip: the provider cannot reload single mails.
51
+ if (!plugin.fetchContent)
52
+ return;
53
+ const requested = await selectMany(db, quarantineTable, { accountId: account.id, retryRequestedAt: { ne: null } }, { fields: ["providerMessageId"], limit: RETRY_BUDGET_PER_TICK });
54
+ // skip: nothing was asked for.
55
+ if (requested.length === 0)
56
+ return;
57
+ const ids = requested.map((row) => row.providerMessageId);
58
+ const done = new Set();
59
+ const held = new Set();
60
+ try {
61
+ const result = await plugin.fetchContent(args.providerCtx, account, ids, {
62
+ ...(args.accessToken !== undefined && { accessToken: args.accessToken }),
63
+ ...(args.signal !== undefined && { signal: args.signal }),
64
+ });
65
+ const existing = new Set((await selectMany(db, inboundMessagesProjectionTable, {
66
+ tenantId: account.tenantId,
67
+ id: { in: ids.map((id) => inboundMessageAggregateId(account.id, id)) },
68
+ }, { fields: ["id"] })).map((row) => row.id));
69
+ for (const raw of result.messages) {
70
+ const msg = normalizeRawInboundMessage(raw);
71
+ const hasHeaderRow = existing.has(inboundMessageAggregateId(account.id, msg.providerMessageId));
72
+ const outcome = await reloadMessage(dispatchWrite, account, msg, hasHeaderRow);
73
+ if (outcome.isSuccess)
74
+ done.add(msg.providerMessageId);
75
+ else if (isOutageFailure(outcome.error))
76
+ held.add(msg.providerMessageId);
77
+ }
78
+ }
79
+ catch (err) {
80
+ log(`inbound-mail: account ${account.id} quarantine retry failed: ${describeError(err)}`);
81
+ for (const id of ids)
82
+ held.add(id);
83
+ }
84
+ const doneIds = [...done];
85
+ if (doneIds.length > 0) {
86
+ await deleteMany(db, quarantineTable, {
87
+ accountId: account.id,
88
+ providerMessageId: { in: doneIds },
89
+ });
90
+ await clearIngestFailures(db, account.id, doneIds);
91
+ }
92
+ const failed = ids.filter((id) => !done.has(id) && !held.has(id));
93
+ if (failed.length > 0) {
94
+ await updateMany(db, quarantineTable, { retryRequestedAt: null }, { accountId: account.id, providerMessageId: { in: failed } });
95
+ log(`inbound-mail: account ${account.id} ${failed.length} quarantined mail(s) still failing`);
96
+ }
97
+ }
@@ -0,0 +1,4 @@
1
+ import { type ProjectionListScreenDefinition } from "@cosmicdrift/kumiko-framework/engine";
2
+ import type { InboundMailRoles } from "./mail-roles.ts";
3
+ export declare const QUARANTINE_REASON_OPTION_KEY_PREFIX = "inboundMail.quarantine.reason.";
4
+ export declare function createMailQuarantineScreen({ memberRoles, }: InboundMailRoles): ProjectionListScreenDefinition;
@@ -0,0 +1,57 @@
1
+ import { i18nKey, MAX_LIST_LIMIT, } from "@cosmicdrift/kumiko-framework/engine";
2
+ import { InboundMailFoundationHandlers, InboundMailFoundationQueries } from "./constants.js";
3
+ import { MAIL_QUARANTINE_SCREEN_ID } from "./screens.js";
4
+ export const QUARANTINE_REASON_OPTION_KEY_PREFIX = "inboundMail.quarantine.reason.";
5
+ // Same roles as the handlers; the bound query shows each caller only the mailboxes they may manage.
6
+ // dormant: reached through the row action "Quarantine" of the mailbox list.
7
+ export function createMailQuarantineScreen({ memberRoles, }) {
8
+ return {
9
+ id: MAIL_QUARANTINE_SCREEN_ID,
10
+ type: "projectionList",
11
+ agent: { expose: false },
12
+ query: InboundMailFoundationQueries.listQuarantine,
13
+ pagination: false,
14
+ pageSize: MAX_LIST_LIMIT,
15
+ columns: [
16
+ { field: "sender", label: i18nKey("inboundMail.quarantine.col.sender"), sortable: false },
17
+ { field: "subject", label: i18nKey("inboundMail.quarantine.col.subject"), sortable: false },
18
+ {
19
+ field: "reason",
20
+ label: i18nKey("inboundMail.quarantine.col.reason"),
21
+ sortable: false,
22
+ renderer: { format: "enumOption", keyPrefix: QUARANTINE_REASON_OPTION_KEY_PREFIX },
23
+ },
24
+ {
25
+ field: "accountName",
26
+ label: i18nKey("inboundMail.quarantine.col.mailbox"),
27
+ sortable: false,
28
+ hideOnNarrow: true,
29
+ },
30
+ {
31
+ field: "quarantinedAt",
32
+ label: i18nKey("inboundMail.quarantine.col.date"),
33
+ sortable: false,
34
+ renderer: { format: "timestamp" },
35
+ },
36
+ ],
37
+ rowActions: [
38
+ {
39
+ kind: "writeHandler",
40
+ id: "retry",
41
+ label: i18nKey("inboundMail.quarantine.retry"),
42
+ handler: InboundMailFoundationHandlers.retryQuarantinedMessage,
43
+ payload: { map: { accountId: "accountId", providerMessageId: "providerMessageId" } },
44
+ visible: { field: "retryRequestedAt", eq: null },
45
+ },
46
+ {
47
+ kind: "writeHandler",
48
+ id: "acknowledge",
49
+ label: i18nKey("inboundMail.quarantine.acknowledge"),
50
+ handler: InboundMailFoundationHandlers.acknowledgeQuarantine,
51
+ payload: { map: { accountId: "accountId", providerMessageId: "providerMessageId" } },
52
+ },
53
+ ],
54
+ access: { roles: [...memberRoles] },
55
+ dormant: true,
56
+ };
57
+ }
@@ -0,0 +1,13 @@
1
+ import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
2
+ import { type QuarantineReasonCode } from "./quarantine-entities.ts";
3
+ export declare const QUARANTINE_ACKNOWLEDGED_RETENTION_DAYS = 90;
4
+ type QuarantineTarget = {
5
+ readonly tenantId: string;
6
+ readonly accountId: string;
7
+ readonly providerMessageId: string;
8
+ };
9
+ /** Returns true when a new row was written, false when the message was already quarantined. */
10
+ export declare function quarantineMessage(db: DbConnection, target: QuarantineTarget, reasonCode: QuarantineReasonCode): Promise<boolean>;
11
+ export declare function quarantinedMessageIds(db: DbConnection, accountId: string, providerMessageIds: readonly string[]): Promise<ReadonlySet<string>>;
12
+ export declare function hasOpenQuarantine(db: DbConnection, accountId: string): Promise<boolean>;
13
+ export {};
@@ -0,0 +1,46 @@
1
+ // Quarantine of poison mails: messages the supervisor cannot ingest (unparseable MIME, payload the
2
+ // ingest handler rejects for good, or repeated hard failures). A quarantined id counts as seen, so the
3
+ // cursor moves on instead of retrying the same mail forever. Rows carry ids only, no mail content.
4
+ import { fetchOne, insertOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
5
+ import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
6
+ import { quarantineTable } from "./quarantine-entities.js";
7
+ const LOOKUP_CHUNK_SIZE = 1000;
8
+ export const QUARANTINE_ACKNOWLEDGED_RETENTION_DAYS = 90;
9
+ /** Returns true when a new row was written, false when the message was already quarantined. */
10
+ export async function quarantineMessage(db, target, reasonCode) {
11
+ const key = { accountId: target.accountId, providerMessageId: target.providerMessageId };
12
+ if (await fetchOne(db, quarantineTable, key))
13
+ return false;
14
+ try {
15
+ await insertOne(db, quarantineTable, {
16
+ id: crypto.randomUUID(),
17
+ tenantId: target.tenantId,
18
+ ...key,
19
+ reasonCode,
20
+ quarantinedAt: Temporal.Now.instant().toString(),
21
+ });
22
+ return true;
23
+ }
24
+ catch (err) {
25
+ // A concurrent worker quarantined the same message between the check and the insert.
26
+ if (await fetchOne(db, quarantineTable, key))
27
+ return false;
28
+ throw err;
29
+ }
30
+ }
31
+ export async function quarantinedMessageIds(db, accountId, providerMessageIds) {
32
+ const ids = new Set();
33
+ for (let start = 0; start < providerMessageIds.length; start += LOOKUP_CHUNK_SIZE) {
34
+ const rows = await selectMany(db, quarantineTable, {
35
+ accountId,
36
+ providerMessageId: { in: providerMessageIds.slice(start, start + LOOKUP_CHUNK_SIZE) },
37
+ }, { fields: ["providerMessageId"] });
38
+ for (const row of rows)
39
+ ids.add(row.providerMessageId);
40
+ }
41
+ return ids;
42
+ }
43
+ export async function hasOpenQuarantine(db, accountId) {
44
+ const rows = await selectMany(db, quarantineTable, { accountId, acknowledgedAt: null }, { fields: ["id"], limit: 1 });
45
+ return rows.length > 0;
46
+ }
@@ -0,0 +1,2 @@
1
+ import type { FeatureRegistrar } from "@cosmicdrift/kumiko-framework/engine";
2
+ export declare function registerInboundMailRetentionJob(r: FeatureRegistrar<"inbound-mail-foundation">): void;
@@ -0,0 +1,62 @@
1
+ import { createFileProviderForTenant, deleteFileRefsBoundToRecord, } from "@cosmicdrift/kumiko-framework/files";
2
+ import { INBOUND_MESSAGE_AGGREGATE_TYPE } from "./events.js";
3
+ import { runInboundMailRetention } from "./retention-sweep.js";
4
+ export function registerInboundMailRetentionJob(r) {
5
+ // Data-Retention — perTenant fan-out (one run per tenant, like
6
+ // data-retention:retention-cleanup): runInboundMailRetention's raw query
7
+ // helpers need the unfiltered runner, so the handler declares escapeHatch
8
+ // and reaches for ctx.db.unsafeRaw(). Without this cron, read_inbound_messages
9
+ // + the bodies grow unbounded (GDPR Art. 5).
10
+ const INBOUND_MAIL_RETENTION_REASON = "inbound-mail retention runs raw deletes; every statement filters by this run's tenantId";
11
+ r.job({
12
+ name: "inbound-mail-retention",
13
+ trigger: { cron: "0 3 * * *" },
14
+ perTenant: true,
15
+ concurrency: "skip",
16
+ escapeHatch: { reason: INBOUND_MAIL_RETENTION_REASON },
17
+ handler: async (_payload, ctx) => {
18
+ if (!ctx.registry) {
19
+ throw new Error("inbound-mail-retention: ctx.registry required (JobContext incomplete)");
20
+ }
21
+ const tenantId = ctx.systemUser?.tenantId ?? ctx._tenantId;
22
+ if (tenantId === undefined) {
23
+ // skip: cron fired without a perTenant fan-out tenant — nothing scoped
24
+ return;
25
+ }
26
+ const T = (await import("@cosmicdrift/kumiko-framework/time")).getTemporal();
27
+ const retentionDb = ctx.db.unsafeRaw(); // @cast-boundary db-operator — jobs never run inside a DbTx
28
+ // Original (.eml/.html) objects live in file-foundation; the provider is lazy and
29
+ // memoized so a tenant without purgeable mails never builds it.
30
+ let providerPromise = null;
31
+ const deleteBodyObject = async (bodyRef) => {
32
+ if (!providerPromise) {
33
+ providerPromise = createFileProviderForTenant({ config: ctx.config, registry: ctx.registry, secrets: ctx.services.secrets }, tenantId);
34
+ }
35
+ const provider = await providerPromise;
36
+ await provider.delete(bodyRef);
37
+ };
38
+ const { systemUser } = ctx;
39
+ const deleteAttachments = systemUser
40
+ ? async (messageId) => {
41
+ await deleteFileRefsBoundToRecord({
42
+ db: ctx.db,
43
+ user: systemUser,
44
+ entityType: INBOUND_MESSAGE_AGGREGATE_TYPE,
45
+ entityId: messageId,
46
+ });
47
+ }
48
+ : undefined;
49
+ const report = await runInboundMailRetention({
50
+ db: retentionDb,
51
+ tenantId,
52
+ now: T.Now.instant(),
53
+ deleteBodyObject,
54
+ ...(deleteAttachments ? { deleteAttachments } : {}),
55
+ });
56
+ if (report.bodyObjectErrors > 0) {
57
+ // biome-ignore lint/suspicious/noConsole: operator-visibility for failed body deletes
58
+ console.warn(`[inbound-mail-foundation:inbound-mail-retention] tenant=${tenantId} bodyObjectErrors=${report.bodyObjectErrors}`);
59
+ }
60
+ },
61
+ });
62
+ }
@@ -16,12 +16,16 @@ export interface InboundRetentionArgs {
16
16
  /** Deletes a file-storage body object by bodyRef key. Wired lazily by the job
17
17
  * (createFileProviderForTenant); if absent, no body is deleted. */
18
18
  readonly deleteBodyObject?: (bodyRef: string) => Promise<void>;
19
+ /** Removes the fileRefs bound to an expired mail (its attachments); wired by the job. */
20
+ readonly deleteAttachments?: (messageId: string) => Promise<void>;
19
21
  }
20
22
  export interface InboundRetentionReport {
21
23
  readonly messagesPurged: number;
22
24
  readonly bodyObjectsDeleted: number;
23
25
  readonly bodyObjectErrors: number;
24
26
  readonly seenPurged: number;
27
+ readonly quarantinePurged: number;
28
+ readonly ingestFailuresPurged: number;
25
29
  }
26
30
  export declare function runInboundMailRetention(args: InboundRetentionArgs): Promise<InboundRetentionReport>;
27
31
  export {};
@@ -20,6 +20,18 @@
20
20
  // directly through the table's tenant_id column (table-builder convention),
21
21
  // without an Account join.
22
22
  //
23
+ // store_mail_ingest_failures (unmanaged): counters of mails the ingest could not take. A counter
24
+ // whose mail never failed again (it went through or was quarantined, which clear it) is stale
25
+ // after the seen retention.
26
+ //
27
+ // store_mail_quarantine (unmanaged): acknowledged entries are purged after
28
+ // QUARANTINE_ACKNOWLEDGED_RETENTION_DAYS; unacknowledged ones stay, they
29
+ // keep the mailbox flagged until someone looked at them.
30
+ //
31
+ // Attachments are fileRefs bound to the mail row: they go with it (soft delete through the
32
+ // fileRef executor; the generic soft-delete cleanup removes the bytes). A failure keeps the Row
33
+ // for the next sweep, like a failed body delete.
34
+ //
23
35
  // LIMITATION: the PII in the message events remains decryptable under the
24
36
  // TENANT subject key—per-Row retention does not shred a key. Actual Art.-17
25
37
  // erasure of event payloads happens only during tenant-destroy (key erasure).
@@ -29,7 +41,10 @@ import { deleteMany, selectMany } from "@cosmicdrift/kumiko-framework/db";
29
41
  import { archiveStream, deleteRowsWithoutReplayableStream, } from "@cosmicdrift/kumiko-framework/event-store";
30
42
  import { seenMessageTable } from "./entities.js";
31
43
  import { INBOUND_MESSAGE_AGGREGATE_TYPE } from "./events.js";
44
+ import { ingestFailureTable } from "./ingest-failures.js";
32
45
  import { inboundMessagesProjectionTable } from "./projection.js";
46
+ import { QUARANTINE_ACKNOWLEDGED_RETENTION_DAYS } from "./quarantine.js";
47
+ import { quarantineTable } from "./quarantine-entities.js";
33
48
  export const MESSAGE_RETENTION_DAYS = 365;
34
49
  export const SEEN_RETENTION_DAYS = 90;
35
50
  const BATCH_LIMIT = 1000;
@@ -42,7 +57,18 @@ export async function runInboundMailRetention(args) {
42
57
  const seenCutoff = args.now.subtract({ hours: seenDays * 24 });
43
58
  const messages = await purgeExpiredMessages(args, messageCutoff);
44
59
  const seenPurged = await purgeExpiredSeenAnchors(args.db, args.tenantId, seenCutoff);
45
- return { ...messages, seenPurged };
60
+ const quarantineCutoff = args.now.subtract({
61
+ hours: QUARANTINE_ACKNOWLEDGED_RETENTION_DAYS * 24,
62
+ });
63
+ const quarantinePurged = await deleteMany(args.db, quarantineTable, {
64
+ tenantId: args.tenantId,
65
+ acknowledgedAt: { lt: quarantineCutoff },
66
+ });
67
+ const ingestFailuresPurged = await deleteMany(args.db, ingestFailureTable, {
68
+ tenantId: args.tenantId,
69
+ lastFailedAt: { lt: seenCutoff },
70
+ });
71
+ return { ...messages, seenPurged, quarantinePurged, ingestFailuresPurged };
46
72
  }
47
73
  async function purgeExpiredMessages(args, cutoff) {
48
74
  let messagesPurged = 0;
@@ -74,16 +100,17 @@ async function purgeExpiredMessages(args, cutoff) {
74
100
  archivedBy: ARCHIVED_BY,
75
101
  reason: REASON,
76
102
  });
77
- if (row.bodyRef && args.deleteBodyObject) {
78
- try {
103
+ try {
104
+ if (row.bodyRef && args.deleteBodyObject) {
79
105
  await args.deleteBodyObject(row.bodyRef);
80
106
  bodyObjectsDeleted++;
81
107
  }
82
- catch {
83
- bodyObjectErrors++;
84
- failedIds.add(row.id);
85
- continue;
86
- }
108
+ await args.deleteAttachments?.(row.id);
109
+ }
110
+ catch {
111
+ bodyObjectErrors++;
112
+ failedIds.add(row.id);
113
+ continue;
87
114
  }
88
115
  ids.push(row.id);
89
116
  }
@@ -1,9 +1,21 @@
1
1
  import { type ProjectionListScreenDefinition } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import type { ActionFormScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
3
+ import type { InboundMailRoles } from "./mail-roles.ts";
3
4
  export declare const MAIL_ACCOUNT_LIST_SCREEN_ID = "mail-accounts";
4
5
  export declare const MAIL_ACCOUNT_EDIT_SCREEN_ID = "mail-account-edit";
5
6
  export declare const MAIL_ACCOUNT_LIST_SCREEN_QN = "inbound-mail-foundation:screen:mail-accounts";
7
+ export declare const MY_MAIL_ACCOUNT_LIST_SCREEN_ID = "my-mail-accounts";
8
+ export declare const MY_MAIL_ACCOUNT_LIST_SCREEN_QN = "inbound-mail-foundation:screen:my-mail-accounts";
9
+ export declare const MAIL_ACCOUNT_SENDER_CHECK_SCREEN_ID = "mail-account-sender-check";
6
10
  export declare const IMAP_CONNECT_SCREEN_ID = "mail-account-connect-imap";
11
+ export declare const IMAP_RECONNECT_SCREEN_ID = "mail-account-reconnect-imap";
12
+ export declare const MY_IMAP_RECONNECT_SCREEN_ID = "my-mail-account-reconnect-imap";
13
+ export declare const MY_IMAP_CONNECT_SCREEN_ID = "my-mail-account-connect-imap";
14
+ export declare const MAIL_QUARANTINE_SCREEN_ID = "mail-quarantine";
7
15
  export declare const MAIL_ACCOUNT_STATUS_OPTION_KEY_PREFIX = "inboundMail.accounts.status.";
8
- export declare const mailAccountListScreen: ProjectionListScreenDefinition;
9
- export declare const mailAccountEditScreen: ActionFormScreenDefinition;
16
+ export declare const MAIL_ACCOUNT_LAST_ERROR_OPTION_KEY_PREFIX = "inboundMail.accounts.lastError.";
17
+ export declare function createMailAccountListScreen({ adminRoles, }: InboundMailRoles): ProjectionListScreenDefinition;
18
+ export declare function createMyMailAccountListScreen({ memberRoles, }: InboundMailRoles): ProjectionListScreenDefinition;
19
+ export declare function createMailAccountEditScreen({ adminRoles, }: InboundMailRoles): ActionFormScreenDefinition;
20
+ export declare function createMailAccountSenderCheckScreen({ adminRoles, }: InboundMailRoles): ActionFormScreenDefinition;
21
+ export declare function createMailAccountScreens(roles: InboundMailRoles): readonly [ProjectionListScreenDefinition, ProjectionListScreenDefinition, ActionFormScreenDefinition, ActionFormScreenDefinition];