@rapidmx/web-client 0.20.0 → 0.22.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 (906) hide show
  1. package/README.md +415 -381
  2. package/apps/admin/_layout.tsx +2 -2
  3. package/apps/admin/audit-log/index.tsx +4 -4
  4. package/apps/admin/branding/index.tsx +39 -39
  5. package/apps/admin/data-requests/index.tsx +482 -482
  6. package/apps/admin/distribution-lists/[uid].tsx +3 -3
  7. package/apps/admin/distribution-lists/index.tsx +4 -4
  8. package/apps/admin/distribution-lists/new/index.tsx +5 -5
  9. package/apps/admin/domains/[uid].tsx +166 -166
  10. package/apps/admin/domains/index.tsx +4 -4
  11. package/apps/admin/domains/new/index.tsx +5 -5
  12. package/apps/admin/encryption-policy/index.tsx +1 -1
  13. package/apps/admin/escrow-scopes/[uid].tsx +350 -350
  14. package/apps/admin/escrow-scopes/index.tsx +4 -4
  15. package/apps/admin/escrow-scopes/new/index.tsx +5 -5
  16. package/apps/admin/index.tsx +129 -129
  17. package/apps/admin/ingest-queue/index.tsx +4 -4
  18. package/apps/admin/mailbox-policy/index.tsx +1 -1
  19. package/apps/admin/mailboxes/[uid].tsx +271 -271
  20. package/apps/admin/mailboxes/new/index.tsx +30 -30
  21. package/apps/admin/plugins/index.tsx +15 -15
  22. package/apps/admin/quarantine/index.tsx +5 -5
  23. package/apps/admin/retention-policy/index.tsx +39 -39
  24. package/apps/admin/signing-certificates/index.tsx +343 -343
  25. package/apps/admin/transport-rules/[uid].tsx +5 -5
  26. package/apps/admin/transport-rules/_transportRuleConfig.tsx +3 -3
  27. package/apps/admin/transport-rules/index.tsx +4 -4
  28. package/apps/admin/transport-rules/new/index.tsx +5 -5
  29. package/apps/escrow/_layout.tsx +1 -1
  30. package/apps/escrow/audit-log/index.tsx +196 -196
  31. package/apps/escrow/index.tsx +4 -4
  32. package/apps/escrow/matters/[uid].tsx +621 -621
  33. package/apps/escrow/matters/new/index.tsx +6 -6
  34. package/apps/shared/appearance/AppearanceForm.tsx +3 -3
  35. package/apps/shared/appearance/AppearanceHead.tsx +1 -1
  36. package/apps/shared/appearance/AppearanceProvider.tsx +3 -3
  37. package/apps/shared/appearance/appearanceCache.ts +1 -1
  38. package/apps/shared/appearance/appearanceContext.ts +1 -1
  39. package/apps/shared/appearance/theme.ts +1 -1
  40. package/apps/shared/auth/adminAccess.ts +99 -99
  41. package/apps/shared/calendar/bookingPlugin.ts +1 -1
  42. package/apps/shared/calendar/calendarLiveUpdates.ts +1 -1
  43. package/apps/shared/calendar/calendarReminders.ts +1 -1
  44. package/apps/shared/calendar/useCalendarReminders.ts +1 -1
  45. package/apps/shared/components/admin/diagnostics/DiagnosticsManager.tsx +1 -1
  46. package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +2 -2
  47. package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +2 -2
  48. package/apps/shared/components/admin/diagnostics/PackagesTable.tsx +1 -1
  49. package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
  50. package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +2 -2
  51. package/apps/shared/components/admin/diagnostics/VersionsPanel.tsx +1 -1
  52. package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +1 -1
  53. package/apps/shared/components/admin/diagnostics/format.ts +1 -1
  54. package/apps/shared/components/admin/diagnostics/logClient.ts +1 -1
  55. package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
  56. package/apps/shared/components/admin/elevation.ts +1 -1
  57. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +3 -3
  58. package/apps/shared/components/admin/layout/AdminShell.tsx +384 -384
  59. package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +238 -238
  60. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +154 -152
  61. package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +194 -194
  62. package/apps/shared/components/admin/mailboxes/MailboxTable.tsx +1 -1
  63. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +19 -14
  64. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +5 -5
  65. package/apps/shared/components/admin/settings/BrandingForm.tsx +423 -423
  66. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +5 -5
  67. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +119 -119
  68. package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +2 -2
  69. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +32 -27
  70. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +198 -198
  71. package/apps/shared/components/admin/settings/PluginsManager.tsx +2093 -2093
  72. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +182 -182
  73. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +288 -288
  74. package/apps/shared/components/admin/setup/SetupWizard.tsx +450 -446
  75. package/apps/shared/components/admin/signOut.ts +1 -1
  76. package/apps/shared/components/admin/usePagedList.tsx +129 -129
  77. package/apps/shared/components/calendar/AppointmentQuickForm.tsx +3 -3
  78. package/apps/shared/components/calendar/CalendarListSidebar.tsx +3 -3
  79. package/apps/shared/components/calendar/DescriptionEditor.tsx +1 -1
  80. package/apps/shared/components/calendar/EventDescriptionView.tsx +1 -1
  81. package/apps/shared/components/calendar/EventDetails.tsx +16 -14
  82. package/apps/shared/components/calendar/EventEditor.tsx +54 -39
  83. package/apps/shared/components/calendar/EventExpandedForm.tsx +3 -3
  84. package/apps/shared/components/calendar/EventFormParts.tsx +2 -2
  85. package/apps/shared/components/calendar/EventModal.tsx +206 -206
  86. package/apps/shared/components/calendar/EventQuickForm.tsx +3 -3
  87. package/apps/shared/components/calendar/EventShell.tsx +1 -1
  88. package/apps/shared/components/calendar/FindATime.tsx +6 -4
  89. package/apps/shared/components/calendar/GuestInput.tsx +2 -2
  90. package/apps/shared/components/calendar/MonthView.tsx +185 -185
  91. package/apps/shared/components/calendar/QuickCreateFaces.tsx +1 -1
  92. package/apps/shared/components/calendar/QuickFaceFrame.tsx +1 -1
  93. package/apps/shared/components/calendar/RecurrenceEditor.tsx +227 -227
  94. package/apps/shared/components/calendar/RequestChangeForm.tsx +8 -6
  95. package/apps/shared/components/calendar/ResourcePicker.tsx +7 -5
  96. package/apps/shared/components/calendar/SplitDayView.tsx +144 -144
  97. package/apps/shared/components/calendar/TaskQuickForm.tsx +23 -18
  98. package/apps/shared/components/calendar/TimeGridView.tsx +246 -246
  99. package/apps/shared/components/calendar/allDay.ts +124 -124
  100. package/apps/shared/components/calendar/eventDialogFields.ts +3 -3
  101. package/apps/shared/components/calendar/eventForm.ts +3 -3
  102. package/apps/shared/components/calendar/eventFormat.ts +3 -3
  103. package/apps/shared/components/calendar/findTimeGrid.ts +2 -2
  104. package/apps/shared/components/calendar/layout/CalendarShell.tsx +11 -9
  105. package/apps/shared/components/contacts/ContactDetailPane.tsx +4 -4
  106. package/apps/shared/components/contacts/ContactForm.tsx +393 -383
  107. package/apps/shared/components/contacts/ContactsSidebar.tsx +7 -5
  108. package/apps/shared/components/contacts/ContactsToolbar.tsx +103 -103
  109. package/apps/shared/components/contacts/KeyChangeReview.tsx +5 -5
  110. package/apps/shared/components/contacts/contactKeys.ts +3 -3
  111. package/apps/shared/components/contacts/layout/ContactsShell.tsx +9 -7
  112. package/apps/shared/components/escrow/layout/EscrowShell.tsx +155 -155
  113. package/apps/shared/components/forms/StringListField.tsx +1 -1
  114. package/apps/shared/components/layout/AppShell.tsx +465 -461
  115. package/apps/shared/components/layout/BrandingChrome.tsx +1 -1
  116. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +398 -398
  117. package/apps/shared/components/layout/MailboxProvisioning.tsx +170 -168
  118. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +9 -9
  119. package/apps/shared/components/layout/ResponsiveToolbar.tsx +315 -315
  120. package/apps/shared/components/layout/ThemeSwitch.tsx +84 -84
  121. package/apps/shared/components/layout/UnlockPromptProvider.tsx +6 -6
  122. package/apps/shared/components/layout/UserMenu.tsx +441 -439
  123. package/apps/shared/components/mail/ConversationList.tsx +334 -332
  124. package/apps/shared/components/mail/ConversationThreadPane.tsx +624 -613
  125. package/apps/shared/components/mail/InviteCard.tsx +11 -9
  126. package/apps/shared/components/mail/LazyReadingPane.tsx +2 -2
  127. package/apps/shared/components/mail/MailAddress.tsx +1 -1
  128. package/apps/shared/components/mail/MailListToolbar.tsx +2 -2
  129. package/apps/shared/components/mail/MailSelectionBar.tsx +240 -240
  130. package/apps/shared/components/mail/MenuButton.tsx +404 -404
  131. package/apps/shared/components/mail/MessageDetailPane.tsx +1759 -1757
  132. package/apps/shared/components/mail/MoveToFolderDialog.tsx +8 -6
  133. package/apps/shared/components/mail/OutboxRowStatus.tsx +1 -1
  134. package/apps/shared/components/mail/PermanentDeleteDialog.tsx +2 -2
  135. package/apps/shared/components/mail/compose/ComposeContext.tsx +323 -312
  136. package/apps/shared/components/mail/compose/ComposeToolbar.tsx +422 -422
  137. package/apps/shared/components/mail/compose/ComposeWindow.tsx +1709 -1681
  138. package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +4 -4
  139. package/apps/shared/components/mail/compose/EmojiPicker.tsx +2 -2
  140. package/apps/shared/components/mail/compose/GifPicker.tsx +3 -3
  141. package/apps/shared/components/mail/compose/RecipientInput.tsx +1 -1
  142. package/apps/shared/components/mail/compose/RichTextEditor.tsx +147 -147
  143. package/apps/shared/components/mail/compose/ScheduleSendPicker.tsx +1 -1
  144. package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -60
  145. package/apps/shared/components/mail/compose/encryptionRequirement.ts +2 -2
  146. package/apps/shared/components/mail/compose/quotedBody.ts +161 -161
  147. package/apps/shared/components/mail/compose/recipients.ts +1 -1
  148. package/apps/shared/components/mail/invite/InviteRowChip.tsx +2 -2
  149. package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +9 -7
  150. package/apps/shared/components/mail/invite/InviteTimeline.tsx +1 -1
  151. package/apps/shared/components/mail/invite/ProposeTimeForm.tsx +2 -2
  152. package/apps/shared/components/mail/invite/inviteFormat.ts +2 -2
  153. package/apps/shared/components/mail/invite/inviteStore.ts +14 -6
  154. package/apps/shared/components/mail/labelMenu.tsx +9 -7
  155. package/apps/shared/components/mail/layout/MailShell.tsx +4 -4
  156. package/apps/shared/components/mail/listPreferences.ts +2 -2
  157. package/apps/shared/components/mail/pinnedSigners.ts +45 -19
  158. package/apps/shared/components/mail/reading/EncryptedBody.tsx +2 -2
  159. package/apps/shared/components/mail/reading/MessageBody.tsx +6 -6
  160. package/apps/shared/components/mail/reading/MessageCard.tsx +3 -3
  161. package/apps/shared/components/mail/reading/MessageMoreMenu.tsx +258 -258
  162. package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +79 -79
  163. package/apps/shared/components/mail/reading/PendingMessageCard.tsx +1 -1
  164. package/apps/shared/components/mail/reading/bodyContent.ts +3 -3
  165. package/apps/shared/components/mail/reading/bodyHtml.ts +1 -1
  166. package/apps/shared/components/mail/reading/messageExport.ts +59 -59
  167. package/apps/shared/components/mail/reading/printMessage.ts +99 -99
  168. package/apps/shared/components/mail/reading/useMessageActions.ts +450 -443
  169. package/apps/shared/components/mail/unreadStyle.tsx +1 -1
  170. package/apps/shared/components/mail/verificationSeals.ts +129 -125
  171. package/apps/shared/components/mail/writableMailboxes.ts +14 -7
  172. package/apps/shared/components/rules/RuleBuilder.tsx +311 -311
  173. package/apps/shared/components/settings/SigningCertificateCard.tsx +344 -344
  174. package/apps/shared/components/settings/layout/SettingsShell.tsx +8 -6
  175. package/apps/shared/components/sharing/PrincipalListField.tsx +1 -1
  176. package/apps/shared/components/sharing/PrincipalPicker.tsx +1 -1
  177. package/apps/shared/components/sharing/PrincipalResolver.tsx +4 -4
  178. package/apps/shared/components/tasks/TasksSidebar.tsx +7 -5
  179. package/apps/shared/components/tasks/layout/TasksShell.tsx +9 -7
  180. package/apps/shared/keyboard/GlobalShortcuts.tsx +51 -51
  181. package/apps/shared/keyboard/ShortcutProvider.tsx +62 -62
  182. package/apps/shared/keyboard/ShortcutsDialog.tsx +84 -84
  183. package/apps/shared/keyboard/dispatch.ts +124 -124
  184. package/apps/shared/keyboard/format.ts +89 -89
  185. package/apps/shared/keyboard/keymap.ts +114 -114
  186. package/apps/shared/keyboard/registry.ts +65 -65
  187. package/apps/shared/keyboard/targets.ts +79 -79
  188. package/apps/shared/mail/findWellKnownFolderUid.ts +6 -4
  189. package/apps/shared/mail/folderCounts.ts +8 -4
  190. package/apps/shared/mail/folderOfType.ts +51 -49
  191. package/apps/shared/mail/folderTree.ts +143 -143
  192. package/apps/shared/mail/listAllPages.ts +39 -39
  193. package/apps/shared/mail/listSnapshots.ts +2 -2
  194. package/apps/shared/mail/messageReadState.ts +6 -5
  195. package/apps/shared/mail/newMailNotifications.ts +171 -171
  196. package/apps/shared/mail/outbox/composeBridge.ts +2 -2
  197. package/apps/shared/mail/outbox/outboxState.ts +1 -1
  198. package/apps/shared/mail/outbox/outgoingReplies.ts +2 -2
  199. package/apps/shared/mail/outbox/sendDecision.ts +2 -2
  200. package/apps/shared/mail/outbox/sendJob.ts +450 -445
  201. package/apps/shared/mail/outbox/sendOutcomes.ts +160 -155
  202. package/apps/shared/mail/outbox/useOutboxStatus.ts +5 -3
  203. package/apps/shared/mail/permanentDelete.ts +8 -7
  204. package/apps/shared/mail/primaryMailbox.ts +1 -1
  205. package/apps/shared/mail/reportNotices.ts +66 -66
  206. package/apps/shared/mail/senderBlocking.ts +157 -141
  207. package/apps/shared/mail/useMailConnection.ts +207 -205
  208. package/apps/shared/mail/useMailLiveUpdates.ts +277 -277
  209. package/apps/shared/mail/useMailboxUpdateAccess.ts +84 -60
  210. package/apps/shared/mail/useMarkMessageRead.ts +54 -47
  211. package/apps/shared/mail/useNewMailNotifications.ts +178 -178
  212. package/apps/shared/mail/usePermanentDelete.tsx +5 -3
  213. package/apps/shared/navigation/pageTitle.ts +1 -1
  214. package/apps/shared/notifications/NotificationCenter.tsx +1 -1
  215. package/apps/shared/notifications/NotificationHistoryDialog.tsx +2 -2
  216. package/apps/shared/notifications/apiErrors.ts +2 -2
  217. package/apps/shared/notifications/pushStatus.ts +1 -1
  218. package/apps/shared/notifications/store.ts +560 -560
  219. package/apps/shared/notifications/systemErrors.ts +1 -1
  220. package/apps/shared/search/LocalIndexLifecycle.tsx +120 -114
  221. package/apps/shared/search/crossMailboxSearch.ts +3 -3
  222. package/apps/shared/search/localIndexBuilder.ts +493 -481
  223. package/apps/shared/search/localIndexKey.ts +1 -1
  224. package/apps/shared/search/localIndexRpcClient.ts +150 -30
  225. package/apps/shared/search/localIndexTransport.ts +84 -0
  226. package/apps/shared/search/localIndexWorker.ts +1 -1
  227. package/apps/shared/search/searchTier2.ts +3 -3
  228. package/apps/shared/signing/enrollmentStorage.ts +33 -33
  229. package/apps/shared/signing/enrollmentTracker.ts +385 -385
  230. package/apps/shared/signing/enrollmentView.ts +251 -251
  231. package/apps/shared/signing/signingInfo.ts +1 -1
  232. package/apps/shared/signing/useNow.ts +19 -19
  233. package/apps/shared/signing/useSigningEnrollmentWatcher.ts +92 -90
  234. package/apps/shared/styles/app.css +387 -396
  235. package/apps/www/_layout.tsx +2 -2
  236. package/apps/www/calendar/index.tsx +583 -581
  237. package/apps/www/contacts/[uid].tsx +114 -112
  238. package/apps/www/contacts/index.tsx +19 -17
  239. package/apps/www/index.tsx +3021 -3012
  240. package/apps/www/messages/[uid].tsx +141 -139
  241. package/apps/www/settings/auto-reply/index.tsx +138 -136
  242. package/apps/www/settings/blocked-senders/index.tsx +305 -303
  243. package/apps/www/settings/encryption/index.tsx +1296 -1290
  244. package/apps/www/settings/filters/[uid].tsx +184 -179
  245. package/apps/www/settings/filters/_mailFilterRuleConfig.tsx +2 -2
  246. package/apps/www/settings/filters/index.tsx +105 -105
  247. package/apps/www/settings/filters/new/index.tsx +167 -165
  248. package/apps/www/settings/labels/index.tsx +209 -207
  249. package/apps/www/settings/privacy/index.tsx +499 -495
  250. package/apps/www/settings/profile/index.tsx +256 -251
  251. package/apps/www/settings/read-receipts/index.tsx +155 -150
  252. package/apps/www/settings/sharing/index.tsx +259 -259
  253. package/apps/www/settings/signatures/[uid].tsx +175 -175
  254. package/apps/www/settings/signatures/index.tsx +91 -91
  255. package/apps/www/settings/signatures/new/index.tsx +138 -138
  256. package/apps/www/settings/signatures/signatureDefaults.ts +1 -1
  257. package/apps/www/tasks/index.tsx +659 -654
  258. package/dist/apps/admin/_layout.d.ts +1 -1
  259. package/dist/apps/admin/_layout.js +1 -1
  260. package/dist/apps/admin/audit-log/index.d.ts +1 -1
  261. package/dist/apps/admin/audit-log/index.js +4 -4
  262. package/dist/apps/admin/branding/index.js +3 -3
  263. package/dist/apps/admin/data-requests/index.js +8 -8
  264. package/dist/apps/admin/distribution-lists/[uid].js +3 -3
  265. package/dist/apps/admin/distribution-lists/index.js +4 -4
  266. package/dist/apps/admin/distribution-lists/new/index.js +5 -5
  267. package/dist/apps/admin/domains/[uid].js +6 -6
  268. package/dist/apps/admin/domains/index.js +4 -4
  269. package/dist/apps/admin/domains/new/index.js +5 -5
  270. package/dist/apps/admin/encryption-policy/index.js +1 -1
  271. package/dist/apps/admin/escrow-scopes/[uid].d.ts +1 -1
  272. package/dist/apps/admin/escrow-scopes/[uid].js +7 -7
  273. package/dist/apps/admin/escrow-scopes/index.js +4 -4
  274. package/dist/apps/admin/escrow-scopes/new/index.js +5 -5
  275. package/dist/apps/admin/index.js +6 -6
  276. package/dist/apps/admin/ingest-queue/index.js +4 -4
  277. package/dist/apps/admin/mailbox-policy/index.js +1 -1
  278. package/dist/apps/admin/mailboxes/[uid].js +5 -5
  279. package/dist/apps/admin/quarantine/index.js +5 -5
  280. package/dist/apps/admin/retention-policy/index.js +3 -3
  281. package/dist/apps/admin/signing-certificates/index.js +5 -5
  282. package/dist/apps/admin/transport-rules/[uid].js +5 -5
  283. package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +1 -1
  284. package/dist/apps/admin/transport-rules/_transportRuleConfig.js +2 -2
  285. package/dist/apps/admin/transport-rules/index.js +4 -4
  286. package/dist/apps/admin/transport-rules/new/index.js +5 -5
  287. package/dist/apps/escrow/_layout.d.ts +1 -1
  288. package/dist/apps/escrow/audit-log/index.d.ts +1 -1
  289. package/dist/apps/escrow/audit-log/index.js +4 -4
  290. package/dist/apps/escrow/index.js +4 -4
  291. package/dist/apps/escrow/matters/[uid].js +10 -10
  292. package/dist/apps/escrow/matters/new/index.js +6 -6
  293. package/dist/apps/shared/appearance/AppearanceForm.js +3 -3
  294. package/dist/apps/shared/appearance/AppearanceHead.js +1 -1
  295. package/dist/apps/shared/appearance/AppearanceProvider.d.ts +1 -1
  296. package/dist/apps/shared/appearance/AppearanceProvider.js +3 -3
  297. package/dist/apps/shared/appearance/appearanceCache.d.ts +1 -1
  298. package/dist/apps/shared/appearance/appearanceCache.js +1 -1
  299. package/dist/apps/shared/appearance/appearanceContext.d.ts +1 -1
  300. package/dist/apps/shared/appearance/theme.d.ts +1 -1
  301. package/dist/apps/shared/auth/adminAccess.js +1 -1
  302. package/dist/apps/shared/calendar/bookingPlugin.js +1 -1
  303. package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +1 -1
  304. package/dist/apps/shared/calendar/calendarReminders.d.ts +1 -1
  305. package/dist/apps/shared/calendar/useCalendarReminders.js +1 -1
  306. package/dist/apps/shared/components/admin/diagnostics/DiagnosticsManager.js +1 -1
  307. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.d.ts +1 -1
  308. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +2 -2
  309. package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +2 -2
  310. package/dist/apps/shared/components/admin/diagnostics/PackagesTable.js +1 -1
  311. package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
  312. package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +2 -2
  313. package/dist/apps/shared/components/admin/diagnostics/VersionsPanel.js +1 -1
  314. package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.js +1 -1
  315. package/dist/apps/shared/components/admin/diagnostics/format.js +1 -1
  316. package/dist/apps/shared/components/admin/diagnostics/logClient.js +1 -1
  317. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +1 -1
  318. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
  319. package/dist/apps/shared/components/admin/elevation.js +1 -1
  320. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +3 -3
  321. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
  322. package/dist/apps/shared/components/admin/layout/AdminShell.js +8 -8
  323. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.d.ts +1 -1
  324. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +6 -6
  325. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +1 -1
  326. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +10 -8
  327. package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
  328. package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +1 -1
  329. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +1 -1
  330. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +7 -5
  331. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +5 -5
  332. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +1 -1
  333. package/dist/apps/shared/components/admin/settings/BrandingForm.js +8 -8
  334. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +1 -1
  335. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +5 -5
  336. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +1 -1
  337. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +4 -4
  338. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +2 -2
  339. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +1 -1
  340. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +14 -12
  341. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +1 -1
  342. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +4 -4
  343. package/dist/apps/shared/components/admin/settings/PluginsManager.js +5 -5
  344. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +1 -1
  345. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +5 -5
  346. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +7 -7
  347. package/dist/apps/shared/components/admin/setup/SetupWizard.js +26 -22
  348. package/dist/apps/shared/components/admin/signOut.js +1 -1
  349. package/dist/apps/shared/components/admin/usePagedList.js +2 -2
  350. package/dist/apps/shared/components/calendar/AppointmentQuickForm.js +3 -3
  351. package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +1 -1
  352. package/dist/apps/shared/components/calendar/CalendarListSidebar.js +2 -2
  353. package/dist/apps/shared/components/calendar/DescriptionEditor.js +1 -1
  354. package/dist/apps/shared/components/calendar/EventDescriptionView.js +1 -1
  355. package/dist/apps/shared/components/calendar/EventDetails.d.ts +2 -2
  356. package/dist/apps/shared/components/calendar/EventDetails.js +16 -14
  357. package/dist/apps/shared/components/calendar/EventEditor.d.ts +2 -2
  358. package/dist/apps/shared/components/calendar/EventEditor.js +22 -20
  359. package/dist/apps/shared/components/calendar/EventExpandedForm.js +2 -2
  360. package/dist/apps/shared/components/calendar/EventFormParts.d.ts +1 -1
  361. package/dist/apps/shared/components/calendar/EventFormParts.js +1 -1
  362. package/dist/apps/shared/components/calendar/EventModal.d.ts +2 -2
  363. package/dist/apps/shared/components/calendar/EventModal.js +3 -3
  364. package/dist/apps/shared/components/calendar/EventQuickForm.js +3 -3
  365. package/dist/apps/shared/components/calendar/EventShell.js +1 -1
  366. package/dist/apps/shared/components/calendar/FindATime.js +6 -4
  367. package/dist/apps/shared/components/calendar/GuestInput.d.ts +2 -2
  368. package/dist/apps/shared/components/calendar/MonthView.d.ts +1 -1
  369. package/dist/apps/shared/components/calendar/MonthView.js +1 -1
  370. package/dist/apps/shared/components/calendar/QuickCreateFaces.js +1 -1
  371. package/dist/apps/shared/components/calendar/QuickFaceFrame.js +1 -1
  372. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +1 -1
  373. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +1 -1
  374. package/dist/apps/shared/components/calendar/RequestChangeForm.js +8 -6
  375. package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +1 -1
  376. package/dist/apps/shared/components/calendar/ResourcePicker.js +7 -5
  377. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +1 -1
  378. package/dist/apps/shared/components/calendar/TaskQuickForm.d.ts +1 -1
  379. package/dist/apps/shared/components/calendar/TaskQuickForm.js +9 -7
  380. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +1 -1
  381. package/dist/apps/shared/components/calendar/TimeGridView.js +1 -1
  382. package/dist/apps/shared/components/calendar/allDay.d.ts +2 -2
  383. package/dist/apps/shared/components/calendar/allDay.js +1 -1
  384. package/dist/apps/shared/components/calendar/eventDialogFields.d.ts +2 -2
  385. package/dist/apps/shared/components/calendar/eventDialogFields.js +2 -2
  386. package/dist/apps/shared/components/calendar/eventForm.d.ts +3 -3
  387. package/dist/apps/shared/components/calendar/eventFormat.d.ts +1 -1
  388. package/dist/apps/shared/components/calendar/eventFormat.js +2 -2
  389. package/dist/apps/shared/components/calendar/findTimeGrid.d.ts +1 -1
  390. package/dist/apps/shared/components/calendar/findTimeGrid.js +1 -1
  391. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
  392. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +11 -9
  393. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +1 -1
  394. package/dist/apps/shared/components/contacts/ContactDetailPane.js +2 -2
  395. package/dist/apps/shared/components/contacts/ContactForm.d.ts +2 -2
  396. package/dist/apps/shared/components/contacts/ContactForm.js +12 -8
  397. package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +1 -1
  398. package/dist/apps/shared/components/contacts/ContactsSidebar.js +7 -5
  399. package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +1 -1
  400. package/dist/apps/shared/components/contacts/KeyChangeReview.js +5 -5
  401. package/dist/apps/shared/components/contacts/contactKeys.d.ts +2 -2
  402. package/dist/apps/shared/components/contacts/contactKeys.js +2 -2
  403. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
  404. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +9 -7
  405. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +7 -7
  406. package/dist/apps/shared/components/forms/StringListField.js +1 -1
  407. package/dist/apps/shared/components/layout/AppShell.d.ts +2 -2
  408. package/dist/apps/shared/components/layout/AppShell.js +14 -10
  409. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +1 -1
  410. package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +1 -1
  411. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +9 -9
  412. package/dist/apps/shared/components/layout/MailboxProvisioning.js +8 -6
  413. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +1 -1
  414. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +9 -9
  415. package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +2 -2
  416. package/dist/apps/shared/components/layout/UnlockPromptProvider.js +5 -5
  417. package/dist/apps/shared/components/layout/UserMenu.js +6 -4
  418. package/dist/apps/shared/components/mail/ConversationList.d.ts +2 -2
  419. package/dist/apps/shared/components/mail/ConversationList.js +6 -4
  420. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +3 -3
  421. package/dist/apps/shared/components/mail/ConversationThreadPane.js +13 -11
  422. package/dist/apps/shared/components/mail/InviteCard.js +10 -8
  423. package/dist/apps/shared/components/mail/LazyReadingPane.js +2 -2
  424. package/dist/apps/shared/components/mail/MailAddress.d.ts +1 -1
  425. package/dist/apps/shared/components/mail/MailAddress.js +1 -1
  426. package/dist/apps/shared/components/mail/MailListToolbar.d.ts +2 -2
  427. package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +2 -2
  428. package/dist/apps/shared/components/mail/MenuButton.js +1 -1
  429. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +3 -3
  430. package/dist/apps/shared/components/mail/MessageDetailPane.js +30 -28
  431. package/dist/apps/shared/components/mail/MoveToFolderDialog.d.ts +1 -1
  432. package/dist/apps/shared/components/mail/MoveToFolderDialog.js +8 -6
  433. package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +1 -1
  434. package/dist/apps/shared/components/mail/PermanentDeleteDialog.js +2 -2
  435. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +10 -1
  436. package/dist/apps/shared/components/mail/compose/ComposeContext.js +4 -2
  437. package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +7 -1
  438. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +54 -31
  439. package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +4 -4
  440. package/dist/apps/shared/components/mail/compose/EmojiPicker.js +2 -2
  441. package/dist/apps/shared/components/mail/compose/GifPicker.js +3 -3
  442. package/dist/apps/shared/components/mail/compose/RecipientInput.d.ts +1 -1
  443. package/dist/apps/shared/components/mail/compose/RecipientInput.js +1 -1
  444. package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.js +1 -1
  445. package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +2 -2
  446. package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +1 -1
  447. package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +3 -3
  448. package/dist/apps/shared/components/mail/compose/quotedBody.js +3 -3
  449. package/dist/apps/shared/components/mail/compose/recipients.d.ts +1 -1
  450. package/dist/apps/shared/components/mail/invite/InviteRowChip.d.ts +1 -1
  451. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +1 -1
  452. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +9 -7
  453. package/dist/apps/shared/components/mail/invite/InviteTimeline.d.ts +1 -1
  454. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.d.ts +1 -1
  455. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.js +1 -1
  456. package/dist/apps/shared/components/mail/invite/inviteFormat.d.ts +2 -2
  457. package/dist/apps/shared/components/mail/invite/inviteStore.d.ts +9 -3
  458. package/dist/apps/shared/components/mail/invite/inviteStore.js +13 -6
  459. package/dist/apps/shared/components/mail/labelMenu.d.ts +1 -1
  460. package/dist/apps/shared/components/mail/labelMenu.js +9 -7
  461. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +1 -1
  462. package/dist/apps/shared/components/mail/layout/MailShell.js +3 -3
  463. package/dist/apps/shared/components/mail/listPreferences.d.ts +2 -2
  464. package/dist/apps/shared/components/mail/listPreferences.js +1 -1
  465. package/dist/apps/shared/components/mail/pinnedSigners.d.ts +12 -5
  466. package/dist/apps/shared/components/mail/pinnedSigners.js +37 -18
  467. package/dist/apps/shared/components/mail/reading/EncryptedBody.js +2 -2
  468. package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +2 -2
  469. package/dist/apps/shared/components/mail/reading/MessageBody.js +4 -4
  470. package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +1 -1
  471. package/dist/apps/shared/components/mail/reading/MessageCard.js +2 -2
  472. package/dist/apps/shared/components/mail/reading/MessageSourceDialog.js +3 -3
  473. package/dist/apps/shared/components/mail/reading/PendingMessageCard.js +1 -1
  474. package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +2 -2
  475. package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -2
  476. package/dist/apps/shared/components/mail/reading/bodyHtml.js +1 -1
  477. package/dist/apps/shared/components/mail/reading/messageExport.js +1 -1
  478. package/dist/apps/shared/components/mail/reading/printMessage.d.ts +2 -2
  479. package/dist/apps/shared/components/mail/reading/printMessage.js +11 -11
  480. package/dist/apps/shared/components/mail/reading/useMessageActions.d.ts +1 -1
  481. package/dist/apps/shared/components/mail/reading/useMessageActions.js +18 -16
  482. package/dist/apps/shared/components/mail/unreadStyle.d.ts +1 -1
  483. package/dist/apps/shared/components/mail/verificationSeals.d.ts +27 -6
  484. package/dist/apps/shared/components/mail/verificationSeals.js +15 -11
  485. package/dist/apps/shared/components/mail/writableMailboxes.d.ts +8 -3
  486. package/dist/apps/shared/components/mail/writableMailboxes.js +12 -6
  487. package/dist/apps/shared/components/rules/RuleBuilder.js +1 -1
  488. package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +1 -1
  489. package/dist/apps/shared/components/settings/SigningCertificateCard.js +3 -3
  490. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
  491. package/dist/apps/shared/components/settings/layout/SettingsShell.js +8 -6
  492. package/dist/apps/shared/components/sharing/PrincipalListField.d.ts +1 -1
  493. package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +1 -1
  494. package/dist/apps/shared/components/sharing/PrincipalPicker.js +1 -1
  495. package/dist/apps/shared/components/sharing/PrincipalResolver.d.ts +1 -1
  496. package/dist/apps/shared/components/sharing/PrincipalResolver.js +3 -3
  497. package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +1 -1
  498. package/dist/apps/shared/components/tasks/TasksSidebar.js +7 -5
  499. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
  500. package/dist/apps/shared/components/tasks/layout/TasksShell.js +9 -7
  501. package/dist/apps/shared/keyboard/ShortcutsDialog.js +1 -1
  502. package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -3
  503. package/dist/apps/shared/mail/findWellKnownFolderUid.js +5 -4
  504. package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
  505. package/dist/apps/shared/mail/folderCounts.js +6 -4
  506. package/dist/apps/shared/mail/folderOfType.d.ts +3 -2
  507. package/dist/apps/shared/mail/folderOfType.js +4 -4
  508. package/dist/apps/shared/mail/folderTree.d.ts +1 -1
  509. package/dist/apps/shared/mail/listSnapshots.d.ts +2 -2
  510. package/dist/apps/shared/mail/messageReadState.d.ts +4 -3
  511. package/dist/apps/shared/mail/messageReadState.js +5 -5
  512. package/dist/apps/shared/mail/newMailNotifications.d.ts +1 -1
  513. package/dist/apps/shared/mail/newMailNotifications.js +1 -1
  514. package/dist/apps/shared/mail/outbox/composeBridge.d.ts +2 -2
  515. package/dist/apps/shared/mail/outbox/outboxState.d.ts +1 -1
  516. package/dist/apps/shared/mail/outbox/outgoingReplies.d.ts +2 -2
  517. package/dist/apps/shared/mail/outbox/sendDecision.d.ts +2 -2
  518. package/dist/apps/shared/mail/outbox/sendDecision.js +1 -1
  519. package/dist/apps/shared/mail/outbox/sendJob.d.ts +10 -6
  520. package/dist/apps/shared/mail/outbox/sendJob.js +39 -35
  521. package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +6 -3
  522. package/dist/apps/shared/mail/outbox/sendOutcomes.js +19 -15
  523. package/dist/apps/shared/mail/outbox/useOutboxStatus.js +5 -3
  524. package/dist/apps/shared/mail/permanentDelete.d.ts +4 -3
  525. package/dist/apps/shared/mail/permanentDelete.js +8 -8
  526. package/dist/apps/shared/mail/primaryMailbox.d.ts +1 -1
  527. package/dist/apps/shared/mail/primaryMailbox.js +1 -1
  528. package/dist/apps/shared/mail/reportNotices.d.ts +1 -1
  529. package/dist/apps/shared/mail/senderBlocking.d.ts +5 -4
  530. package/dist/apps/shared/mail/senderBlocking.js +19 -16
  531. package/dist/apps/shared/mail/useMailConnection.d.ts +1 -1
  532. package/dist/apps/shared/mail/useMailConnection.js +12 -10
  533. package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +2 -2
  534. package/dist/apps/shared/mail/useMailLiveUpdates.js +2 -2
  535. package/dist/apps/shared/mail/useMailboxUpdateAccess.d.ts +3 -2
  536. package/dist/apps/shared/mail/useMailboxUpdateAccess.js +31 -10
  537. package/dist/apps/shared/mail/useMarkMessageRead.d.ts +1 -1
  538. package/dist/apps/shared/mail/useMarkMessageRead.js +5 -3
  539. package/dist/apps/shared/mail/useNewMailNotifications.d.ts +1 -1
  540. package/dist/apps/shared/mail/usePermanentDelete.d.ts +1 -1
  541. package/dist/apps/shared/mail/usePermanentDelete.js +4 -2
  542. package/dist/apps/shared/navigation/pageTitle.d.ts +1 -1
  543. package/dist/apps/shared/notifications/NotificationCenter.js +1 -1
  544. package/dist/apps/shared/notifications/NotificationHistoryDialog.js +2 -2
  545. package/dist/apps/shared/notifications/apiErrors.js +2 -2
  546. package/dist/apps/shared/notifications/pushStatus.js +1 -1
  547. package/dist/apps/shared/notifications/systemErrors.js +1 -1
  548. package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +2 -2
  549. package/dist/apps/shared/search/LocalIndexLifecycle.js +15 -10
  550. package/dist/apps/shared/search/crossMailboxSearch.d.ts +1 -1
  551. package/dist/apps/shared/search/crossMailboxSearch.js +2 -2
  552. package/dist/apps/shared/search/localIndexBuilder.d.ts +4 -3
  553. package/dist/apps/shared/search/localIndexBuilder.js +15 -12
  554. package/dist/apps/shared/search/localIndexKey.js +1 -1
  555. package/dist/apps/shared/search/localIndexRpcClient.d.ts +43 -31
  556. package/dist/apps/shared/search/localIndexRpcClient.js +113 -20
  557. package/dist/apps/shared/search/localIndexTransport.d.ts +77 -0
  558. package/dist/apps/shared/search/localIndexTransport.js +1 -0
  559. package/dist/apps/shared/search/localIndexWorker.d.ts +1 -1
  560. package/dist/apps/shared/search/searchTier2.d.ts +3 -3
  561. package/dist/apps/shared/signing/enrollmentTracker.d.ts +1 -1
  562. package/dist/apps/shared/signing/enrollmentTracker.js +3 -3
  563. package/dist/apps/shared/signing/enrollmentView.d.ts +1 -1
  564. package/dist/apps/shared/signing/signingInfo.d.ts +1 -1
  565. package/dist/apps/shared/signing/signingInfo.js +1 -1
  566. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +1 -1
  567. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +5 -3
  568. package/dist/apps/shared/styles/app.css +387 -396
  569. package/dist/apps/www/_layout.d.ts +1 -1
  570. package/dist/apps/www/_layout.js +1 -1
  571. package/dist/apps/www/calendar/index.d.ts +1 -1
  572. package/dist/apps/www/calendar/index.js +20 -18
  573. package/dist/apps/www/contacts/[uid].d.ts +1 -1
  574. package/dist/apps/www/contacts/[uid].js +8 -6
  575. package/dist/apps/www/contacts/index.d.ts +1 -1
  576. package/dist/apps/www/contacts/index.js +19 -17
  577. package/dist/apps/www/index.d.ts +1 -1
  578. package/dist/apps/www/index.js +54 -50
  579. package/dist/apps/www/messages/[uid].d.ts +1 -1
  580. package/dist/apps/www/messages/[uid].js +11 -9
  581. package/dist/apps/www/settings/appearance/index.d.ts +1 -1
  582. package/dist/apps/www/settings/auto-reply/index.d.ts +1 -1
  583. package/dist/apps/www/settings/auto-reply/index.js +6 -4
  584. package/dist/apps/www/settings/blocked-senders/index.d.ts +1 -1
  585. package/dist/apps/www/settings/blocked-senders/index.js +6 -4
  586. package/dist/apps/www/settings/encryption/index.d.ts +1 -1
  587. package/dist/apps/www/settings/encryption/index.js +31 -29
  588. package/dist/apps/www/settings/filters/[uid].d.ts +1 -1
  589. package/dist/apps/www/settings/filters/[uid].js +11 -9
  590. package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +2 -2
  591. package/dist/apps/www/settings/filters/index.d.ts +1 -1
  592. package/dist/apps/www/settings/filters/index.js +4 -4
  593. package/dist/apps/www/settings/filters/new/index.d.ts +1 -1
  594. package/dist/apps/www/settings/filters/new/index.js +10 -8
  595. package/dist/apps/www/settings/labels/index.d.ts +1 -1
  596. package/dist/apps/www/settings/labels/index.js +12 -10
  597. package/dist/apps/www/settings/privacy/index.d.ts +1 -1
  598. package/dist/apps/www/settings/privacy/index.js +18 -14
  599. package/dist/apps/www/settings/profile/index.d.ts +1 -1
  600. package/dist/apps/www/settings/profile/index.js +7 -5
  601. package/dist/apps/www/settings/read-receipts/index.d.ts +1 -1
  602. package/dist/apps/www/settings/read-receipts/index.js +5 -3
  603. package/dist/apps/www/settings/sharing/index.d.ts +1 -1
  604. package/dist/apps/www/settings/sharing/index.js +6 -6
  605. package/dist/apps/www/settings/signatures/[uid].d.ts +1 -1
  606. package/dist/apps/www/settings/signatures/[uid].js +5 -5
  607. package/dist/apps/www/settings/signatures/index.d.ts +1 -1
  608. package/dist/apps/www/settings/signatures/index.js +4 -4
  609. package/dist/apps/www/settings/signatures/new/index.d.ts +1 -1
  610. package/dist/apps/www/settings/signatures/new/index.js +4 -4
  611. package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +1 -1
  612. package/dist/apps/www/settings/signatures/signatureDefaults.js +1 -1
  613. package/dist/apps/www/tasks/index.d.ts +1 -1
  614. package/dist/apps/www/tasks/index.js +17 -15
  615. package/dist/lib/admin/auditLogApi.d.ts +32 -0
  616. package/dist/lib/admin/auditLogApi.js +27 -0
  617. package/dist/lib/admin/distributionListsApi.d.ts +47 -0
  618. package/dist/lib/admin/distributionListsApi.js +34 -0
  619. package/dist/lib/admin/domainsApi.d.ts +75 -0
  620. package/dist/lib/admin/domainsApi.js +44 -0
  621. package/dist/lib/admin/escrowAccessRequestsApi.d.ts +79 -0
  622. package/dist/lib/admin/escrowAccessRequestsApi.js +46 -0
  623. package/dist/lib/admin/escrowAuditLogApi.d.ts +66 -0
  624. package/dist/lib/admin/escrowAuditLogApi.js +31 -0
  625. package/dist/lib/admin/escrowScopesApi.d.ts +78 -0
  626. package/dist/lib/admin/escrowScopesApi.js +50 -0
  627. package/dist/lib/admin/leftoverMailboxApi.d.ts +73 -0
  628. package/dist/lib/admin/leftoverMailboxApi.js +67 -0
  629. package/dist/lib/admin/mailboxPolicyApi.d.ts +27 -0
  630. package/dist/lib/admin/mailboxPolicyApi.js +21 -0
  631. package/dist/lib/admin/matterExportApi.d.ts +40 -0
  632. package/dist/lib/admin/matterExportApi.js +39 -0
  633. package/dist/lib/admin/matterSearchApi.d.ts +20 -0
  634. package/dist/lib/admin/matterSearchApi.js +27 -0
  635. package/dist/lib/admin/mattersApi.d.ts +56 -0
  636. package/dist/lib/admin/mattersApi.js +40 -0
  637. package/dist/lib/admin/pluginsApi.d.ts +265 -0
  638. package/dist/lib/admin/pluginsApi.js +102 -0
  639. package/dist/lib/admin/retentionPolicyApi.d.ts +32 -0
  640. package/dist/lib/admin/retentionPolicyApi.js +29 -0
  641. package/dist/lib/admin/setupApi.d.ts +23 -0
  642. package/dist/lib/admin/setupApi.js +26 -0
  643. package/dist/lib/admin/transportRulesApi.d.ts +66 -0
  644. package/dist/lib/admin/transportRulesApi.js +43 -0
  645. package/dist/lib/appearance/preferencesApi.d.ts +128 -0
  646. package/dist/lib/appearance/preferencesApi.js +257 -0
  647. package/dist/lib/auth/profileApi.d.ts +33 -0
  648. package/dist/lib/auth/profileApi.js +52 -0
  649. package/dist/lib/auth/session.d.ts +70 -0
  650. package/dist/lib/auth/session.js +210 -0
  651. package/dist/lib/branding/brandingApi.d.ts +47 -0
  652. package/dist/lib/branding/brandingApi.js +61 -0
  653. package/dist/lib/branding/useBranding.d.ts +23 -0
  654. package/dist/lib/branding/useBranding.js +65 -0
  655. package/dist/lib/calendar/calendarApi.d.ts +230 -0
  656. package/dist/lib/calendar/calendarApi.js +106 -0
  657. package/dist/lib/calendar/calendarColors.d.ts +18 -0
  658. package/dist/lib/calendar/calendarColors.js +39 -0
  659. package/dist/lib/calendar/calendarDragIds.d.ts +42 -0
  660. package/dist/lib/calendar/calendarDragIds.js +92 -0
  661. package/dist/lib/calendar/calendarMutations.d.ts +68 -0
  662. package/dist/lib/calendar/calendarMutations.js +190 -0
  663. package/dist/lib/calendar/eventDescription.d.ts +43 -0
  664. package/dist/lib/calendar/eventDescription.js +195 -0
  665. package/dist/lib/calendar/freeBusyApi.d.ts +100 -0
  666. package/dist/lib/calendar/freeBusyApi.js +119 -0
  667. package/dist/lib/calendar/inviteApi.d.ts +121 -0
  668. package/dist/lib/calendar/inviteApi.js +54 -0
  669. package/dist/lib/calendar/recurrence.d.ts +60 -0
  670. package/dist/lib/calendar/recurrence.js +225 -0
  671. package/dist/lib/components/avatar/ContactAvatar.d.ts +8 -0
  672. package/dist/lib/components/avatar/ContactAvatar.js +26 -0
  673. package/dist/lib/components/buttons/Button.d.ts +9 -0
  674. package/dist/lib/components/buttons/Button.js +14 -0
  675. package/dist/lib/components/buttons/CopyButton.d.ts +18 -0
  676. package/dist/lib/components/buttons/CopyButton.js +14 -0
  677. package/dist/lib/components/feedback/Alert.d.ts +4 -0
  678. package/dist/lib/components/feedback/Alert.js +4 -0
  679. package/dist/lib/components/feedback/Skeleton.d.ts +21 -0
  680. package/dist/lib/components/feedback/Skeleton.js +14 -0
  681. package/dist/lib/components/forms/FormField.d.ts +8 -0
  682. package/dist/lib/components/forms/FormField.js +5 -0
  683. package/dist/lib/components/navigation/BottomTabBar.d.ts +27 -0
  684. package/dist/lib/components/navigation/BottomTabBar.js +32 -0
  685. package/dist/lib/components/overlays/Drawer.d.ts +20 -0
  686. package/dist/lib/components/overlays/Drawer.js +27 -0
  687. package/dist/lib/components/overlays/Modal.d.ts +17 -0
  688. package/dist/lib/components/overlays/Modal.js +25 -0
  689. package/dist/lib/components/overlays/PopoverPortal.d.ts +23 -0
  690. package/dist/lib/components/overlays/PopoverPortal.js +53 -0
  691. package/dist/lib/components/overlays/overlayStack.d.ts +31 -0
  692. package/dist/lib/components/overlays/overlayStack.js +143 -0
  693. package/dist/lib/components/pickers/MiniDatePicker.d.ts +13 -0
  694. package/dist/lib/components/pickers/MiniDatePicker.js +42 -0
  695. package/dist/lib/contacts/contactsApi.d.ts +174 -0
  696. package/dist/lib/contacts/contactsApi.js +139 -0
  697. package/dist/lib/contacts/vcard.d.ts +23 -0
  698. package/dist/lib/contacts/vcard.js +179 -0
  699. package/dist/lib/crypto/composeSecurity.d.ts +67 -0
  700. package/dist/lib/crypto/composeSecurity.js +93 -0
  701. package/dist/lib/crypto/encoding.d.ts +9 -0
  702. package/dist/lib/crypto/encoding.js +32 -0
  703. package/dist/lib/crypto/escrowKeys.d.ts +25 -0
  704. package/dist/lib/crypto/escrowKeys.js +59 -0
  705. package/dist/lib/crypto/idleTimeout.d.ts +16 -0
  706. package/dist/lib/crypto/idleTimeout.js +47 -0
  707. package/dist/lib/crypto/keySession.d.ts +159 -0
  708. package/dist/lib/crypto/keySession.js +367 -0
  709. package/dist/lib/crypto/keys.d.ts +50 -0
  710. package/dist/lib/crypto/keys.js +89 -0
  711. package/dist/lib/crypto/keyvaultApi.d.ts +394 -0
  712. package/dist/lib/crypto/keyvaultApi.js +350 -0
  713. package/dist/lib/crypto/masterKey.d.ts +59 -0
  714. package/dist/lib/crypto/masterKey.js +104 -0
  715. package/dist/lib/crypto/masterKeyWraps.d.ts +108 -0
  716. package/dist/lib/crypto/masterKeyWraps.js +228 -0
  717. package/dist/lib/crypto/messageSecurity.d.ts +248 -0
  718. package/dist/lib/crypto/messageSecurity.js +367 -0
  719. package/dist/lib/crypto/mime.d.ts +143 -0
  720. package/dist/lib/crypto/mime.js +504 -0
  721. package/dist/lib/crypto/passkeyUnlock.d.ts +20 -0
  722. package/dist/lib/crypto/passkeyUnlock.js +79 -0
  723. package/dist/lib/crypto/passwordUnlock.d.ts +39 -0
  724. package/dist/lib/crypto/passwordUnlock.js +73 -0
  725. package/dist/lib/crypto/recoveryCode.d.ts +28 -0
  726. package/dist/lib/crypto/recoveryCode.js +86 -0
  727. package/dist/lib/crypto/signingProviderApi.d.ts +95 -0
  728. package/dist/lib/crypto/signingProviderApi.js +60 -0
  729. package/dist/lib/crypto/smime.d.ts +128 -0
  730. package/dist/lib/crypto/smime.js +402 -0
  731. package/dist/lib/crypto/smimeMessage.d.ts +132 -0
  732. package/dist/lib/crypto/smimeMessage.js +341 -0
  733. package/dist/lib/crypto/useIdleKeyTimeout.d.ts +10 -0
  734. package/dist/lib/crypto/useIdleKeyTimeout.js +163 -0
  735. package/dist/lib/crypto/verificationSeal.d.ts +56 -0
  736. package/dist/lib/crypto/verificationSeal.js +220 -0
  737. package/dist/lib/mail/compose/composeQuoting.d.ts +88 -0
  738. package/dist/lib/mail/compose/composeQuoting.js +204 -0
  739. package/dist/lib/mail/compose/emojiData.d.ts +9 -0
  740. package/dist/lib/mail/compose/emojiData.js +18 -0
  741. package/dist/lib/mail/compose/giphyApi.d.ts +17 -0
  742. package/dist/lib/mail/compose/giphyApi.js +20 -0
  743. package/dist/lib/mail/conversationsApi.d.ts +80 -0
  744. package/dist/lib/mail/conversationsApi.js +44 -0
  745. package/dist/lib/mail/dataExportApi.d.ts +50 -0
  746. package/dist/lib/mail/dataExportApi.js +40 -0
  747. package/dist/lib/mail/directoryApi.d.ts +49 -0
  748. package/dist/lib/mail/directoryApi.js +101 -0
  749. package/dist/lib/mail/erasureRequestApi.d.ts +45 -0
  750. package/dist/lib/mail/erasureRequestApi.js +43 -0
  751. package/dist/lib/mail/flaggedMessages.d.ts +22 -0
  752. package/dist/lib/mail/flaggedMessages.js +73 -0
  753. package/dist/lib/mail/focusedInboxOverridesApi.d.ts +37 -0
  754. package/dist/lib/mail/focusedInboxOverridesApi.js +34 -0
  755. package/dist/lib/mail/labelsApi.d.ts +47 -0
  756. package/dist/lib/mail/labelsApi.js +38 -0
  757. package/dist/lib/mail/mailAddress.d.ts +27 -0
  758. package/dist/lib/mail/mailAddress.js +54 -0
  759. package/dist/lib/mail/mailApi.d.ts +850 -0
  760. package/dist/lib/mail/mailApi.js +602 -0
  761. package/dist/lib/mail/mailDetailHooks.d.ts +10 -0
  762. package/dist/lib/mail/mailDetailHooks.js +53 -0
  763. package/dist/lib/mail/mailFilterRulesApi.d.ts +76 -0
  764. package/dist/lib/mail/mailFilterRulesApi.js +45 -0
  765. package/dist/lib/mail/mailSignaturesApi.d.ts +49 -0
  766. package/dist/lib/mail/mailSignaturesApi.js +42 -0
  767. package/dist/lib/mail/mailboxAccessApi.d.ts +74 -0
  768. package/dist/lib/mail/mailboxAccessApi.js +56 -0
  769. package/dist/lib/mail/mailboxImportApi.d.ts +53 -0
  770. package/dist/lib/mail/mailboxImportApi.js +51 -0
  771. package/dist/lib/mail/messageBodySanitizer.d.ts +16 -0
  772. package/dist/lib/mail/messageBodySanitizer.js +118 -0
  773. package/dist/lib/mail/pushClient.d.ts +106 -0
  774. package/dist/lib/mail/pushClient.js +317 -0
  775. package/dist/lib/mail/sendEvents.d.ts +33 -0
  776. package/dist/lib/mail/sendEvents.js +44 -0
  777. package/dist/lib/mail/sendFailure.d.ts +16 -0
  778. package/dist/lib/mail/sendFailure.js +86 -0
  779. package/dist/lib/mail/senderListsApi.d.ts +69 -0
  780. package/dist/lib/mail/senderListsApi.js +126 -0
  781. package/dist/lib/search/queryGrammar.d.ts +51 -0
  782. package/dist/lib/search/queryGrammar.js +111 -0
  783. package/dist/lib/search/searchApi.d.ts +100 -0
  784. package/dist/lib/search/searchApi.js +107 -0
  785. package/dist/lib/search/searchScoring.d.ts +34 -0
  786. package/dist/lib/search/searchScoring.js +44 -0
  787. package/dist/lib/search/searchTier3.d.ts +64 -0
  788. package/dist/lib/search/searchTier3.js +335 -0
  789. package/dist/lib/tasks/tasksApi.d.ts +85 -0
  790. package/dist/lib/tasks/tasksApi.js +55 -0
  791. package/dist/lib/util/api.d.ts +160 -0
  792. package/dist/lib/util/api.js +251 -0
  793. package/dist/lib/util/apiClientContext.d.ts +7 -0
  794. package/dist/lib/util/apiClientContext.js +32 -0
  795. package/dist/lib/util/apiQuery.d.ts +32 -0
  796. package/dist/lib/util/apiQuery.js +42 -0
  797. package/dist/lib/util/clipboard.d.ts +7 -0
  798. package/dist/lib/util/clipboard.js +56 -0
  799. package/dist/lib/util/dateInput.d.ts +6 -0
  800. package/dist/lib/util/dateInput.js +14 -0
  801. package/dist/lib/util/timeZone.d.ts +12 -0
  802. package/dist/lib/util/timeZone.js +32 -0
  803. package/dist/lib/util/useCopyToClipboard.d.ts +12 -0
  804. package/dist/lib/util/useCopyToClipboard.js +34 -0
  805. package/dist/lib/util/useIsMobile.d.ts +10 -0
  806. package/dist/lib/util/useIsMobile.js +29 -0
  807. package/dist/lib/videoconf/videoMeetingsApi.d.ts +116 -0
  808. package/dist/lib/videoconf/videoMeetingsApi.js +49 -0
  809. package/lib/admin/auditLogApi.ts +48 -0
  810. package/lib/admin/distributionListsApi.ts +77 -0
  811. package/lib/admin/domainsApi.ts +113 -0
  812. package/lib/admin/escrowAccessRequestsApi.ts +110 -0
  813. package/lib/admin/escrowAuditLogApi.ts +101 -0
  814. package/lib/admin/escrowScopesApi.ts +112 -0
  815. package/lib/admin/leftoverMailboxApi.ts +120 -0
  816. package/lib/admin/mailboxPolicyApi.ts +38 -0
  817. package/lib/admin/matterExportApi.ts +62 -0
  818. package/lib/admin/matterSearchApi.ts +35 -0
  819. package/lib/admin/mattersApi.ts +86 -0
  820. package/lib/admin/pluginsApi.ts +339 -0
  821. package/lib/admin/retentionPolicyApi.ts +46 -0
  822. package/lib/admin/setupApi.ts +40 -0
  823. package/lib/admin/transportRulesApi.ts +106 -0
  824. package/lib/appearance/preferencesApi.ts +335 -0
  825. package/lib/auth/profileApi.ts +77 -0
  826. package/lib/auth/session.ts +238 -0
  827. package/lib/branding/brandingApi.ts +97 -0
  828. package/lib/branding/useBranding.ts +81 -0
  829. package/lib/calendar/calendarApi.ts +309 -0
  830. package/lib/calendar/calendarColors.ts +45 -0
  831. package/lib/calendar/calendarDragIds.ts +112 -0
  832. package/lib/calendar/calendarMutations.ts +236 -0
  833. package/lib/calendar/eventDescription.ts +211 -0
  834. package/lib/calendar/freeBusyApi.ts +197 -0
  835. package/lib/calendar/inviteApi.ts +154 -0
  836. package/lib/calendar/recurrence.ts +285 -0
  837. package/lib/components/avatar/ContactAvatar.tsx +47 -0
  838. package/lib/components/buttons/Button.tsx +40 -0
  839. package/lib/components/buttons/CopyButton.tsx +45 -0
  840. package/lib/components/feedback/Alert.tsx +13 -0
  841. package/lib/components/feedback/Skeleton.tsx +38 -0
  842. package/lib/components/forms/FormField.tsx +23 -0
  843. package/lib/components/navigation/BottomTabBar.tsx +66 -0
  844. package/lib/components/overlays/Drawer.tsx +72 -0
  845. package/lib/components/overlays/Modal.tsx +64 -0
  846. package/lib/components/overlays/PopoverPortal.tsx +74 -0
  847. package/lib/components/overlays/overlayStack.ts +165 -0
  848. package/lib/components/pickers/MiniDatePicker.tsx +90 -0
  849. package/lib/contacts/contactsApi.ts +289 -0
  850. package/lib/contacts/vcard.ts +197 -0
  851. package/lib/crypto/composeSecurity.ts +140 -0
  852. package/lib/crypto/encoding.ts +36 -0
  853. package/lib/crypto/escrowKeys.ts +74 -0
  854. package/lib/crypto/idleTimeout.ts +49 -0
  855. package/lib/crypto/keySession.ts +483 -0
  856. package/lib/crypto/keys.ts +105 -0
  857. package/lib/crypto/keyvaultApi.ts +674 -0
  858. package/lib/crypto/masterKey.ts +134 -0
  859. package/lib/crypto/masterKeyWraps.ts +269 -0
  860. package/lib/crypto/messageSecurity.ts +600 -0
  861. package/lib/crypto/mime.ts +568 -0
  862. package/lib/crypto/passkeyUnlock.ts +103 -0
  863. package/lib/crypto/passwordUnlock.ts +98 -0
  864. package/lib/crypto/recoveryCode.ts +93 -0
  865. package/lib/crypto/signingProviderApi.ts +135 -0
  866. package/lib/crypto/smime.ts +459 -0
  867. package/lib/crypto/smimeMessage.ts +491 -0
  868. package/lib/crypto/useIdleKeyTimeout.ts +176 -0
  869. package/lib/crypto/verificationSeal.ts +288 -0
  870. package/lib/mail/compose/composeQuoting.ts +243 -0
  871. package/lib/mail/compose/emojiData.ts +34 -0
  872. package/lib/mail/compose/giphyApi.ts +31 -0
  873. package/lib/mail/conversationsApi.ts +123 -0
  874. package/lib/mail/dataExportApi.ts +73 -0
  875. package/lib/mail/directoryApi.ts +161 -0
  876. package/lib/mail/erasureRequestApi.ts +71 -0
  877. package/lib/mail/flaggedMessages.ts +80 -0
  878. package/lib/mail/focusedInboxOverridesApi.ts +64 -0
  879. package/lib/mail/labelsApi.ts +71 -0
  880. package/lib/mail/mailAddress.ts +76 -0
  881. package/lib/mail/mailApi.ts +1286 -0
  882. package/lib/mail/mailDetailHooks.ts +57 -0
  883. package/lib/mail/mailFilterRulesApi.ts +116 -0
  884. package/lib/mail/mailSignaturesApi.ts +84 -0
  885. package/lib/mail/mailboxAccessApi.ts +106 -0
  886. package/lib/mail/mailboxImportApi.ts +87 -0
  887. package/lib/mail/messageBodySanitizer.ts +129 -0
  888. package/lib/mail/pushClient.ts +375 -0
  889. package/lib/mail/sendEvents.ts +72 -0
  890. package/lib/mail/sendFailure.ts +98 -0
  891. package/lib/mail/senderListsApi.ts +161 -0
  892. package/lib/search/queryGrammar.ts +179 -0
  893. package/lib/search/searchApi.ts +199 -0
  894. package/lib/search/searchScoring.ts +46 -0
  895. package/lib/search/searchTier3.ts +406 -0
  896. package/lib/tasks/tasksApi.ts +128 -0
  897. package/lib/util/api.ts +318 -0
  898. package/lib/util/apiClientContext.ts +35 -0
  899. package/lib/util/apiQuery.ts +61 -0
  900. package/lib/util/clipboard.ts +55 -0
  901. package/lib/util/dateInput.ts +15 -0
  902. package/lib/util/timeZone.ts +33 -0
  903. package/lib/util/useCopyToClipboard.ts +48 -0
  904. package/lib/util/useIsMobile.ts +34 -0
  905. package/lib/videoconf/videoMeetingsApi.ts +144 -0
  906. package/package.json +10 -4
@@ -1,443 +1,450 @@
1
- ///////////////////////////////////////////////////////////////////////////////
2
- // Copyright (C) 2026 Jean-Philippe Steinmetz
3
- // SPDX-License-Identifier: MPL-2.0
4
- ///////////////////////////////////////////////////////////////////////////////
5
- import { ReactElement, useState } from "react";
6
- import {
7
- Folder,
8
- Message,
9
- MessageReportKind,
10
- MessageReportResult,
11
- getMessageRawContent,
12
- moveMessage,
13
- reportMessage,
14
- setMessageFlagged,
15
- } from "@rapidmx/react-shared/mail/mailApi.js";
16
- import {
17
- SenderListsChange,
18
- addBlockedSender,
19
- addSafeSender,
20
- checkSenderEntry,
21
- removeBlockedSender,
22
- removeSafeSender,
23
- } from "@rapidmx/react-shared/mail/senderListsApi.js";
24
- import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
25
- import type { CountTracker } from "../../../mail/folderCounts.js";
26
- import { resolveFolderOfType } from "../../../mail/folderOfType.js";
27
- import { setReadStateMany } from "../../../mail/messageReadState.js";
28
- import { usePermanentDelete } from "../../../mail/usePermanentDelete.js";
29
- import { reportFolderName, reportNotice, reportNoun, reportTitle, senderListsHref } from "../../../mail/reportNotices.js";
30
- import { blockSender, neverBlockSender, normalizeAddresses, removeSenderRule } from "../../../mail/senderBlocking.js";
31
- import { notifyApiError } from "../../../notifications/apiErrors.js";
32
- import { notify } from "../../../notifications/store.js";
33
- import { moveLocalEntity } from "../../../search/localIndexRpcClient.js";
34
- import { displaySubject } from "./EncryptedPreview.js";
35
- import { headerFromAddress } from "./messageExport.js";
36
-
37
- export interface MessageActionsParams {
38
- /** The message the card shows, and the newest copy of it known (a version another action of the card has since raised). */
39
- message: Message;
40
- newest: () => Message;
41
- /** Records a newer copy, so the next action builds on its `version`. */
42
- remember: (updated: Message) => void;
43
- /** Every folder of the message's mailbox - `resolveFolderOfType()` finds Junk Email, Deleted Items and the Inbox among them. */
44
- folders: Folder[] | undefined;
45
- inJunk: boolean;
46
- /** The message is in its mailbox's Deleted Items: Delete is then the permanent one (asked first, see `usePermanentDelete()`). */
47
- inDeletedItems: boolean;
48
- /** Every address the reader owns (their mailboxes' primary addresses and aliases), lowercase: a sender among them is never blocked. */
49
- ownAddresses?: readonly string[];
50
- trackMessageChange: (previous: Message, next: Message | null) => CountTracker;
51
- /** The message left the folder it was in (Delete, Report junk, Block): the caller takes it out of its list, or the thread. */
52
- onMoved?: (updated: Message) => void;
53
- /** A newer copy of the message that is still where it was (read, flagged), with the copy it replaces. */
54
- onChanged?: (updated: Message, previous?: Message) => void;
55
- onFolderCreated?: (folder: Folder) => void;
56
- }
57
-
58
- export interface MessageActions {
59
- /** An action is on the wire: the card's other actions wait for it. */
60
- busy: boolean;
61
- /** The permanent-delete confirmation - render it once (it is a portal). */
62
- dialog: ReactElement;
63
- reportJunk: () => Promise<void>;
64
- reportPhishing: () => Promise<void>;
65
- /** Not junk: to the Inbox, and the spam filter is told the message is legitimate. */
66
- notJunk: () => Promise<void>;
67
- /** Not junk, and the sender is added to the mailbox's Safe Senders (needs full access to the mailbox). */
68
- notJunkAndTrust: () => Promise<void>;
69
- deleteMessage: () => Promise<void>;
70
- toggleRead: () => Promise<void>;
71
- toggleFlag: () => Promise<void>;
72
- blockSender: () => Promise<void>;
73
- neverBlockSender: () => Promise<void>;
74
- }
75
-
76
- /** Where a notification's "View rules" goes: the filters page of the mailbox. */
77
- export function rulesHref(mailboxUid: string): string {
78
- return `/settings/filters?mailboxUid=${encodeURIComponent(mailboxUid)}`;
79
- }
80
-
81
- /** Whether `err` is a `404`: for a route, what a server that predates it answers (a message or mailbox that is gone answers the same, and the fallback then fails the same way). */
82
- function isNotFound(err: unknown): boolean {
83
- return err instanceof ApiRequestError && err.status === 404;
84
- }
85
-
86
- /**
87
- * What a message card's Report junk, Report phishing, Not junk, Delete, Mark as read/unread, Flag, Block and Never block do.
88
- *
89
- * - **Report junk, phishing and Not junk** ask the SERVER to do it (`reportMessage()`): it moves the message, teaches its spam filter and audits the report,
90
- * and the card then does what a move did (the folder badges, the search index, taking the message out of its list). A server that predates the route answers
91
- * `404`, and the card then makes the move itself (`moveMessage()`), as it used to, so a new client still works.
92
- * - **Block** adds the sender to the message's OWN mailbox's Blocked Senders (`addBlockedSender()`) and moves the message to Junk Email; **Never block** adds it to
93
- * Safe Senders, which takes it off the blocked list. On a server without the lists (`404`) both fall back to mail filter rules (`senderBlocking.ts`).
94
- * - The rest go over the same requests the mail page's selection bar and keyboard shortcuts make - a move is a move into the message's OWN mailbox's Junk Email or
95
- * Deleted Items folder (`resolveFolderOfType()`), a read or flag change goes through the same optimistic path - so a card opened from a shared mailbox, or from a
96
- * search over several, acts in the mailbox the message is in.
97
- *
98
- * A failure is a pop-up that says what could not be done (`notifyApiError()`), as the selection bar's are. Nothing here rejects.
99
- */
100
- export function useMessageActions(params: MessageActionsParams): MessageActions {
101
- const { message, newest, remember, folders, inJunk, inDeletedItems, ownAddresses = [], trackMessageChange, onMoved, onChanged, onFolderCreated } = params;
102
- const [busy, setBusy] = useState(false);
103
- const permanent = usePermanentDelete();
104
-
105
- /** Runs one action with the card's other actions held meanwhile. */
106
- async function exclusive(action: () => Promise<void>): Promise<void> {
107
- setBusy(true);
108
- try {
109
- await action();
110
- } finally {
111
- setBusy(false);
112
- }
113
- }
114
-
115
- function folderOf(type: Folder["type"], name: string): Promise<string> {
116
- return resolveFolderOfType(message.mailboxUid, type, name, folders, onFolderCreated);
117
- }
118
-
119
- /** The card's part of a message having left its folder for `updated`'s: the folder badges and the local search index. */
120
- function relocated(before: Message, updated: Message): void {
121
- remember(updated);
122
- void moveLocalEntity(updated.mailboxUid, updated.uid, updated.folderUid);
123
- trackMessageChange(before, updated).settle();
124
- }
125
-
126
- /** Moves the message into its mailbox's folder of `type`, and tells the folder badges and the local search index. */
127
- async function moveToType(type: Folder["type"], name: string): Promise<Message> {
128
- const before = newest();
129
- const updated = await moveMessage(before, await folderOf(type, name));
130
- relocated(before, updated);
131
- return updated;
132
- }
133
-
134
- const subjectOf = () => displaySubject(message.subject) || "(no subject)";
135
-
136
- /** What the server did with a report, as the card shows it: the message is out of its list (when it moved) and a pop-up says what happened. */
137
- function reported(result: MessageReportResult, alwaysTrust: boolean): void {
138
- const before = newest();
139
- if (result.folderUid !== before.folderUid) {
140
- // The answer names no new `version`; the message is out of the card's list now, so nothing builds on this copy.
141
- const updated: Message = { ...before, folderUid: result.folderUid };
142
- relocated(before, updated);
143
- onMoved?.(updated);
144
- }
145
- const notice = reportNotice(result, subjectOf(), alwaysTrust);
146
- const safeSender = result.safeSender;
147
- notify({
148
- kind: "success",
149
- title: notice.title,
150
- message: notice.message,
151
- hint: notice.hint,
152
- actions: safeSender
153
- ? [
154
- {
155
- label: "Undo",
156
- onClick: () => {
157
- removeSafeSender(message.mailboxUid, safeSender).then(
158
- () => notify({ kind: "info", title: `${safeSender} is no longer a safe sender`, message: "This message stays in the Inbox." }),
159
- (err) => notifyApiError(err, "Couldn't undo trusting this sender"),
160
- );
161
- },
162
- },
163
- { label: "Manage safe senders", href: senderListsHref(message.mailboxUid) },
164
- ]
165
- : undefined,
166
- });
167
- }
168
-
169
- /** What a server that has no report route leaves: the move alone, in the message's own mailbox, and nothing learned. */
170
- async function reportByMoving(kind: MessageReportKind, alwaysTrust: boolean): Promise<void> {
171
- const toInbox = kind === "not_junk";
172
- let updated: Message;
173
- try {
174
- updated = await moveToType(toInbox ? "inbox" : "junk", toInbox ? "Inbox" : "Junk Email");
175
- } catch (err) {
176
- notifyApiError(err, `Couldn't report this message as ${reportNoun(kind)}`);
177
- return;
178
- }
179
- onMoved?.(updated);
180
- notify({
181
- kind: "success",
182
- title: reportTitle(kind),
183
- message: `“${subjectOf()}” was moved to ${reportFolderName(kind)}.${alwaysTrust ? " This server cannot keep a list of safe senders, so its sender was not added to one." : ""}`,
184
- });
185
- }
186
-
187
- async function report(kind: MessageReportKind, alwaysTrustSender = false): Promise<void> {
188
- await exclusive(async () => {
189
- let result: MessageReportResult;
190
- try {
191
- result = await reportMessage(message.uid, kind, { alwaysTrustSender });
192
- } catch (err) {
193
- if (isNotFound(err)) {
194
- await reportByMoving(kind, alwaysTrustSender);
195
- } else {
196
- notifyApiError(err, `Couldn't report this message as ${reportNoun(kind)}`);
197
- }
198
- return;
199
- }
200
- reported(result, alwaysTrustSender);
201
- });
202
- }
203
-
204
- async function deleteMessage(): Promise<void> {
205
- await exclusive(async () => {
206
- if (inDeletedItems) {
207
- // Nowhere further to move it: asks first, deletes for good and tells the badges, the search index and the reader itself.
208
- const outcome = await permanent.requestPermanentDelete([message]);
209
- if (outcome && outcome.deleted.length > 0) {
210
- onMoved?.(message);
211
- }
212
- return;
213
- }
214
- try {
215
- // Awaited on its own line: an optional call with no callee never evaluates its arguments, so with no `onMoved` nothing would be moved.
216
- const updated = await moveToType("deleted_items", "Deleted Items");
217
- onMoved?.(updated);
218
- } catch (err) {
219
- notifyApiError(err, "Couldn't delete this message");
220
- }
221
- });
222
- }
223
-
224
- async function toggleRead(): Promise<void> {
225
- await exclusive(async () => {
226
- const before = newest();
227
- try {
228
- await setReadStateMany([before], before.flags.read !== true, {
229
- patch: (updated, previous) => {
230
- remember(updated);
231
- onChanged?.(updated, previous);
232
- },
233
- track: trackMessageChange,
234
- });
235
- } catch (err) {
236
- notifyApiError(err, "Couldn't update the message");
237
- }
238
- });
239
- }
240
-
241
- async function toggleFlag(): Promise<void> {
242
- await exclusive(async () => {
243
- const before = newest();
244
- try {
245
- const updated = await setMessageFlagged(before, before.flags.flagged !== true);
246
- remember(updated);
247
- onChanged?.(updated, before);
248
- } catch (err) {
249
- notifyApiError(err, "Couldn't update the message");
250
- }
251
- });
252
- }
253
-
254
- /** The sender of this message as a list entry needs it: the address in its From header - what the reader sees, and what the mail server matches a list
255
- * against (with the envelope sender) - or, without one, the address the message is filed under. `all` is both, for the filter rules of a server without lists. */
256
- async function senders(): Promise<{ listed: string | undefined; all: string[] }> {
257
- const raw = await getMessageRawContent(message.uid).catch(() => undefined);
258
- const header = raw === undefined ? undefined : headerFromAddress(raw);
259
- return { listed: normalizeAddresses([header, message.from.address])[0], all: normalizeAddresses([message.from.address, header]) };
260
- }
261
-
262
- /** Whether `address` can go on a list (a plain address the mail server accepts); a pop-up says so when it cannot. */
263
- function listable(address: string | undefined, title: string): address is string {
264
- const checked = address === undefined ? undefined : checkSenderEntry(address);
265
- if (address !== undefined && checked?.ok && checked.kind === "address") {
266
- return true;
267
- }
268
- notify({ kind: "error", title, message: "This message has no sender address that can be put on a list." });
269
- return false;
270
- }
271
-
272
- /** Files the message in its mailbox's Junk Email when it is not there yet, and says where it ended up. */
273
- async function moveToJunkUnlessThere(): Promise<string> {
274
- if (inJunk) {
275
- return "This message is already in Junk Email.";
276
- }
277
- try {
278
- const moved = await moveToType("junk", "Junk Email");
279
- onMoved?.(moved);
280
- return "This message was moved there.";
281
- } catch (err) {
282
- notifyApiError(err, "Couldn't move this message to Junk Email");
283
- return "This message is still where it was.";
284
- }
285
- }
286
-
287
- /** Block, on a server without sender lists: the mailbox's mail filter rules. */
288
- async function blockWithRules(addresses: string[], address: string): Promise<void> {
289
- let result: Awaited<ReturnType<typeof blockSender>>;
290
- try {
291
- const [junkUid, inboxUid] = await Promise.all([folderOf("junk", "Junk Email"), folderOf("inbox", "Inbox")]);
292
- result = await blockSender(message.mailboxUid, addresses, junkUid, inboxUid);
293
- } catch (err) {
294
- notifyApiError(err, "Couldn't block this sender");
295
- return;
296
- }
297
- const where = await moveToJunkUnlessThere();
298
- notify({
299
- kind: result.outcome === "existing" ? "info" : "success",
300
- title: result.outcome === "existing" ? `${address} is already blocked` : `Blocked ${address}`,
301
- message: `New mail from this address goes to Junk Email. ${where}`,
302
- hint: "This server has no list of blocked senders, so the block is a filter rule that matches any sender address containing this one.",
303
- actions: [
304
- ...(result.outcome === "created"
305
- ? [
306
- {
307
- label: "Undo",
308
- onClick: () => {
309
- removeSenderRule(result.rule).then(
310
- () => notify({ kind: "info", title: `Unblocked ${address}`, message: "The block was removed. This message stays where it is." }),
311
- (err) => notifyApiError(err, "Couldn't undo the block"),
312
- );
313
- },
314
- },
315
- ]
316
- : []),
317
- { label: "View rules", href: rulesHref(message.mailboxUid) },
318
- ],
319
- });
320
- }
321
-
322
- async function block(): Promise<void> {
323
- await exclusive(async () => {
324
- const { listed, all } = await senders();
325
- if (!listable(listed, "Couldn't block this sender")) {
326
- return;
327
- }
328
- if (ownAddresses.includes(listed)) {
329
- notify({ kind: "info", title: "That is your own address", message: `${listed} is one of your addresses, so it is not blocked.` });
330
- return;
331
- }
332
- let added: SenderListsChange;
333
- try {
334
- added = await addBlockedSender(message.mailboxUid, listed);
335
- } catch (err) {
336
- if (isNotFound(err)) {
337
- await blockWithRules(all, message.from.address);
338
- } else {
339
- notifyApiError(err, "Couldn't block this sender");
340
- }
341
- return;
342
- }
343
- const where = await moveToJunkUnlessThere();
344
- notify({
345
- kind: added.changed ? "success" : "info",
346
- title: added.changed ? `Blocked ${listed}` : `${listed} is already blocked`,
347
- message: `New mail from this address goes to Junk Email. ${where}`,
348
- actions: [
349
- ...(added.changed
350
- ? [
351
- {
352
- label: "Undo",
353
- onClick: () => {
354
- removeBlockedSender(message.mailboxUid, listed).then(
355
- () => notify({ kind: "info", title: `Unblocked ${listed}`, message: "The block was removed. This message stays where it is." }),
356
- (err) => notifyApiError(err, "Couldn't undo the block"),
357
- );
358
- },
359
- },
360
- ]
361
- : []),
362
- { label: "Manage blocked senders", href: senderListsHref(message.mailboxUid) },
363
- ],
364
- });
365
- });
366
- }
367
-
368
- /** Never block, on a server without sender lists: the rule that keeps the sender's mail in the Inbox. */
369
- async function neverBlockWithRules(addresses: string[], address: string): Promise<void> {
370
- let result: Awaited<ReturnType<typeof neverBlockSender>>;
371
- try {
372
- const [junkUid, inboxUid] = await Promise.all([folderOf("junk", "Junk Email"), folderOf("inbox", "Inbox")]);
373
- result = await neverBlockSender(message.mailboxUid, addresses, junkUid, inboxUid);
374
- } catch (err) {
375
- notifyApiError(err, "Couldn't stop blocking this sender");
376
- return;
377
- }
378
- const unblocked = result.removed.length > 0 ? "The block on this sender was removed. " : "";
379
- notify({
380
- kind: result.outcome === "existing" && !unblocked ? "info" : "success",
381
- title: result.outcome === "existing" && !unblocked ? `${address} is already never blocked` : `Never blocking ${address}`,
382
- message: `${unblocked}New mail from this address stays in your Inbox, ahead of your other filters. Mail the spam filter judges to be junk still goes to Junk Email.`,
383
- actions: [{ label: "View rules", href: rulesHref(message.mailboxUid) }],
384
- });
385
- }
386
-
387
- async function neverBlock(): Promise<void> {
388
- await exclusive(async () => {
389
- const { listed, all } = await senders();
390
- if (!listable(listed, "Couldn't stop blocking this sender")) {
391
- return;
392
- }
393
- let added: SenderListsChange;
394
- try {
395
- added = await addSafeSender(message.mailboxUid, listed);
396
- } catch (err) {
397
- if (isNotFound(err)) {
398
- await neverBlockWithRules(all, message.from.address);
399
- } else {
400
- notifyApiError(err, "Couldn't stop blocking this sender");
401
- }
402
- return;
403
- }
404
- notify({
405
- kind: added.changed ? "success" : "info",
406
- title: added.changed ? `Never blocking ${listed}` : `${listed} is already a safe sender`,
407
- message:
408
- "Any block on this address is removed. Mail from it that passes authentication is delivered to your Inbox instead of Junk Email; " +
409
- "mail that fails authentication, carries a virus or is quarantined by policy is still kept out.",
410
- actions: [
411
- ...(added.changed
412
- ? [
413
- {
414
- label: "Undo",
415
- onClick: () => {
416
- removeSafeSender(message.mailboxUid, listed).then(
417
- () => notify({ kind: "info", title: `${listed} is no longer a safe sender`, message: "Its mail is filtered as usual again." }),
418
- (err) => notifyApiError(err, "Couldn't undo the change"),
419
- );
420
- },
421
- },
422
- ]
423
- : []),
424
- { label: "Manage safe senders", href: senderListsHref(message.mailboxUid) },
425
- ],
426
- });
427
- });
428
- }
429
-
430
- return {
431
- busy: busy || permanent.busy,
432
- dialog: permanent.dialog,
433
- reportJunk: () => report("junk"),
434
- reportPhishing: () => report("phishing"),
435
- notJunk: () => report("not_junk"),
436
- notJunkAndTrust: () => report("not_junk", true),
437
- deleteMessage,
438
- toggleRead,
439
- toggleFlag,
440
- blockSender: block,
441
- neverBlockSender: neverBlock,
442
- };
443
- }
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import { ReactElement, useState } from "react";
6
+ import {
7
+ Folder,
8
+ Message,
9
+ MessageReportKind,
10
+ MessageReportResult,
11
+ getMessageRawContent,
12
+ moveMessage,
13
+ reportMessage,
14
+ setMessageFlagged,
15
+ } from "../../../../../lib/mail/mailApi.js";
16
+ import {
17
+ SenderListsChange,
18
+ addBlockedSender,
19
+ addSafeSender,
20
+ checkSenderEntry,
21
+ removeBlockedSender,
22
+ removeSafeSender,
23
+ } from "../../../../../lib/mail/senderListsApi.js";
24
+ import { ApiRequestError } from "../../../../../lib/util/api.js";
25
+ import { useApiClient } from "../../../../../lib/util/apiClientContext.js";
26
+ import type { CountTracker } from "../../../mail/folderCounts.js";
27
+ import { resolveFolderOfType } from "../../../mail/folderOfType.js";
28
+ import { setReadStateMany } from "../../../mail/messageReadState.js";
29
+ import { usePermanentDelete } from "../../../mail/usePermanentDelete.js";
30
+ import { reportFolderName, reportNotice, reportNoun, reportTitle, senderListsHref } from "../../../mail/reportNotices.js";
31
+ import { blockSender, neverBlockSender, normalizeAddresses, removeSenderRule } from "../../../mail/senderBlocking.js";
32
+ import { notifyApiError } from "../../../notifications/apiErrors.js";
33
+ import { notify } from "../../../notifications/store.js";
34
+ import { moveLocalEntity } from "../../../search/localIndexRpcClient.js";
35
+ import { displaySubject } from "./EncryptedPreview.js";
36
+ import { headerFromAddress } from "./messageExport.js";
37
+
38
+ export interface MessageActionsParams {
39
+ /** The message the card shows, and the newest copy of it known (a version another action of the card has since raised). */
40
+ message: Message;
41
+ newest: () => Message;
42
+ /** Records a newer copy, so the next action builds on its `version`. */
43
+ remember: (updated: Message) => void;
44
+ /** Every folder of the message's mailbox - `resolveFolderOfType()` finds Junk Email, Deleted Items and the Inbox among them. */
45
+ folders: Folder[] | undefined;
46
+ inJunk: boolean;
47
+ /** The message is in its mailbox's Deleted Items: Delete is then the permanent one (asked first, see `usePermanentDelete()`). */
48
+ inDeletedItems: boolean;
49
+ /** Every address the reader owns (their mailboxes' primary addresses and aliases), lowercase: a sender among them is never blocked. */
50
+ ownAddresses?: readonly string[];
51
+ trackMessageChange: (previous: Message, next: Message | null) => CountTracker;
52
+ /** The message left the folder it was in (Delete, Report junk, Block): the caller takes it out of its list, or the thread. */
53
+ onMoved?: (updated: Message) => void;
54
+ /** A newer copy of the message that is still where it was (read, flagged), with the copy it replaces. */
55
+ onChanged?: (updated: Message, previous?: Message) => void;
56
+ onFolderCreated?: (folder: Folder) => void;
57
+ }
58
+
59
+ export interface MessageActions {
60
+ /** An action is on the wire: the card's other actions wait for it. */
61
+ busy: boolean;
62
+ /** The permanent-delete confirmation - render it once (it is a portal). */
63
+ dialog: ReactElement;
64
+ reportJunk: () => Promise<void>;
65
+ reportPhishing: () => Promise<void>;
66
+ /** Not junk: to the Inbox, and the spam filter is told the message is legitimate. */
67
+ notJunk: () => Promise<void>;
68
+ /** Not junk, and the sender is added to the mailbox's Safe Senders (needs full access to the mailbox). */
69
+ notJunkAndTrust: () => Promise<void>;
70
+ deleteMessage: () => Promise<void>;
71
+ toggleRead: () => Promise<void>;
72
+ toggleFlag: () => Promise<void>;
73
+ blockSender: () => Promise<void>;
74
+ neverBlockSender: () => Promise<void>;
75
+ }
76
+
77
+ /** Where a notification's "View rules" goes: the filters page of the mailbox. */
78
+ export function rulesHref(mailboxUid: string): string {
79
+ return `/settings/filters?mailboxUid=${encodeURIComponent(mailboxUid)}`;
80
+ }
81
+
82
+ /** Whether `err` is a `404`: for a route, what a server that predates it answers (a message or mailbox that is gone answers the same, and the fallback then fails the same way). */
83
+ function isNotFound(err: unknown): boolean {
84
+ return err instanceof ApiRequestError && err.status === 404;
85
+ }
86
+
87
+ /**
88
+ * What a message card's Report junk, Report phishing, Not junk, Delete, Mark as read/unread, Flag, Block and Never block do.
89
+ *
90
+ * - **Report junk, phishing and Not junk** ask the SERVER to do it (`reportMessage()`): it moves the message, teaches its spam filter and audits the report,
91
+ * and the card then does what a move did (the folder badges, the search index, taking the message out of its list). A server that predates the route answers
92
+ * `404`, and the card then makes the move itself (`moveMessage()`), as it used to, so a new client still works.
93
+ * - **Block** adds the sender to the message's OWN mailbox's Blocked Senders (`addBlockedSender()`) and moves the message to Junk Email; **Never block** adds it to
94
+ * Safe Senders, which takes it off the blocked list. On a server without the lists (`404`) both fall back to mail filter rules (`senderBlocking.ts`).
95
+ * - The rest go over the same requests the mail page's selection bar and keyboard shortcuts make - a move is a move into the message's OWN mailbox's Junk Email or
96
+ * Deleted Items folder (`resolveFolderOfType()`), a read or flag change goes through the same optimistic path - so a card opened from a shared mailbox, or from a
97
+ * search over several, acts in the mailbox the message is in.
98
+ *
99
+ * A failure is a pop-up that says what could not be done (`notifyApiError()`), as the selection bar's are. Nothing here rejects.
100
+ */
101
+ export function useMessageActions(params: MessageActionsParams): MessageActions {
102
+ const { message, newest, remember, folders, inJunk, inDeletedItems, ownAddresses = [], trackMessageChange, onMoved, onChanged, onFolderCreated } = params;
103
+ const [busy, setBusy] = useState(false);
104
+ const client = useApiClient();
105
+ const permanent = usePermanentDelete();
106
+
107
+ /** Runs one action with the card's other actions held meanwhile. */
108
+ async function exclusive(action: () => Promise<void>): Promise<void> {
109
+ setBusy(true);
110
+ try {
111
+ await action();
112
+ } finally {
113
+ setBusy(false);
114
+ }
115
+ }
116
+
117
+ function folderOf(type: Folder["type"], name: string): Promise<string> {
118
+ return resolveFolderOfType(message.mailboxUid, type, name, folders, onFolderCreated, client);
119
+ }
120
+
121
+ /** The card's part of a message having left its folder for `updated`'s: the folder badges and the local search index. */
122
+ function relocated(before: Message, updated: Message): void {
123
+ remember(updated);
124
+ void moveLocalEntity(updated.mailboxUid, updated.uid, updated.folderUid);
125
+ trackMessageChange(before, updated).settle();
126
+ }
127
+
128
+ /** Moves the message into its mailbox's folder of `type`, and tells the folder badges and the local search index. */
129
+ async function moveToType(type: Folder["type"], name: string): Promise<Message> {
130
+ const before = newest();
131
+ const updated = await moveMessage(before, await folderOf(type, name), client);
132
+ relocated(before, updated);
133
+ return updated;
134
+ }
135
+
136
+ const subjectOf = () => displaySubject(message.subject) || "(no subject)";
137
+
138
+ /** What the server did with a report, as the card shows it: the message is out of its list (when it moved) and a pop-up says what happened. */
139
+ function reported(result: MessageReportResult, alwaysTrust: boolean): void {
140
+ const before = newest();
141
+ if (result.folderUid !== before.folderUid) {
142
+ // The answer names no new `version`; the message is out of the card's list now, so nothing builds on this copy.
143
+ const updated: Message = { ...before, folderUid: result.folderUid };
144
+ relocated(before, updated);
145
+ onMoved?.(updated);
146
+ }
147
+ const notice = reportNotice(result, subjectOf(), alwaysTrust);
148
+ const safeSender = result.safeSender;
149
+ notify({
150
+ kind: "success",
151
+ title: notice.title,
152
+ message: notice.message,
153
+ hint: notice.hint,
154
+ actions: safeSender
155
+ ? [
156
+ {
157
+ label: "Undo",
158
+ onClick: () => {
159
+ removeSafeSender(message.mailboxUid, safeSender, client).then(
160
+ () => notify({ kind: "info", title: `${safeSender} is no longer a safe sender`, message: "This message stays in the Inbox." }),
161
+ (err) => notifyApiError(err, "Couldn't undo trusting this sender"),
162
+ );
163
+ },
164
+ },
165
+ { label: "Manage safe senders", href: senderListsHref(message.mailboxUid) },
166
+ ]
167
+ : undefined,
168
+ });
169
+ }
170
+
171
+ /** What a server that has no report route leaves: the move alone, in the message's own mailbox, and nothing learned. */
172
+ async function reportByMoving(kind: MessageReportKind, alwaysTrust: boolean): Promise<void> {
173
+ const toInbox = kind === "not_junk";
174
+ let updated: Message;
175
+ try {
176
+ updated = await moveToType(toInbox ? "inbox" : "junk", toInbox ? "Inbox" : "Junk Email");
177
+ } catch (err) {
178
+ notifyApiError(err, `Couldn't report this message as ${reportNoun(kind)}`);
179
+ return;
180
+ }
181
+ onMoved?.(updated);
182
+ notify({
183
+ kind: "success",
184
+ title: reportTitle(kind),
185
+ message: `“${subjectOf()}” was moved to ${reportFolderName(kind)}.${alwaysTrust ? " This server cannot keep a list of safe senders, so its sender was not added to one." : ""}`,
186
+ });
187
+ }
188
+
189
+ async function report(kind: MessageReportKind, alwaysTrustSender = false): Promise<void> {
190
+ await exclusive(async () => {
191
+ let result: MessageReportResult;
192
+ try {
193
+ result = await reportMessage(message.uid, kind, { alwaysTrustSender }, client);
194
+ } catch (err) {
195
+ if (isNotFound(err)) {
196
+ await reportByMoving(kind, alwaysTrustSender);
197
+ } else {
198
+ notifyApiError(err, `Couldn't report this message as ${reportNoun(kind)}`);
199
+ }
200
+ return;
201
+ }
202
+ reported(result, alwaysTrustSender);
203
+ });
204
+ }
205
+
206
+ async function deleteMessage(): Promise<void> {
207
+ await exclusive(async () => {
208
+ if (inDeletedItems) {
209
+ // Nowhere further to move it: asks first, deletes for good and tells the badges, the search index and the reader itself.
210
+ const outcome = await permanent.requestPermanentDelete([message]);
211
+ if (outcome && outcome.deleted.length > 0) {
212
+ onMoved?.(message);
213
+ }
214
+ return;
215
+ }
216
+ try {
217
+ // Awaited on its own line: an optional call with no callee never evaluates its arguments, so with no `onMoved` nothing would be moved.
218
+ const updated = await moveToType("deleted_items", "Deleted Items");
219
+ onMoved?.(updated);
220
+ } catch (err) {
221
+ notifyApiError(err, "Couldn't delete this message");
222
+ }
223
+ });
224
+ }
225
+
226
+ async function toggleRead(): Promise<void> {
227
+ await exclusive(async () => {
228
+ const before = newest();
229
+ try {
230
+ await setReadStateMany(
231
+ [before],
232
+ before.flags.read !== true,
233
+ {
234
+ patch: (updated, previous) => {
235
+ remember(updated);
236
+ onChanged?.(updated, previous);
237
+ },
238
+ track: trackMessageChange,
239
+ },
240
+ client,
241
+ );
242
+ } catch (err) {
243
+ notifyApiError(err, "Couldn't update the message");
244
+ }
245
+ });
246
+ }
247
+
248
+ async function toggleFlag(): Promise<void> {
249
+ await exclusive(async () => {
250
+ const before = newest();
251
+ try {
252
+ const updated = await setMessageFlagged(before, before.flags.flagged !== true, client);
253
+ remember(updated);
254
+ onChanged?.(updated, before);
255
+ } catch (err) {
256
+ notifyApiError(err, "Couldn't update the message");
257
+ }
258
+ });
259
+ }
260
+
261
+ /** The sender of this message as a list entry needs it: the address in its From header - what the reader sees, and what the mail server matches a list
262
+ * against (with the envelope sender) - or, without one, the address the message is filed under. `all` is both, for the filter rules of a server without lists. */
263
+ async function senders(): Promise<{ listed: string | undefined; all: string[] }> {
264
+ const raw = await getMessageRawContent(message.uid).catch(() => undefined);
265
+ const header = raw === undefined ? undefined : headerFromAddress(raw);
266
+ return { listed: normalizeAddresses([header, message.from.address])[0], all: normalizeAddresses([message.from.address, header]) };
267
+ }
268
+
269
+ /** Whether `address` can go on a list (a plain address the mail server accepts); a pop-up says so when it cannot. */
270
+ function listable(address: string | undefined, title: string): address is string {
271
+ const checked = address === undefined ? undefined : checkSenderEntry(address);
272
+ if (address !== undefined && checked?.ok && checked.kind === "address") {
273
+ return true;
274
+ }
275
+ notify({ kind: "error", title, message: "This message has no sender address that can be put on a list." });
276
+ return false;
277
+ }
278
+
279
+ /** Files the message in its mailbox's Junk Email when it is not there yet, and says where it ended up. */
280
+ async function moveToJunkUnlessThere(): Promise<string> {
281
+ if (inJunk) {
282
+ return "This message is already in Junk Email.";
283
+ }
284
+ try {
285
+ const moved = await moveToType("junk", "Junk Email");
286
+ onMoved?.(moved);
287
+ return "This message was moved there.";
288
+ } catch (err) {
289
+ notifyApiError(err, "Couldn't move this message to Junk Email");
290
+ return "This message is still where it was.";
291
+ }
292
+ }
293
+
294
+ /** Block, on a server without sender lists: the mailbox's mail filter rules. */
295
+ async function blockWithRules(addresses: string[], address: string): Promise<void> {
296
+ let result: Awaited<ReturnType<typeof blockSender>>;
297
+ try {
298
+ const [junkUid, inboxUid] = await Promise.all([folderOf("junk", "Junk Email"), folderOf("inbox", "Inbox")]);
299
+ result = await blockSender(message.mailboxUid, addresses, junkUid, inboxUid, client);
300
+ } catch (err) {
301
+ notifyApiError(err, "Couldn't block this sender");
302
+ return;
303
+ }
304
+ const where = await moveToJunkUnlessThere();
305
+ notify({
306
+ kind: result.outcome === "existing" ? "info" : "success",
307
+ title: result.outcome === "existing" ? `${address} is already blocked` : `Blocked ${address}`,
308
+ message: `New mail from this address goes to Junk Email. ${where}`,
309
+ hint: "This server has no list of blocked senders, so the block is a filter rule that matches any sender address containing this one.",
310
+ actions: [
311
+ ...(result.outcome === "created"
312
+ ? [
313
+ {
314
+ label: "Undo",
315
+ onClick: () => {
316
+ removeSenderRule(result.rule, client).then(
317
+ () => notify({ kind: "info", title: `Unblocked ${address}`, message: "The block was removed. This message stays where it is." }),
318
+ (err) => notifyApiError(err, "Couldn't undo the block"),
319
+ );
320
+ },
321
+ },
322
+ ]
323
+ : []),
324
+ { label: "View rules", href: rulesHref(message.mailboxUid) },
325
+ ],
326
+ });
327
+ }
328
+
329
+ async function block(): Promise<void> {
330
+ await exclusive(async () => {
331
+ const { listed, all } = await senders();
332
+ if (!listable(listed, "Couldn't block this sender")) {
333
+ return;
334
+ }
335
+ if (ownAddresses.includes(listed)) {
336
+ notify({ kind: "info", title: "That is your own address", message: `${listed} is one of your addresses, so it is not blocked.` });
337
+ return;
338
+ }
339
+ let added: SenderListsChange;
340
+ try {
341
+ added = await addBlockedSender(message.mailboxUid, listed, client);
342
+ } catch (err) {
343
+ if (isNotFound(err)) {
344
+ await blockWithRules(all, message.from.address);
345
+ } else {
346
+ notifyApiError(err, "Couldn't block this sender");
347
+ }
348
+ return;
349
+ }
350
+ const where = await moveToJunkUnlessThere();
351
+ notify({
352
+ kind: added.changed ? "success" : "info",
353
+ title: added.changed ? `Blocked ${listed}` : `${listed} is already blocked`,
354
+ message: `New mail from this address goes to Junk Email. ${where}`,
355
+ actions: [
356
+ ...(added.changed
357
+ ? [
358
+ {
359
+ label: "Undo",
360
+ onClick: () => {
361
+ removeBlockedSender(message.mailboxUid, listed, client).then(
362
+ () => notify({ kind: "info", title: `Unblocked ${listed}`, message: "The block was removed. This message stays where it is." }),
363
+ (err) => notifyApiError(err, "Couldn't undo the block"),
364
+ );
365
+ },
366
+ },
367
+ ]
368
+ : []),
369
+ { label: "Manage blocked senders", href: senderListsHref(message.mailboxUid) },
370
+ ],
371
+ });
372
+ });
373
+ }
374
+
375
+ /** Never block, on a server without sender lists: the rule that keeps the sender's mail in the Inbox. */
376
+ async function neverBlockWithRules(addresses: string[], address: string): Promise<void> {
377
+ let result: Awaited<ReturnType<typeof neverBlockSender>>;
378
+ try {
379
+ const [junkUid, inboxUid] = await Promise.all([folderOf("junk", "Junk Email"), folderOf("inbox", "Inbox")]);
380
+ result = await neverBlockSender(message.mailboxUid, addresses, junkUid, inboxUid, client);
381
+ } catch (err) {
382
+ notifyApiError(err, "Couldn't stop blocking this sender");
383
+ return;
384
+ }
385
+ const unblocked = result.removed.length > 0 ? "The block on this sender was removed. " : "";
386
+ notify({
387
+ kind: result.outcome === "existing" && !unblocked ? "info" : "success",
388
+ title: result.outcome === "existing" && !unblocked ? `${address} is already never blocked` : `Never blocking ${address}`,
389
+ message: `${unblocked}New mail from this address stays in your Inbox, ahead of your other filters. Mail the spam filter judges to be junk still goes to Junk Email.`,
390
+ actions: [{ label: "View rules", href: rulesHref(message.mailboxUid) }],
391
+ });
392
+ }
393
+
394
+ async function neverBlock(): Promise<void> {
395
+ await exclusive(async () => {
396
+ const { listed, all } = await senders();
397
+ if (!listable(listed, "Couldn't stop blocking this sender")) {
398
+ return;
399
+ }
400
+ let added: SenderListsChange;
401
+ try {
402
+ added = await addSafeSender(message.mailboxUid, listed, client);
403
+ } catch (err) {
404
+ if (isNotFound(err)) {
405
+ await neverBlockWithRules(all, message.from.address);
406
+ } else {
407
+ notifyApiError(err, "Couldn't stop blocking this sender");
408
+ }
409
+ return;
410
+ }
411
+ notify({
412
+ kind: added.changed ? "success" : "info",
413
+ title: added.changed ? `Never blocking ${listed}` : `${listed} is already a safe sender`,
414
+ message:
415
+ "Any block on this address is removed. Mail from it that passes authentication is delivered to your Inbox instead of Junk Email; " +
416
+ "mail that fails authentication, carries a virus or is quarantined by policy is still kept out.",
417
+ actions: [
418
+ ...(added.changed
419
+ ? [
420
+ {
421
+ label: "Undo",
422
+ onClick: () => {
423
+ removeSafeSender(message.mailboxUid, listed, client).then(
424
+ () => notify({ kind: "info", title: `${listed} is no longer a safe sender`, message: "Its mail is filtered as usual again." }),
425
+ (err) => notifyApiError(err, "Couldn't undo the change"),
426
+ );
427
+ },
428
+ },
429
+ ]
430
+ : []),
431
+ { label: "Manage safe senders", href: senderListsHref(message.mailboxUid) },
432
+ ],
433
+ });
434
+ });
435
+ }
436
+
437
+ return {
438
+ busy: busy || permanent.busy,
439
+ dialog: permanent.dialog,
440
+ reportJunk: () => report("junk"),
441
+ reportPhishing: () => report("phishing"),
442
+ notJunk: () => report("not_junk"),
443
+ notJunkAndTrust: () => report("not_junk", true),
444
+ deleteMessage,
445
+ toggleRead,
446
+ toggleFlag,
447
+ blockSender: block,
448
+ neverBlockSender: neverBlock,
449
+ };
450
+ }