@rapidmx/web-client 0.21.0 → 0.23.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 (897) hide show
  1. package/README.md +48 -14
  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 +3 -3
  5. package/apps/admin/data-requests/index.tsx +8 -8
  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 +6 -6
  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 +7 -7
  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 +6 -6
  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 +5 -5
  20. package/apps/admin/quarantine/index.tsx +5 -5
  21. package/apps/admin/retention-policy/index.tsx +3 -3
  22. package/apps/admin/signing-certificates/index.tsx +5 -5
  23. package/apps/admin/transport-rules/[uid].tsx +5 -5
  24. package/apps/admin/transport-rules/_transportRuleConfig.tsx +3 -3
  25. package/apps/admin/transport-rules/index.tsx +4 -4
  26. package/apps/admin/transport-rules/new/index.tsx +5 -5
  27. package/apps/escrow/_layout.tsx +1 -1
  28. package/apps/escrow/audit-log/index.tsx +4 -4
  29. package/apps/escrow/index.tsx +4 -4
  30. package/apps/escrow/matters/[uid].tsx +10 -10
  31. package/apps/escrow/matters/new/index.tsx +6 -6
  32. package/apps/shared/appearance/AppearanceForm.tsx +3 -3
  33. package/apps/shared/appearance/AppearanceHead.tsx +1 -1
  34. package/apps/shared/appearance/AppearanceProvider.tsx +3 -3
  35. package/apps/shared/appearance/appearanceCache.ts +1 -1
  36. package/apps/shared/appearance/appearanceContext.ts +1 -1
  37. package/apps/shared/appearance/theme.ts +1 -1
  38. package/apps/shared/auth/adminAccess.ts +1 -1
  39. package/apps/shared/calendar/bookingPlugin.ts +1 -1
  40. package/apps/shared/calendar/calendarLiveUpdates.ts +1 -1
  41. package/apps/shared/calendar/calendarReminders.ts +1 -1
  42. package/apps/shared/calendar/useCalendarReminders.ts +1 -1
  43. package/apps/shared/components/admin/diagnostics/DiagnosticsManager.tsx +1 -1
  44. package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +2 -2
  45. package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +2 -2
  46. package/apps/shared/components/admin/diagnostics/PackagesTable.tsx +1 -1
  47. package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
  48. package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +2 -2
  49. package/apps/shared/components/admin/diagnostics/VersionsPanel.tsx +1 -1
  50. package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +1 -1
  51. package/apps/shared/components/admin/diagnostics/format.ts +1 -1
  52. package/apps/shared/components/admin/diagnostics/logClient.ts +1 -1
  53. package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
  54. package/apps/shared/components/admin/elevation.ts +1 -1
  55. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +3 -3
  56. package/apps/shared/components/admin/layout/AdminShell.tsx +8 -8
  57. package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +6 -6
  58. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +10 -8
  59. package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +4 -4
  60. package/apps/shared/components/admin/mailboxes/MailboxTable.tsx +1 -1
  61. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +19 -14
  62. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +5 -5
  63. package/apps/shared/components/admin/settings/BrandingForm.tsx +5 -5
  64. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +5 -5
  65. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +4 -4
  66. package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +2 -2
  67. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +32 -27
  68. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +4 -4
  69. package/apps/shared/components/admin/settings/PluginsManager.tsx +5 -5
  70. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +5 -5
  71. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +7 -7
  72. package/apps/shared/components/admin/setup/SetupWizard.tsx +28 -24
  73. package/apps/shared/components/admin/signOut.ts +1 -1
  74. package/apps/shared/components/admin/usePagedList.tsx +2 -2
  75. package/apps/shared/components/calendar/AppointmentQuickForm.tsx +3 -3
  76. package/apps/shared/components/calendar/CalendarListSidebar.tsx +3 -3
  77. package/apps/shared/components/calendar/DescriptionEditor.tsx +1 -1
  78. package/apps/shared/components/calendar/EventDescriptionView.tsx +1 -1
  79. package/apps/shared/components/calendar/EventDetails.tsx +16 -14
  80. package/apps/shared/components/calendar/EventEditor.tsx +54 -39
  81. package/apps/shared/components/calendar/EventExpandedForm.tsx +3 -3
  82. package/apps/shared/components/calendar/EventFormParts.tsx +2 -2
  83. package/apps/shared/components/calendar/EventModal.tsx +5 -5
  84. package/apps/shared/components/calendar/EventQuickForm.tsx +3 -3
  85. package/apps/shared/components/calendar/EventShell.tsx +1 -1
  86. package/apps/shared/components/calendar/FindATime.tsx +6 -4
  87. package/apps/shared/components/calendar/GuestInput.tsx +2 -2
  88. package/apps/shared/components/calendar/MonthView.tsx +2 -2
  89. package/apps/shared/components/calendar/QuickCreateFaces.tsx +1 -1
  90. package/apps/shared/components/calendar/QuickFaceFrame.tsx +1 -1
  91. package/apps/shared/components/calendar/RecurrenceEditor.tsx +2 -2
  92. package/apps/shared/components/calendar/RequestChangeForm.tsx +8 -6
  93. package/apps/shared/components/calendar/ResourcePicker.tsx +7 -5
  94. package/apps/shared/components/calendar/SplitDayView.tsx +1 -1
  95. package/apps/shared/components/calendar/TaskQuickForm.tsx +23 -18
  96. package/apps/shared/components/calendar/TimeGridView.tsx +5 -3
  97. package/apps/shared/components/calendar/allDay.ts +2 -2
  98. package/apps/shared/components/calendar/eventDialogFields.ts +3 -3
  99. package/apps/shared/components/calendar/eventForm.ts +3 -3
  100. package/apps/shared/components/calendar/eventFormat.ts +3 -3
  101. package/apps/shared/components/calendar/findTimeGrid.ts +2 -2
  102. package/apps/shared/components/calendar/layout/CalendarShell.tsx +11 -9
  103. package/apps/shared/components/contacts/ContactDetailPane.tsx +4 -4
  104. package/apps/shared/components/contacts/ContactForm.tsx +27 -17
  105. package/apps/shared/components/contacts/ContactsSidebar.tsx +7 -5
  106. package/apps/shared/components/contacts/KeyChangeReview.tsx +5 -5
  107. package/apps/shared/components/contacts/contactKeys.ts +3 -3
  108. package/apps/shared/components/contacts/layout/ContactsShell.tsx +9 -7
  109. package/apps/shared/components/escrow/layout/EscrowShell.tsx +6 -6
  110. package/apps/shared/components/forms/StringListField.tsx +1 -1
  111. package/apps/shared/components/layout/AppShell.tsx +12 -10
  112. package/apps/shared/components/layout/BrandingChrome.tsx +1 -1
  113. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +9 -9
  114. package/apps/shared/components/layout/MailboxProvisioning.tsx +8 -6
  115. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +9 -9
  116. package/apps/shared/components/layout/ThemeSwitch.tsx +1 -1
  117. package/apps/shared/components/layout/UnlockPromptProvider.tsx +6 -6
  118. package/apps/shared/components/layout/UserMenu.tsx +6 -4
  119. package/apps/shared/components/mail/ConversationList.tsx +25 -10
  120. package/apps/shared/components/mail/ConversationThreadPane.tsx +33 -17
  121. package/apps/shared/components/mail/InviteCard.tsx +11 -9
  122. package/apps/shared/components/mail/LazyReadingPane.tsx +2 -2
  123. package/apps/shared/components/mail/MailAddress.tsx +1 -1
  124. package/apps/shared/components/mail/MailListToolbar.tsx +2 -2
  125. package/apps/shared/components/mail/MailSelectionBar.tsx +2 -2
  126. package/apps/shared/components/mail/MenuButton.tsx +1 -1
  127. package/apps/shared/components/mail/MessageDetailPane.tsx +69 -48
  128. package/apps/shared/components/mail/MoveToFolderDialog.tsx +8 -6
  129. package/apps/shared/components/mail/OutboxRowStatus.tsx +1 -1
  130. package/apps/shared/components/mail/PermanentDeleteDialog.tsx +2 -2
  131. package/apps/shared/components/mail/compose/ComposeContext.tsx +14 -3
  132. package/apps/shared/components/mail/compose/ComposeWindow.tsx +34 -30
  133. package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +4 -4
  134. package/apps/shared/components/mail/compose/EmojiPicker.tsx +2 -2
  135. package/apps/shared/components/mail/compose/GifPicker.tsx +3 -3
  136. package/apps/shared/components/mail/compose/RecipientInput.tsx +1 -1
  137. package/apps/shared/components/mail/compose/ScheduleSendPicker.tsx +1 -1
  138. package/apps/shared/components/mail/compose/encryptionRequirement.ts +2 -2
  139. package/apps/shared/components/mail/compose/quotedBody.ts +5 -5
  140. package/apps/shared/components/mail/compose/recipients.ts +1 -1
  141. package/apps/shared/components/mail/invite/InviteRowChip.tsx +10 -14
  142. package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +11 -9
  143. package/apps/shared/components/mail/invite/InviteTimeline.tsx +1 -1
  144. package/apps/shared/components/mail/invite/ProposeTimeForm.tsx +2 -2
  145. package/apps/shared/components/mail/invite/inviteFormat.ts +2 -2
  146. package/apps/shared/components/mail/invite/inviteStore.ts +14 -6
  147. package/apps/shared/components/mail/labelMenu.tsx +9 -7
  148. package/apps/shared/components/mail/layout/MailShell.tsx +4 -4
  149. package/apps/shared/components/mail/listPreferences.ts +2 -2
  150. package/apps/shared/components/mail/pinnedSigners.ts +45 -19
  151. package/apps/shared/components/mail/reading/EncryptedBody.tsx +2 -2
  152. package/apps/shared/components/mail/reading/MessageBody.tsx +6 -6
  153. package/apps/shared/components/mail/reading/MessageCard.tsx +3 -3
  154. package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +3 -3
  155. package/apps/shared/components/mail/reading/PendingMessageCard.tsx +1 -1
  156. package/apps/shared/components/mail/reading/bodyContent.ts +3 -3
  157. package/apps/shared/components/mail/reading/bodyHtml.ts +1 -1
  158. package/apps/shared/components/mail/reading/conversationPrint.ts +76 -0
  159. package/apps/shared/components/mail/reading/messageExport.ts +1 -1
  160. package/apps/shared/components/mail/reading/printMessage.ts +46 -9
  161. package/apps/shared/components/mail/reading/useMessageActions.ts +28 -21
  162. package/apps/shared/components/mail/unreadStyle.tsx +1 -1
  163. package/apps/shared/components/mail/verificationSeals.ts +16 -12
  164. package/apps/shared/components/mail/writableMailboxes.ts +14 -7
  165. package/apps/shared/components/rules/RuleBuilder.tsx +1 -1
  166. package/apps/shared/components/settings/SigningCertificateCard.tsx +4 -4
  167. package/apps/shared/components/settings/layout/SettingsShell.tsx +8 -6
  168. package/apps/shared/components/sharing/PrincipalListField.tsx +1 -1
  169. package/apps/shared/components/sharing/PrincipalPicker.tsx +1 -1
  170. package/apps/shared/components/sharing/PrincipalResolver.tsx +4 -4
  171. package/apps/shared/components/tasks/TasksSidebar.tsx +7 -5
  172. package/apps/shared/components/tasks/layout/TasksShell.tsx +9 -7
  173. package/apps/shared/keyboard/ShortcutsDialog.tsx +1 -1
  174. package/apps/shared/keyboard/keymap.ts +1 -0
  175. package/apps/shared/mail/decryptedMessages.ts +116 -0
  176. package/apps/shared/mail/findWellKnownFolderUid.ts +6 -4
  177. package/apps/shared/mail/folderCounts.ts +8 -4
  178. package/apps/shared/mail/folderOfType.ts +5 -3
  179. package/apps/shared/mail/folderTree.ts +1 -1
  180. package/apps/shared/mail/listSnapshots.ts +2 -2
  181. package/apps/shared/mail/messageReadState.ts +6 -5
  182. package/apps/shared/mail/newMailNotifications.ts +2 -2
  183. package/apps/shared/mail/outbox/composeBridge.ts +2 -2
  184. package/apps/shared/mail/outbox/outboxState.ts +1 -1
  185. package/apps/shared/mail/outbox/outgoingReplies.ts +2 -2
  186. package/apps/shared/mail/outbox/sendDecision.ts +2 -2
  187. package/apps/shared/mail/outbox/sendJob.ts +40 -35
  188. package/apps/shared/mail/outbox/sendOutcomes.ts +20 -15
  189. package/apps/shared/mail/outbox/useOutboxStatus.ts +5 -3
  190. package/apps/shared/mail/permanentDelete.ts +8 -7
  191. package/apps/shared/mail/primaryMailbox.ts +1 -1
  192. package/apps/shared/mail/reportNotices.ts +1 -1
  193. package/apps/shared/mail/senderBlocking.ts +36 -20
  194. package/apps/shared/mail/useMailConnection.ts +12 -10
  195. package/apps/shared/mail/useMailLiveUpdates.ts +3 -3
  196. package/apps/shared/mail/useMailboxUpdateAccess.ts +35 -11
  197. package/apps/shared/mail/useMarkMessageRead.ts +14 -7
  198. package/apps/shared/mail/useNewMailNotifications.ts +1 -1
  199. package/apps/shared/mail/usePermanentDelete.tsx +5 -3
  200. package/apps/shared/navigation/pageTitle.ts +1 -1
  201. package/apps/shared/notifications/NotificationCenter.tsx +1 -1
  202. package/apps/shared/notifications/NotificationHistoryDialog.tsx +2 -2
  203. package/apps/shared/notifications/apiErrors.ts +2 -2
  204. package/apps/shared/notifications/pushStatus.ts +1 -1
  205. package/apps/shared/notifications/systemErrors.ts +1 -1
  206. package/apps/shared/search/LocalIndexLifecycle.tsx +18 -12
  207. package/apps/shared/search/crossMailboxSearch.ts +3 -3
  208. package/apps/shared/search/localIndexBuilder.ts +24 -12
  209. package/apps/shared/search/localIndexKey.ts +1 -1
  210. package/apps/shared/search/localIndexRpcClient.ts +150 -30
  211. package/apps/shared/search/localIndexTransport.ts +84 -0
  212. package/apps/shared/search/localIndexWorker.ts +1 -1
  213. package/apps/shared/search/searchTier2.ts +3 -3
  214. package/apps/shared/signing/enrollmentTracker.ts +3 -3
  215. package/apps/shared/signing/enrollmentView.ts +1 -1
  216. package/apps/shared/signing/signingInfo.ts +1 -1
  217. package/apps/shared/signing/useSigningEnrollmentWatcher.ts +6 -4
  218. package/apps/shared/styles/app.css +14 -23
  219. package/apps/www/_layout.tsx +2 -2
  220. package/apps/www/calendar/index.tsx +20 -18
  221. package/apps/www/contacts/[uid].tsx +8 -6
  222. package/apps/www/contacts/index.tsx +19 -17
  223. package/apps/www/index.tsx +68 -48
  224. package/apps/www/messages/[uid].tsx +11 -9
  225. package/apps/www/settings/auto-reply/index.tsx +6 -4
  226. package/apps/www/settings/blocked-senders/index.tsx +9 -7
  227. package/apps/www/settings/encryption/index.tsx +38 -32
  228. package/apps/www/settings/filters/[uid].tsx +19 -14
  229. package/apps/www/settings/filters/_mailFilterRuleConfig.tsx +2 -2
  230. package/apps/www/settings/filters/index.tsx +4 -4
  231. package/apps/www/settings/filters/new/index.tsx +10 -8
  232. package/apps/www/settings/labels/index.tsx +12 -10
  233. package/apps/www/settings/privacy/index.tsx +18 -14
  234. package/apps/www/settings/profile/index.tsx +16 -11
  235. package/apps/www/settings/read-receipts/index.tsx +17 -12
  236. package/apps/www/settings/sharing/index.tsx +6 -6
  237. package/apps/www/settings/signatures/[uid].tsx +5 -5
  238. package/apps/www/settings/signatures/index.tsx +4 -4
  239. package/apps/www/settings/signatures/new/index.tsx +4 -4
  240. package/apps/www/settings/signatures/signatureDefaults.ts +1 -1
  241. package/apps/www/tasks/index.tsx +28 -23
  242. package/dist/apps/admin/_layout.d.ts +1 -1
  243. package/dist/apps/admin/_layout.js +1 -1
  244. package/dist/apps/admin/audit-log/index.d.ts +1 -1
  245. package/dist/apps/admin/audit-log/index.js +4 -4
  246. package/dist/apps/admin/branding/index.js +3 -3
  247. package/dist/apps/admin/data-requests/index.js +8 -8
  248. package/dist/apps/admin/distribution-lists/[uid].js +3 -3
  249. package/dist/apps/admin/distribution-lists/index.js +4 -4
  250. package/dist/apps/admin/distribution-lists/new/index.js +5 -5
  251. package/dist/apps/admin/domains/[uid].js +6 -6
  252. package/dist/apps/admin/domains/index.js +4 -4
  253. package/dist/apps/admin/domains/new/index.js +5 -5
  254. package/dist/apps/admin/encryption-policy/index.js +1 -1
  255. package/dist/apps/admin/escrow-scopes/[uid].d.ts +1 -1
  256. package/dist/apps/admin/escrow-scopes/[uid].js +7 -7
  257. package/dist/apps/admin/escrow-scopes/index.js +4 -4
  258. package/dist/apps/admin/escrow-scopes/new/index.js +5 -5
  259. package/dist/apps/admin/index.js +6 -6
  260. package/dist/apps/admin/ingest-queue/index.js +4 -4
  261. package/dist/apps/admin/mailbox-policy/index.js +1 -1
  262. package/dist/apps/admin/mailboxes/[uid].js +5 -5
  263. package/dist/apps/admin/quarantine/index.js +5 -5
  264. package/dist/apps/admin/retention-policy/index.js +3 -3
  265. package/dist/apps/admin/signing-certificates/index.js +5 -5
  266. package/dist/apps/admin/transport-rules/[uid].js +5 -5
  267. package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +1 -1
  268. package/dist/apps/admin/transport-rules/_transportRuleConfig.js +2 -2
  269. package/dist/apps/admin/transport-rules/index.js +4 -4
  270. package/dist/apps/admin/transport-rules/new/index.js +5 -5
  271. package/dist/apps/escrow/_layout.d.ts +1 -1
  272. package/dist/apps/escrow/audit-log/index.d.ts +1 -1
  273. package/dist/apps/escrow/audit-log/index.js +4 -4
  274. package/dist/apps/escrow/index.js +4 -4
  275. package/dist/apps/escrow/matters/[uid].js +10 -10
  276. package/dist/apps/escrow/matters/new/index.js +6 -6
  277. package/dist/apps/shared/appearance/AppearanceForm.js +3 -3
  278. package/dist/apps/shared/appearance/AppearanceHead.js +1 -1
  279. package/dist/apps/shared/appearance/AppearanceProvider.d.ts +1 -1
  280. package/dist/apps/shared/appearance/AppearanceProvider.js +3 -3
  281. package/dist/apps/shared/appearance/appearanceCache.d.ts +1 -1
  282. package/dist/apps/shared/appearance/appearanceCache.js +1 -1
  283. package/dist/apps/shared/appearance/appearanceContext.d.ts +1 -1
  284. package/dist/apps/shared/appearance/theme.d.ts +1 -1
  285. package/dist/apps/shared/auth/adminAccess.js +1 -1
  286. package/dist/apps/shared/calendar/bookingPlugin.js +1 -1
  287. package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +1 -1
  288. package/dist/apps/shared/calendar/calendarReminders.d.ts +1 -1
  289. package/dist/apps/shared/calendar/useCalendarReminders.js +1 -1
  290. package/dist/apps/shared/components/admin/diagnostics/DiagnosticsManager.js +1 -1
  291. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.d.ts +1 -1
  292. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +2 -2
  293. package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +2 -2
  294. package/dist/apps/shared/components/admin/diagnostics/PackagesTable.js +1 -1
  295. package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
  296. package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +2 -2
  297. package/dist/apps/shared/components/admin/diagnostics/VersionsPanel.js +1 -1
  298. package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.js +1 -1
  299. package/dist/apps/shared/components/admin/diagnostics/format.js +1 -1
  300. package/dist/apps/shared/components/admin/diagnostics/logClient.js +1 -1
  301. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +1 -1
  302. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
  303. package/dist/apps/shared/components/admin/elevation.js +1 -1
  304. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +3 -3
  305. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
  306. package/dist/apps/shared/components/admin/layout/AdminShell.js +7 -7
  307. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.d.ts +1 -1
  308. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +6 -6
  309. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +1 -1
  310. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +10 -8
  311. package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
  312. package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +1 -1
  313. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +1 -1
  314. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +7 -5
  315. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +5 -5
  316. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +1 -1
  317. package/dist/apps/shared/components/admin/settings/BrandingForm.js +5 -5
  318. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +1 -1
  319. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +5 -5
  320. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +1 -1
  321. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +4 -4
  322. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +2 -2
  323. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +1 -1
  324. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +14 -12
  325. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +1 -1
  326. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +4 -4
  327. package/dist/apps/shared/components/admin/settings/PluginsManager.js +5 -5
  328. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +1 -1
  329. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +5 -5
  330. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +7 -7
  331. package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +4 -4
  332. package/dist/apps/shared/components/admin/setup/SetupWizard.js +27 -23
  333. package/dist/apps/shared/components/admin/signOut.js +1 -1
  334. package/dist/apps/shared/components/admin/usePagedList.js +2 -2
  335. package/dist/apps/shared/components/calendar/AppointmentQuickForm.js +3 -3
  336. package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +1 -1
  337. package/dist/apps/shared/components/calendar/CalendarListSidebar.js +2 -2
  338. package/dist/apps/shared/components/calendar/DescriptionEditor.js +1 -1
  339. package/dist/apps/shared/components/calendar/EventDescriptionView.js +1 -1
  340. package/dist/apps/shared/components/calendar/EventDetails.d.ts +2 -2
  341. package/dist/apps/shared/components/calendar/EventDetails.js +16 -14
  342. package/dist/apps/shared/components/calendar/EventEditor.d.ts +2 -2
  343. package/dist/apps/shared/components/calendar/EventEditor.js +22 -20
  344. package/dist/apps/shared/components/calendar/EventExpandedForm.js +2 -2
  345. package/dist/apps/shared/components/calendar/EventFormParts.d.ts +1 -1
  346. package/dist/apps/shared/components/calendar/EventFormParts.js +1 -1
  347. package/dist/apps/shared/components/calendar/EventModal.d.ts +2 -2
  348. package/dist/apps/shared/components/calendar/EventModal.js +3 -3
  349. package/dist/apps/shared/components/calendar/EventQuickForm.js +3 -3
  350. package/dist/apps/shared/components/calendar/EventShell.js +1 -1
  351. package/dist/apps/shared/components/calendar/FindATime.js +6 -4
  352. package/dist/apps/shared/components/calendar/GuestInput.d.ts +2 -2
  353. package/dist/apps/shared/components/calendar/MonthView.d.ts +1 -1
  354. package/dist/apps/shared/components/calendar/MonthView.js +1 -1
  355. package/dist/apps/shared/components/calendar/QuickCreateFaces.js +1 -1
  356. package/dist/apps/shared/components/calendar/QuickFaceFrame.js +1 -1
  357. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +1 -1
  358. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +1 -1
  359. package/dist/apps/shared/components/calendar/RequestChangeForm.js +8 -6
  360. package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +1 -1
  361. package/dist/apps/shared/components/calendar/ResourcePicker.js +7 -5
  362. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +1 -1
  363. package/dist/apps/shared/components/calendar/TaskQuickForm.d.ts +1 -1
  364. package/dist/apps/shared/components/calendar/TaskQuickForm.js +9 -7
  365. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +1 -1
  366. package/dist/apps/shared/components/calendar/TimeGridView.js +2 -2
  367. package/dist/apps/shared/components/calendar/allDay.d.ts +2 -2
  368. package/dist/apps/shared/components/calendar/allDay.js +1 -1
  369. package/dist/apps/shared/components/calendar/eventDialogFields.d.ts +2 -2
  370. package/dist/apps/shared/components/calendar/eventDialogFields.js +2 -2
  371. package/dist/apps/shared/components/calendar/eventForm.d.ts +3 -3
  372. package/dist/apps/shared/components/calendar/eventFormat.d.ts +1 -1
  373. package/dist/apps/shared/components/calendar/eventFormat.js +2 -2
  374. package/dist/apps/shared/components/calendar/findTimeGrid.d.ts +1 -1
  375. package/dist/apps/shared/components/calendar/findTimeGrid.js +1 -1
  376. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
  377. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +11 -9
  378. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +1 -1
  379. package/dist/apps/shared/components/contacts/ContactDetailPane.js +2 -2
  380. package/dist/apps/shared/components/contacts/ContactForm.d.ts +2 -2
  381. package/dist/apps/shared/components/contacts/ContactForm.js +12 -8
  382. package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +1 -1
  383. package/dist/apps/shared/components/contacts/ContactsSidebar.js +7 -5
  384. package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +1 -1
  385. package/dist/apps/shared/components/contacts/KeyChangeReview.js +5 -5
  386. package/dist/apps/shared/components/contacts/contactKeys.d.ts +2 -2
  387. package/dist/apps/shared/components/contacts/contactKeys.js +2 -2
  388. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
  389. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +9 -7
  390. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +6 -6
  391. package/dist/apps/shared/components/forms/StringListField.js +1 -1
  392. package/dist/apps/shared/components/layout/AppShell.d.ts +2 -2
  393. package/dist/apps/shared/components/layout/AppShell.js +11 -9
  394. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +1 -1
  395. package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +1 -1
  396. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +9 -9
  397. package/dist/apps/shared/components/layout/MailboxProvisioning.js +8 -6
  398. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +1 -1
  399. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +9 -9
  400. package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +2 -2
  401. package/dist/apps/shared/components/layout/UnlockPromptProvider.js +5 -5
  402. package/dist/apps/shared/components/layout/UserMenu.js +6 -4
  403. package/dist/apps/shared/components/mail/ConversationList.d.ts +2 -2
  404. package/dist/apps/shared/components/mail/ConversationList.js +23 -8
  405. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +3 -3
  406. package/dist/apps/shared/components/mail/ConversationThreadPane.js +19 -13
  407. package/dist/apps/shared/components/mail/InviteCard.js +10 -8
  408. package/dist/apps/shared/components/mail/LazyReadingPane.js +2 -2
  409. package/dist/apps/shared/components/mail/MailAddress.d.ts +1 -1
  410. package/dist/apps/shared/components/mail/MailAddress.js +1 -1
  411. package/dist/apps/shared/components/mail/MailListToolbar.d.ts +2 -2
  412. package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +2 -2
  413. package/dist/apps/shared/components/mail/MenuButton.js +1 -1
  414. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +3 -3
  415. package/dist/apps/shared/components/mail/MessageDetailPane.js +61 -46
  416. package/dist/apps/shared/components/mail/MoveToFolderDialog.d.ts +1 -1
  417. package/dist/apps/shared/components/mail/MoveToFolderDialog.js +8 -6
  418. package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +1 -1
  419. package/dist/apps/shared/components/mail/PermanentDeleteDialog.js +2 -2
  420. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +10 -1
  421. package/dist/apps/shared/components/mail/compose/ComposeContext.js +4 -2
  422. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +34 -30
  423. package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +4 -4
  424. package/dist/apps/shared/components/mail/compose/EmojiPicker.js +2 -2
  425. package/dist/apps/shared/components/mail/compose/GifPicker.js +3 -3
  426. package/dist/apps/shared/components/mail/compose/RecipientInput.d.ts +1 -1
  427. package/dist/apps/shared/components/mail/compose/RecipientInput.js +1 -1
  428. package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.js +1 -1
  429. package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +2 -2
  430. package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +1 -1
  431. package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +3 -3
  432. package/dist/apps/shared/components/mail/compose/quotedBody.js +3 -3
  433. package/dist/apps/shared/components/mail/compose/recipients.d.ts +1 -1
  434. package/dist/apps/shared/components/mail/invite/InviteRowChip.d.ts +3 -3
  435. package/dist/apps/shared/components/mail/invite/InviteRowChip.js +7 -9
  436. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +2 -2
  437. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +11 -9
  438. package/dist/apps/shared/components/mail/invite/InviteTimeline.d.ts +1 -1
  439. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.d.ts +1 -1
  440. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.js +1 -1
  441. package/dist/apps/shared/components/mail/invite/inviteFormat.d.ts +2 -2
  442. package/dist/apps/shared/components/mail/invite/inviteStore.d.ts +9 -3
  443. package/dist/apps/shared/components/mail/invite/inviteStore.js +13 -6
  444. package/dist/apps/shared/components/mail/labelMenu.d.ts +1 -1
  445. package/dist/apps/shared/components/mail/labelMenu.js +9 -7
  446. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +1 -1
  447. package/dist/apps/shared/components/mail/layout/MailShell.js +3 -3
  448. package/dist/apps/shared/components/mail/listPreferences.d.ts +2 -2
  449. package/dist/apps/shared/components/mail/listPreferences.js +1 -1
  450. package/dist/apps/shared/components/mail/pinnedSigners.d.ts +12 -5
  451. package/dist/apps/shared/components/mail/pinnedSigners.js +37 -18
  452. package/dist/apps/shared/components/mail/reading/EncryptedBody.js +2 -2
  453. package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +2 -2
  454. package/dist/apps/shared/components/mail/reading/MessageBody.js +4 -4
  455. package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +1 -1
  456. package/dist/apps/shared/components/mail/reading/MessageCard.js +2 -2
  457. package/dist/apps/shared/components/mail/reading/MessageSourceDialog.js +3 -3
  458. package/dist/apps/shared/components/mail/reading/PendingMessageCard.js +1 -1
  459. package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +2 -2
  460. package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -2
  461. package/dist/apps/shared/components/mail/reading/bodyHtml.js +1 -1
  462. package/dist/apps/shared/components/mail/reading/conversationPrint.d.ts +15 -0
  463. package/dist/apps/shared/components/mail/reading/conversationPrint.js +69 -0
  464. package/dist/apps/shared/components/mail/reading/messageExport.js +1 -1
  465. package/dist/apps/shared/components/mail/reading/printMessage.d.ts +9 -3
  466. package/dist/apps/shared/components/mail/reading/printMessage.js +33 -6
  467. package/dist/apps/shared/components/mail/reading/useMessageActions.d.ts +1 -1
  468. package/dist/apps/shared/components/mail/reading/useMessageActions.js +18 -16
  469. package/dist/apps/shared/components/mail/unreadStyle.d.ts +1 -1
  470. package/dist/apps/shared/components/mail/verificationSeals.d.ts +27 -6
  471. package/dist/apps/shared/components/mail/verificationSeals.js +15 -11
  472. package/dist/apps/shared/components/mail/writableMailboxes.d.ts +8 -3
  473. package/dist/apps/shared/components/mail/writableMailboxes.js +12 -6
  474. package/dist/apps/shared/components/rules/RuleBuilder.js +1 -1
  475. package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +1 -1
  476. package/dist/apps/shared/components/settings/SigningCertificateCard.js +3 -3
  477. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
  478. package/dist/apps/shared/components/settings/layout/SettingsShell.js +8 -6
  479. package/dist/apps/shared/components/sharing/PrincipalListField.d.ts +1 -1
  480. package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +1 -1
  481. package/dist/apps/shared/components/sharing/PrincipalPicker.js +1 -1
  482. package/dist/apps/shared/components/sharing/PrincipalResolver.d.ts +1 -1
  483. package/dist/apps/shared/components/sharing/PrincipalResolver.js +3 -3
  484. package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +1 -1
  485. package/dist/apps/shared/components/tasks/TasksSidebar.js +7 -5
  486. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
  487. package/dist/apps/shared/components/tasks/layout/TasksShell.js +9 -7
  488. package/dist/apps/shared/keyboard/ShortcutsDialog.js +1 -1
  489. package/dist/apps/shared/keyboard/keymap.d.ts +6 -0
  490. package/dist/apps/shared/keyboard/keymap.js +1 -0
  491. package/dist/apps/shared/mail/decryptedMessages.d.ts +27 -0
  492. package/dist/apps/shared/mail/decryptedMessages.js +97 -0
  493. package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -3
  494. package/dist/apps/shared/mail/findWellKnownFolderUid.js +5 -4
  495. package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
  496. package/dist/apps/shared/mail/folderCounts.js +6 -4
  497. package/dist/apps/shared/mail/folderOfType.d.ts +3 -2
  498. package/dist/apps/shared/mail/folderOfType.js +4 -4
  499. package/dist/apps/shared/mail/folderTree.d.ts +1 -1
  500. package/dist/apps/shared/mail/listSnapshots.d.ts +2 -2
  501. package/dist/apps/shared/mail/messageReadState.d.ts +4 -3
  502. package/dist/apps/shared/mail/messageReadState.js +5 -5
  503. package/dist/apps/shared/mail/newMailNotifications.d.ts +1 -1
  504. package/dist/apps/shared/mail/newMailNotifications.js +1 -1
  505. package/dist/apps/shared/mail/outbox/composeBridge.d.ts +2 -2
  506. package/dist/apps/shared/mail/outbox/outboxState.d.ts +1 -1
  507. package/dist/apps/shared/mail/outbox/outgoingReplies.d.ts +2 -2
  508. package/dist/apps/shared/mail/outbox/sendDecision.d.ts +2 -2
  509. package/dist/apps/shared/mail/outbox/sendDecision.js +1 -1
  510. package/dist/apps/shared/mail/outbox/sendJob.d.ts +10 -6
  511. package/dist/apps/shared/mail/outbox/sendJob.js +39 -35
  512. package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +6 -3
  513. package/dist/apps/shared/mail/outbox/sendOutcomes.js +19 -15
  514. package/dist/apps/shared/mail/outbox/useOutboxStatus.js +5 -3
  515. package/dist/apps/shared/mail/permanentDelete.d.ts +4 -3
  516. package/dist/apps/shared/mail/permanentDelete.js +8 -8
  517. package/dist/apps/shared/mail/primaryMailbox.d.ts +1 -1
  518. package/dist/apps/shared/mail/primaryMailbox.js +1 -1
  519. package/dist/apps/shared/mail/reportNotices.d.ts +1 -1
  520. package/dist/apps/shared/mail/senderBlocking.d.ts +5 -4
  521. package/dist/apps/shared/mail/senderBlocking.js +19 -16
  522. package/dist/apps/shared/mail/useMailConnection.d.ts +1 -1
  523. package/dist/apps/shared/mail/useMailConnection.js +12 -10
  524. package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +2 -2
  525. package/dist/apps/shared/mail/useMailLiveUpdates.js +2 -2
  526. package/dist/apps/shared/mail/useMailboxUpdateAccess.d.ts +3 -2
  527. package/dist/apps/shared/mail/useMailboxUpdateAccess.js +31 -10
  528. package/dist/apps/shared/mail/useMarkMessageRead.d.ts +1 -1
  529. package/dist/apps/shared/mail/useMarkMessageRead.js +5 -3
  530. package/dist/apps/shared/mail/useNewMailNotifications.d.ts +1 -1
  531. package/dist/apps/shared/mail/usePermanentDelete.d.ts +1 -1
  532. package/dist/apps/shared/mail/usePermanentDelete.js +4 -2
  533. package/dist/apps/shared/navigation/pageTitle.d.ts +1 -1
  534. package/dist/apps/shared/notifications/NotificationCenter.js +1 -1
  535. package/dist/apps/shared/notifications/NotificationHistoryDialog.js +2 -2
  536. package/dist/apps/shared/notifications/apiErrors.js +2 -2
  537. package/dist/apps/shared/notifications/pushStatus.js +1 -1
  538. package/dist/apps/shared/notifications/systemErrors.js +1 -1
  539. package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +2 -2
  540. package/dist/apps/shared/search/LocalIndexLifecycle.js +15 -10
  541. package/dist/apps/shared/search/crossMailboxSearch.d.ts +1 -1
  542. package/dist/apps/shared/search/crossMailboxSearch.js +2 -2
  543. package/dist/apps/shared/search/localIndexBuilder.d.ts +4 -3
  544. package/dist/apps/shared/search/localIndexBuilder.js +15 -12
  545. package/dist/apps/shared/search/localIndexKey.js +1 -1
  546. package/dist/apps/shared/search/localIndexRpcClient.d.ts +43 -31
  547. package/dist/apps/shared/search/localIndexRpcClient.js +113 -20
  548. package/dist/apps/shared/search/localIndexTransport.d.ts +77 -0
  549. package/dist/apps/shared/search/localIndexTransport.js +1 -0
  550. package/dist/apps/shared/search/localIndexWorker.d.ts +1 -1
  551. package/dist/apps/shared/search/searchTier2.d.ts +3 -3
  552. package/dist/apps/shared/signing/enrollmentTracker.d.ts +1 -1
  553. package/dist/apps/shared/signing/enrollmentTracker.js +3 -3
  554. package/dist/apps/shared/signing/enrollmentView.d.ts +1 -1
  555. package/dist/apps/shared/signing/signingInfo.d.ts +1 -1
  556. package/dist/apps/shared/signing/signingInfo.js +1 -1
  557. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +1 -1
  558. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +5 -3
  559. package/dist/apps/shared/styles/app.css +14 -23
  560. package/dist/apps/www/_layout.d.ts +1 -1
  561. package/dist/apps/www/_layout.js +1 -1
  562. package/dist/apps/www/calendar/index.d.ts +1 -1
  563. package/dist/apps/www/calendar/index.js +20 -18
  564. package/dist/apps/www/contacts/[uid].d.ts +1 -1
  565. package/dist/apps/www/contacts/[uid].js +8 -6
  566. package/dist/apps/www/contacts/index.d.ts +1 -1
  567. package/dist/apps/www/contacts/index.js +19 -17
  568. package/dist/apps/www/index.d.ts +1 -1
  569. package/dist/apps/www/index.js +64 -50
  570. package/dist/apps/www/messages/[uid].d.ts +1 -1
  571. package/dist/apps/www/messages/[uid].js +11 -9
  572. package/dist/apps/www/settings/appearance/index.d.ts +1 -1
  573. package/dist/apps/www/settings/auto-reply/index.d.ts +1 -1
  574. package/dist/apps/www/settings/auto-reply/index.js +6 -4
  575. package/dist/apps/www/settings/blocked-senders/index.d.ts +1 -1
  576. package/dist/apps/www/settings/blocked-senders/index.js +6 -4
  577. package/dist/apps/www/settings/encryption/index.d.ts +1 -1
  578. package/dist/apps/www/settings/encryption/index.js +31 -29
  579. package/dist/apps/www/settings/filters/[uid].d.ts +1 -1
  580. package/dist/apps/www/settings/filters/[uid].js +11 -9
  581. package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +2 -2
  582. package/dist/apps/www/settings/filters/index.d.ts +1 -1
  583. package/dist/apps/www/settings/filters/index.js +4 -4
  584. package/dist/apps/www/settings/filters/new/index.d.ts +1 -1
  585. package/dist/apps/www/settings/filters/new/index.js +10 -8
  586. package/dist/apps/www/settings/labels/index.d.ts +1 -1
  587. package/dist/apps/www/settings/labels/index.js +12 -10
  588. package/dist/apps/www/settings/privacy/index.d.ts +1 -1
  589. package/dist/apps/www/settings/privacy/index.js +18 -14
  590. package/dist/apps/www/settings/profile/index.d.ts +1 -1
  591. package/dist/apps/www/settings/profile/index.js +7 -5
  592. package/dist/apps/www/settings/read-receipts/index.d.ts +1 -1
  593. package/dist/apps/www/settings/read-receipts/index.js +5 -3
  594. package/dist/apps/www/settings/sharing/index.d.ts +1 -1
  595. package/dist/apps/www/settings/sharing/index.js +6 -6
  596. package/dist/apps/www/settings/signatures/[uid].d.ts +1 -1
  597. package/dist/apps/www/settings/signatures/[uid].js +5 -5
  598. package/dist/apps/www/settings/signatures/index.d.ts +1 -1
  599. package/dist/apps/www/settings/signatures/index.js +4 -4
  600. package/dist/apps/www/settings/signatures/new/index.d.ts +1 -1
  601. package/dist/apps/www/settings/signatures/new/index.js +4 -4
  602. package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +1 -1
  603. package/dist/apps/www/settings/signatures/signatureDefaults.js +1 -1
  604. package/dist/apps/www/tasks/index.d.ts +1 -1
  605. package/dist/apps/www/tasks/index.js +17 -15
  606. package/dist/lib/admin/auditLogApi.d.ts +32 -0
  607. package/dist/lib/admin/auditLogApi.js +27 -0
  608. package/dist/lib/admin/distributionListsApi.d.ts +47 -0
  609. package/dist/lib/admin/distributionListsApi.js +34 -0
  610. package/dist/lib/admin/domainsApi.d.ts +75 -0
  611. package/dist/lib/admin/domainsApi.js +44 -0
  612. package/dist/lib/admin/escrowAccessRequestsApi.d.ts +79 -0
  613. package/dist/lib/admin/escrowAccessRequestsApi.js +46 -0
  614. package/dist/lib/admin/escrowAuditLogApi.d.ts +66 -0
  615. package/dist/lib/admin/escrowAuditLogApi.js +31 -0
  616. package/dist/lib/admin/escrowScopesApi.d.ts +78 -0
  617. package/dist/lib/admin/escrowScopesApi.js +50 -0
  618. package/dist/lib/admin/leftoverMailboxApi.d.ts +73 -0
  619. package/dist/lib/admin/leftoverMailboxApi.js +67 -0
  620. package/dist/lib/admin/mailboxPolicyApi.d.ts +27 -0
  621. package/dist/lib/admin/mailboxPolicyApi.js +21 -0
  622. package/dist/lib/admin/matterExportApi.d.ts +40 -0
  623. package/dist/lib/admin/matterExportApi.js +39 -0
  624. package/dist/lib/admin/matterSearchApi.d.ts +20 -0
  625. package/dist/lib/admin/matterSearchApi.js +27 -0
  626. package/dist/lib/admin/mattersApi.d.ts +56 -0
  627. package/dist/lib/admin/mattersApi.js +40 -0
  628. package/dist/lib/admin/pluginsApi.d.ts +265 -0
  629. package/dist/lib/admin/pluginsApi.js +102 -0
  630. package/dist/lib/admin/retentionPolicyApi.d.ts +32 -0
  631. package/dist/lib/admin/retentionPolicyApi.js +29 -0
  632. package/dist/lib/admin/setupApi.d.ts +23 -0
  633. package/dist/lib/admin/setupApi.js +26 -0
  634. package/dist/lib/admin/transportRulesApi.d.ts +66 -0
  635. package/dist/lib/admin/transportRulesApi.js +43 -0
  636. package/dist/lib/appearance/preferencesApi.d.ts +128 -0
  637. package/dist/lib/appearance/preferencesApi.js +257 -0
  638. package/dist/lib/auth/profileApi.d.ts +33 -0
  639. package/dist/lib/auth/profileApi.js +52 -0
  640. package/dist/lib/auth/session.d.ts +70 -0
  641. package/dist/lib/auth/session.js +210 -0
  642. package/dist/lib/branding/brandingApi.d.ts +47 -0
  643. package/dist/lib/branding/brandingApi.js +61 -0
  644. package/dist/lib/branding/useBranding.d.ts +23 -0
  645. package/dist/lib/branding/useBranding.js +65 -0
  646. package/dist/lib/calendar/calendarApi.d.ts +230 -0
  647. package/dist/lib/calendar/calendarApi.js +106 -0
  648. package/dist/lib/calendar/calendarColors.d.ts +18 -0
  649. package/dist/lib/calendar/calendarColors.js +39 -0
  650. package/dist/lib/calendar/calendarDragIds.d.ts +42 -0
  651. package/dist/lib/calendar/calendarDragIds.js +92 -0
  652. package/dist/lib/calendar/calendarMutations.d.ts +68 -0
  653. package/dist/lib/calendar/calendarMutations.js +190 -0
  654. package/dist/lib/calendar/eventDescription.d.ts +43 -0
  655. package/dist/lib/calendar/eventDescription.js +195 -0
  656. package/dist/lib/calendar/freeBusyApi.d.ts +100 -0
  657. package/dist/lib/calendar/freeBusyApi.js +119 -0
  658. package/dist/lib/calendar/inviteApi.d.ts +121 -0
  659. package/dist/lib/calendar/inviteApi.js +54 -0
  660. package/dist/lib/calendar/recurrence.d.ts +60 -0
  661. package/dist/lib/calendar/recurrence.js +225 -0
  662. package/dist/lib/components/avatar/ContactAvatar.d.ts +8 -0
  663. package/dist/lib/components/avatar/ContactAvatar.js +26 -0
  664. package/dist/lib/components/buttons/Button.d.ts +9 -0
  665. package/dist/lib/components/buttons/Button.js +14 -0
  666. package/dist/lib/components/buttons/CopyButton.d.ts +18 -0
  667. package/dist/lib/components/buttons/CopyButton.js +14 -0
  668. package/dist/lib/components/feedback/Alert.d.ts +4 -0
  669. package/dist/lib/components/feedback/Alert.js +4 -0
  670. package/dist/lib/components/feedback/Skeleton.d.ts +21 -0
  671. package/dist/lib/components/feedback/Skeleton.js +14 -0
  672. package/dist/lib/components/forms/FormField.d.ts +8 -0
  673. package/dist/lib/components/forms/FormField.js +5 -0
  674. package/dist/lib/components/navigation/BottomTabBar.d.ts +27 -0
  675. package/dist/lib/components/navigation/BottomTabBar.js +32 -0
  676. package/dist/lib/components/overlays/Drawer.d.ts +20 -0
  677. package/dist/lib/components/overlays/Drawer.js +27 -0
  678. package/dist/lib/components/overlays/Modal.d.ts +17 -0
  679. package/dist/lib/components/overlays/Modal.js +25 -0
  680. package/dist/lib/components/overlays/PopoverPortal.d.ts +23 -0
  681. package/dist/lib/components/overlays/PopoverPortal.js +53 -0
  682. package/dist/lib/components/overlays/overlayStack.d.ts +31 -0
  683. package/dist/lib/components/overlays/overlayStack.js +143 -0
  684. package/dist/lib/components/pickers/MiniDatePicker.d.ts +13 -0
  685. package/dist/lib/components/pickers/MiniDatePicker.js +42 -0
  686. package/dist/lib/contacts/contactsApi.d.ts +174 -0
  687. package/dist/lib/contacts/contactsApi.js +139 -0
  688. package/dist/lib/contacts/vcard.d.ts +23 -0
  689. package/dist/lib/contacts/vcard.js +179 -0
  690. package/dist/lib/crypto/composeSecurity.d.ts +67 -0
  691. package/dist/lib/crypto/composeSecurity.js +93 -0
  692. package/dist/lib/crypto/encoding.d.ts +9 -0
  693. package/dist/lib/crypto/encoding.js +32 -0
  694. package/dist/lib/crypto/escrowKeys.d.ts +25 -0
  695. package/dist/lib/crypto/escrowKeys.js +59 -0
  696. package/dist/lib/crypto/idleTimeout.d.ts +16 -0
  697. package/dist/lib/crypto/idleTimeout.js +47 -0
  698. package/dist/lib/crypto/keySession.d.ts +159 -0
  699. package/dist/lib/crypto/keySession.js +367 -0
  700. package/dist/lib/crypto/keys.d.ts +50 -0
  701. package/dist/lib/crypto/keys.js +89 -0
  702. package/dist/lib/crypto/keyvaultApi.d.ts +394 -0
  703. package/dist/lib/crypto/keyvaultApi.js +350 -0
  704. package/dist/lib/crypto/masterKey.d.ts +59 -0
  705. package/dist/lib/crypto/masterKey.js +104 -0
  706. package/dist/lib/crypto/masterKeyWraps.d.ts +108 -0
  707. package/dist/lib/crypto/masterKeyWraps.js +228 -0
  708. package/dist/lib/crypto/messageSecurity.d.ts +248 -0
  709. package/dist/lib/crypto/messageSecurity.js +367 -0
  710. package/dist/lib/crypto/mime.d.ts +143 -0
  711. package/dist/lib/crypto/mime.js +504 -0
  712. package/dist/lib/crypto/passkeyUnlock.d.ts +20 -0
  713. package/dist/lib/crypto/passkeyUnlock.js +79 -0
  714. package/dist/lib/crypto/passwordUnlock.d.ts +39 -0
  715. package/dist/lib/crypto/passwordUnlock.js +73 -0
  716. package/dist/lib/crypto/recoveryCode.d.ts +28 -0
  717. package/dist/lib/crypto/recoveryCode.js +86 -0
  718. package/dist/lib/crypto/signingProviderApi.d.ts +95 -0
  719. package/dist/lib/crypto/signingProviderApi.js +60 -0
  720. package/dist/lib/crypto/smime.d.ts +128 -0
  721. package/dist/lib/crypto/smime.js +402 -0
  722. package/dist/lib/crypto/smimeMessage.d.ts +132 -0
  723. package/dist/lib/crypto/smimeMessage.js +341 -0
  724. package/dist/lib/crypto/useIdleKeyTimeout.d.ts +10 -0
  725. package/dist/lib/crypto/useIdleKeyTimeout.js +163 -0
  726. package/dist/lib/crypto/verificationSeal.d.ts +56 -0
  727. package/dist/lib/crypto/verificationSeal.js +220 -0
  728. package/dist/lib/mail/compose/composeQuoting.d.ts +88 -0
  729. package/dist/lib/mail/compose/composeQuoting.js +204 -0
  730. package/dist/lib/mail/compose/emojiData.d.ts +9 -0
  731. package/dist/lib/mail/compose/emojiData.js +18 -0
  732. package/dist/lib/mail/compose/giphyApi.d.ts +17 -0
  733. package/dist/lib/mail/compose/giphyApi.js +20 -0
  734. package/dist/lib/mail/conversationsApi.d.ts +80 -0
  735. package/dist/lib/mail/conversationsApi.js +44 -0
  736. package/dist/lib/mail/dataExportApi.d.ts +50 -0
  737. package/dist/lib/mail/dataExportApi.js +40 -0
  738. package/dist/lib/mail/directoryApi.d.ts +49 -0
  739. package/dist/lib/mail/directoryApi.js +101 -0
  740. package/dist/lib/mail/erasureRequestApi.d.ts +45 -0
  741. package/dist/lib/mail/erasureRequestApi.js +43 -0
  742. package/dist/lib/mail/flaggedMessages.d.ts +22 -0
  743. package/dist/lib/mail/flaggedMessages.js +73 -0
  744. package/dist/lib/mail/focusedInboxOverridesApi.d.ts +37 -0
  745. package/dist/lib/mail/focusedInboxOverridesApi.js +34 -0
  746. package/dist/lib/mail/labelsApi.d.ts +47 -0
  747. package/dist/lib/mail/labelsApi.js +38 -0
  748. package/dist/lib/mail/mailAddress.d.ts +27 -0
  749. package/dist/lib/mail/mailAddress.js +54 -0
  750. package/dist/lib/mail/mailApi.d.ts +850 -0
  751. package/dist/lib/mail/mailApi.js +602 -0
  752. package/dist/lib/mail/mailDetailHooks.d.ts +10 -0
  753. package/dist/lib/mail/mailDetailHooks.js +53 -0
  754. package/dist/lib/mail/mailFilterRulesApi.d.ts +76 -0
  755. package/dist/lib/mail/mailFilterRulesApi.js +45 -0
  756. package/dist/lib/mail/mailSignaturesApi.d.ts +49 -0
  757. package/dist/lib/mail/mailSignaturesApi.js +42 -0
  758. package/dist/lib/mail/mailboxAccessApi.d.ts +74 -0
  759. package/dist/lib/mail/mailboxAccessApi.js +56 -0
  760. package/dist/lib/mail/mailboxImportApi.d.ts +53 -0
  761. package/dist/lib/mail/mailboxImportApi.js +51 -0
  762. package/dist/lib/mail/messageBodySanitizer.d.ts +16 -0
  763. package/dist/lib/mail/messageBodySanitizer.js +118 -0
  764. package/dist/lib/mail/pushClient.d.ts +106 -0
  765. package/dist/lib/mail/pushClient.js +317 -0
  766. package/dist/lib/mail/sendEvents.d.ts +33 -0
  767. package/dist/lib/mail/sendEvents.js +44 -0
  768. package/dist/lib/mail/sendFailure.d.ts +16 -0
  769. package/dist/lib/mail/sendFailure.js +86 -0
  770. package/dist/lib/mail/senderListsApi.d.ts +69 -0
  771. package/dist/lib/mail/senderListsApi.js +126 -0
  772. package/dist/lib/search/queryGrammar.d.ts +51 -0
  773. package/dist/lib/search/queryGrammar.js +111 -0
  774. package/dist/lib/search/searchApi.d.ts +100 -0
  775. package/dist/lib/search/searchApi.js +107 -0
  776. package/dist/lib/search/searchScoring.d.ts +34 -0
  777. package/dist/lib/search/searchScoring.js +44 -0
  778. package/dist/lib/search/searchTier3.d.ts +64 -0
  779. package/dist/lib/search/searchTier3.js +335 -0
  780. package/dist/lib/tasks/tasksApi.d.ts +85 -0
  781. package/dist/lib/tasks/tasksApi.js +55 -0
  782. package/dist/lib/util/api.d.ts +160 -0
  783. package/dist/lib/util/api.js +251 -0
  784. package/dist/lib/util/apiClientContext.d.ts +7 -0
  785. package/dist/lib/util/apiClientContext.js +32 -0
  786. package/dist/lib/util/apiQuery.d.ts +32 -0
  787. package/dist/lib/util/apiQuery.js +42 -0
  788. package/dist/lib/util/clipboard.d.ts +7 -0
  789. package/dist/lib/util/clipboard.js +56 -0
  790. package/dist/lib/util/dateInput.d.ts +6 -0
  791. package/dist/lib/util/dateInput.js +14 -0
  792. package/dist/lib/util/timeZone.d.ts +12 -0
  793. package/dist/lib/util/timeZone.js +32 -0
  794. package/dist/lib/util/useCopyToClipboard.d.ts +12 -0
  795. package/dist/lib/util/useCopyToClipboard.js +34 -0
  796. package/dist/lib/util/useIsMobile.d.ts +10 -0
  797. package/dist/lib/util/useIsMobile.js +29 -0
  798. package/dist/lib/videoconf/videoMeetingsApi.d.ts +116 -0
  799. package/dist/lib/videoconf/videoMeetingsApi.js +49 -0
  800. package/lib/admin/auditLogApi.ts +48 -0
  801. package/lib/admin/distributionListsApi.ts +77 -0
  802. package/lib/admin/domainsApi.ts +113 -0
  803. package/lib/admin/escrowAccessRequestsApi.ts +110 -0
  804. package/lib/admin/escrowAuditLogApi.ts +101 -0
  805. package/lib/admin/escrowScopesApi.ts +112 -0
  806. package/lib/admin/leftoverMailboxApi.ts +120 -0
  807. package/lib/admin/mailboxPolicyApi.ts +38 -0
  808. package/lib/admin/matterExportApi.ts +62 -0
  809. package/lib/admin/matterSearchApi.ts +35 -0
  810. package/lib/admin/mattersApi.ts +86 -0
  811. package/lib/admin/pluginsApi.ts +339 -0
  812. package/lib/admin/retentionPolicyApi.ts +46 -0
  813. package/lib/admin/setupApi.ts +40 -0
  814. package/lib/admin/transportRulesApi.ts +106 -0
  815. package/lib/appearance/preferencesApi.ts +335 -0
  816. package/lib/auth/profileApi.ts +77 -0
  817. package/lib/auth/session.ts +238 -0
  818. package/lib/branding/brandingApi.ts +97 -0
  819. package/lib/branding/useBranding.ts +81 -0
  820. package/lib/calendar/calendarApi.ts +309 -0
  821. package/lib/calendar/calendarColors.ts +45 -0
  822. package/lib/calendar/calendarDragIds.ts +112 -0
  823. package/lib/calendar/calendarMutations.ts +236 -0
  824. package/lib/calendar/eventDescription.ts +211 -0
  825. package/lib/calendar/freeBusyApi.ts +197 -0
  826. package/lib/calendar/inviteApi.ts +154 -0
  827. package/lib/calendar/recurrence.ts +285 -0
  828. package/lib/components/avatar/ContactAvatar.tsx +47 -0
  829. package/lib/components/buttons/Button.tsx +40 -0
  830. package/lib/components/buttons/CopyButton.tsx +45 -0
  831. package/lib/components/feedback/Alert.tsx +13 -0
  832. package/lib/components/feedback/Skeleton.tsx +38 -0
  833. package/lib/components/forms/FormField.tsx +23 -0
  834. package/lib/components/navigation/BottomTabBar.tsx +66 -0
  835. package/lib/components/overlays/Drawer.tsx +72 -0
  836. package/lib/components/overlays/Modal.tsx +64 -0
  837. package/lib/components/overlays/PopoverPortal.tsx +74 -0
  838. package/lib/components/overlays/overlayStack.ts +165 -0
  839. package/lib/components/pickers/MiniDatePicker.tsx +90 -0
  840. package/lib/contacts/contactsApi.ts +289 -0
  841. package/lib/contacts/vcard.ts +197 -0
  842. package/lib/crypto/composeSecurity.ts +140 -0
  843. package/lib/crypto/encoding.ts +36 -0
  844. package/lib/crypto/escrowKeys.ts +74 -0
  845. package/lib/crypto/idleTimeout.ts +49 -0
  846. package/lib/crypto/keySession.ts +483 -0
  847. package/lib/crypto/keys.ts +105 -0
  848. package/lib/crypto/keyvaultApi.ts +674 -0
  849. package/lib/crypto/masterKey.ts +134 -0
  850. package/lib/crypto/masterKeyWraps.ts +269 -0
  851. package/lib/crypto/messageSecurity.ts +600 -0
  852. package/lib/crypto/mime.ts +568 -0
  853. package/lib/crypto/passkeyUnlock.ts +103 -0
  854. package/lib/crypto/passwordUnlock.ts +98 -0
  855. package/lib/crypto/recoveryCode.ts +93 -0
  856. package/lib/crypto/signingProviderApi.ts +135 -0
  857. package/lib/crypto/smime.ts +459 -0
  858. package/lib/crypto/smimeMessage.ts +491 -0
  859. package/lib/crypto/useIdleKeyTimeout.ts +176 -0
  860. package/lib/crypto/verificationSeal.ts +288 -0
  861. package/lib/mail/compose/composeQuoting.ts +243 -0
  862. package/lib/mail/compose/emojiData.ts +34 -0
  863. package/lib/mail/compose/giphyApi.ts +31 -0
  864. package/lib/mail/conversationsApi.ts +123 -0
  865. package/lib/mail/dataExportApi.ts +73 -0
  866. package/lib/mail/directoryApi.ts +161 -0
  867. package/lib/mail/erasureRequestApi.ts +71 -0
  868. package/lib/mail/flaggedMessages.ts +80 -0
  869. package/lib/mail/focusedInboxOverridesApi.ts +64 -0
  870. package/lib/mail/labelsApi.ts +71 -0
  871. package/lib/mail/mailAddress.ts +76 -0
  872. package/lib/mail/mailApi.ts +1286 -0
  873. package/lib/mail/mailDetailHooks.ts +57 -0
  874. package/lib/mail/mailFilterRulesApi.ts +116 -0
  875. package/lib/mail/mailSignaturesApi.ts +84 -0
  876. package/lib/mail/mailboxAccessApi.ts +106 -0
  877. package/lib/mail/mailboxImportApi.ts +87 -0
  878. package/lib/mail/messageBodySanitizer.ts +129 -0
  879. package/lib/mail/pushClient.ts +375 -0
  880. package/lib/mail/sendEvents.ts +72 -0
  881. package/lib/mail/sendFailure.ts +98 -0
  882. package/lib/mail/senderListsApi.ts +161 -0
  883. package/lib/search/queryGrammar.ts +179 -0
  884. package/lib/search/searchApi.ts +199 -0
  885. package/lib/search/searchScoring.ts +46 -0
  886. package/lib/search/searchTier3.ts +406 -0
  887. package/lib/tasks/tasksApi.ts +128 -0
  888. package/lib/util/api.ts +318 -0
  889. package/lib/util/apiClientContext.ts +35 -0
  890. package/lib/util/apiQuery.ts +61 -0
  891. package/lib/util/clipboard.ts +55 -0
  892. package/lib/util/dateInput.ts +15 -0
  893. package/lib/util/timeZone.ts +33 -0
  894. package/lib/util/useCopyToClipboard.ts +48 -0
  895. package/lib/util/useIsMobile.ts +34 -0
  896. package/lib/videoconf/videoMeetingsApi.ts +144 -0
  897. package/package.json +10 -4
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ ///////////////////////////////////////////////////////////////////////////////
3
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
4
+ // SPDX-License-Identifier: MPL-2.0
5
+ ///////////////////////////////////////////////////////////////////////////////
6
+ import { useEffect, useRef, useState } from "react";
7
+ import { createPortal } from "react-dom";
8
+ /**
9
+ * Renders its children into `document.body` (via a portal), `position: fixed` at a spot computed from
10
+ * `anchorRef`'s own rect — used by `EmojiPicker`/`GifPicker` so the popup escapes every ancestor's
11
+ * `overflow-hidden` (the Compose window's own outer frame, and `RichTextEditor`'s bordered wrapper
12
+ * both clip anything positioned merely `absolute` inside them, however high its `z-index` — clipping
13
+ * isn't a stacking-order problem `z-index` can override). Prefers opening *below* the anchor (there's
14
+ * more room in the editor area below the toolbar than above it, where the To/Cc/Subject rows are —
15
+ * confirmed directly: an earlier `absolute`+`overflow-hidden` version of this rendered the popup
16
+ * behind those rows), flipping to *above* only if there isn't enough room below.
17
+ */
18
+ export default function PopoverPortal({ anchorRef, onClose, width, height, children, ...rest }) {
19
+ const containerRef = useRef(null);
20
+ const [style, setStyle] = useState(null);
21
+ // Read through a ref, like `overlayStack.ts`'s `onCloseRef`: callers (EmojiPicker/GifPicker) routinely pass
22
+ // `onClose` as a fresh inline function every render, and depending on it directly would remove/re-add the
23
+ // document listener on every parent re-render instead of just once on mount.
24
+ const onCloseRef = useRef(onClose);
25
+ onCloseRef.current = onClose;
26
+ useEffect(() => {
27
+ const rect = anchorRef.current?.getBoundingClientRect();
28
+ if (!rect) {
29
+ return;
30
+ }
31
+ const gap = 6;
32
+ const margin = 8;
33
+ const spaceBelow = window.innerHeight - rect.bottom;
34
+ const top = spaceBelow >= height + gap ? rect.bottom + gap : Math.max(margin, rect.top - height - gap);
35
+ const left = Math.min(Math.max(rect.left, margin), window.innerWidth - width - margin);
36
+ setStyle({ position: "fixed", top, left, width, height });
37
+ }, [anchorRef, height, width]);
38
+ useEffect(() => {
39
+ function handlePointerDown(e) {
40
+ const target = e.target;
41
+ if (containerRef.current?.contains(target) || anchorRef.current?.contains(target)) {
42
+ return;
43
+ }
44
+ onCloseRef.current();
45
+ }
46
+ document.addEventListener("pointerdown", handlePointerDown);
47
+ return () => document.removeEventListener("pointerdown", handlePointerDown);
48
+ }, [anchorRef]);
49
+ if (!style) {
50
+ return null;
51
+ }
52
+ return createPortal(_jsx("div", { ref: containerRef, role: "dialog", style: style, className: "z-50 flex flex-col bg-surface border border-border rounded-md shadow-modal overflow-hidden", ...rest, children: children }), document.body);
53
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The shared dialog behavior behind `Modal.tsx` and `Drawer.tsx`: a module-level stack of every open
3
+ * overlay, so that when overlays nest (a Modal opened from inside a Drawer, a confirm Modal on top of an
4
+ * edit Modal) only the *topmost* one reacts to Escape and traps Tab — pressing Escape once closes one
5
+ * layer, not every layer at once.
6
+ *
7
+ * One `keydown` listener on `document` is installed while the stack is non-empty and dispatches to the
8
+ * top entry only. A per-overlay listener that checked "am I on top?" wouldn't be enough: the top
9
+ * overlay's `onClose` only *schedules* a React state update, so a lower overlay's listener running later
10
+ * in the same dispatch would still see itself as not-on-top only by luck of ordering.
11
+ */
12
+ import { RefObject } from "react";
13
+ /**
14
+ * The nesting depth of the overlay rendering a subtree. Overlays wrap their children in a provider with
15
+ * the value `useOverlayDialog()` returns, so an overlay rendered inside another's children knows it
16
+ * belongs above it regardless of effect ordering - see `push()`.
17
+ */
18
+ export declare const OverlayDepthContext: import("react").Context<number>;
19
+ /**
20
+ * Wires one open overlay into the stack: on open, remembers the previously focused element and moves
21
+ * focus into `dialogRef`'s element; while open *and topmost*, Escape calls `onClose` and Tab/Shift+Tab
22
+ * cycle focus within the dialog; on close/unmount, leaves the stack and restores focus to whatever had it
23
+ * before opening (when that's still an `HTMLElement`).
24
+ *
25
+ * `onClose` is read through a ref: callers routinely pass it as a fresh inline function every render, and
26
+ * depending on it directly would re-run the effect - re-stealing focus into the dialog - on every parent
27
+ * re-render (e.g. every keystroke in a field inside the dialog).
28
+ *
29
+ * Returns the depth to provide to the overlay's children via `OverlayDepthContext`.
30
+ */
31
+ export declare function useOverlayDialog(open: boolean, dialogRef: RefObject<HTMLElement | null>, onClose: () => void): number;
@@ -0,0 +1,143 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /**
6
+ * The shared dialog behavior behind `Modal.tsx` and `Drawer.tsx`: a module-level stack of every open
7
+ * overlay, so that when overlays nest (a Modal opened from inside a Drawer, a confirm Modal on top of an
8
+ * edit Modal) only the *topmost* one reacts to Escape and traps Tab — pressing Escape once closes one
9
+ * layer, not every layer at once.
10
+ *
11
+ * One `keydown` listener on `document` is installed while the stack is non-empty and dispatches to the
12
+ * top entry only. A per-overlay listener that checked "am I on top?" wouldn't be enough: the top
13
+ * overlay's `onClose` only *schedules* a React state update, so a lower overlay's listener running later
14
+ * in the same dispatch would still see itself as not-on-top only by luck of ordering.
15
+ */
16
+ import { createContext, useContext, useEffect, useRef } from "react";
17
+ /**
18
+ * The nesting depth of the overlay rendering a subtree. Overlays wrap their children in a provider with
19
+ * the value `useOverlayDialog()` returns, so an overlay rendered inside another's children knows it
20
+ * belongs above it regardless of effect ordering - see `push()`.
21
+ */
22
+ export const OverlayDepthContext = createContext(0);
23
+ const stack = [];
24
+ /** Everything natively tabbable - disabled controls, `tabindex="-1"`, and hidden inputs excluded. */
25
+ const TABBABLE_SELECTOR = [
26
+ "a[href]",
27
+ "area[href]",
28
+ "button:not([disabled])",
29
+ "input:not([disabled]):not([type='hidden'])",
30
+ "select:not([disabled])",
31
+ "textarea:not([disabled])",
32
+ "iframe",
33
+ "audio[controls]",
34
+ "video[controls]",
35
+ "[contenteditable]:not([contenteditable='false'])",
36
+ "[tabindex]",
37
+ ].join(",");
38
+ function tabbableElements(container) {
39
+ return Array.from(container.querySelectorAll(TABBABLE_SELECTOR)).filter((el) => el.tabIndex >= 0 && !el.hasAttribute("inert") && !el.closest("[hidden]"));
40
+ }
41
+ function handleKeyDown(e) {
42
+ const top = stack[stack.length - 1];
43
+ const dialog = top.dialogRef.current;
44
+ if (e.key === "Escape") {
45
+ top.onEscape();
46
+ return;
47
+ }
48
+ if (e.key !== "Tab" || !dialog) {
49
+ return;
50
+ }
51
+ const tabbable = tabbableElements(dialog);
52
+ const active = document.activeElement;
53
+ if (tabbable.length === 0) {
54
+ e.preventDefault();
55
+ dialog.focus();
56
+ return;
57
+ }
58
+ const first = tabbable[0];
59
+ const last = tabbable[tabbable.length - 1];
60
+ const outside = !dialog.contains(active);
61
+ if (e.shiftKey) {
62
+ if (outside || active === first || active === dialog) {
63
+ e.preventDefault();
64
+ last.focus();
65
+ }
66
+ }
67
+ else if (outside || active === last) {
68
+ e.preventDefault();
69
+ first.focus();
70
+ }
71
+ }
72
+ /** Identifies the synchronous burst of effects (one React commit) an entry was pushed in: bumped in a
73
+ * microtask after the first push of a burst, so every push from the same commit shares one value. */
74
+ let currentCommit = 0;
75
+ let commitBumpScheduled = false;
76
+ function push(entry) {
77
+ if (stack.length === 0) {
78
+ document.addEventListener("keydown", handleKeyDown);
79
+ }
80
+ if (!commitBumpScheduled) {
81
+ commitBumpScheduled = true;
82
+ queueMicrotask(() => {
83
+ commitBumpScheduled = false;
84
+ currentCommit++;
85
+ });
86
+ }
87
+ entry.commit = currentCommit;
88
+ // Normally just an append (the most recently opened overlay is on top). But React runs a child's
89
+ // effects before its parent's, so when a nested overlay mounts already-open in the same commit as the
90
+ // overlay containing it, the child is pushed first and would end up *under* its own container - so an
91
+ // entry goes below deeper entries pushed *in the same commit* (its not-yet-stacked children). A deeper
92
+ // entry from an earlier commit stays below it: an overlay opened later is on top regardless of depth
93
+ // (e.g. a top-level confirm opened while a nested Drawer > Modal is already showing).
94
+ let index = stack.length;
95
+ while (index > 0 && stack[index - 1].depth > entry.depth && stack[index - 1].commit === entry.commit) {
96
+ index--;
97
+ }
98
+ stack.splice(index, 0, entry);
99
+ }
100
+ function remove(entry) {
101
+ stack.splice(stack.indexOf(entry), 1);
102
+ if (stack.length === 0) {
103
+ document.removeEventListener("keydown", handleKeyDown);
104
+ }
105
+ }
106
+ /**
107
+ * Wires one open overlay into the stack: on open, remembers the previously focused element and moves
108
+ * focus into `dialogRef`'s element; while open *and topmost*, Escape calls `onClose` and Tab/Shift+Tab
109
+ * cycle focus within the dialog; on close/unmount, leaves the stack and restores focus to whatever had it
110
+ * before opening (when that's still an `HTMLElement`).
111
+ *
112
+ * `onClose` is read through a ref: callers routinely pass it as a fresh inline function every render, and
113
+ * depending on it directly would re-run the effect - re-stealing focus into the dialog - on every parent
114
+ * re-render (e.g. every keystroke in a field inside the dialog).
115
+ *
116
+ * Returns the depth to provide to the overlay's children via `OverlayDepthContext`.
117
+ */
118
+ export function useOverlayDialog(open, dialogRef, onClose) {
119
+ const depth = useContext(OverlayDepthContext);
120
+ const onCloseRef = useRef(onClose);
121
+ onCloseRef.current = onClose;
122
+ useEffect(() => {
123
+ if (!open)
124
+ return;
125
+ // Remember what had focus before the overlay opened so it can be restored on close (e.g. the
126
+ // "+ Add" button that triggered it), then move focus into the dialog itself.
127
+ const trigger = document.activeElement;
128
+ const entry = { dialogRef, onEscape: () => onCloseRef.current(), depth };
129
+ push(entry);
130
+ // An overlay that mounted open underneath an already-open nested one (see `push()`) must not
131
+ // steal focus from the overlay above it.
132
+ if (stack[stack.length - 1] === entry) {
133
+ dialogRef.current?.focus();
134
+ }
135
+ return () => {
136
+ remove(entry);
137
+ if (trigger instanceof HTMLElement) {
138
+ trigger.focus();
139
+ }
140
+ };
141
+ }, [open]);
142
+ return depth + 1;
143
+ }
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ export interface MiniDatePickerProps {
3
+ /** The main view's current date — determines both the month shown and which day is highlighted. */
4
+ selected: Date;
5
+ onSelect: (date: Date) => void;
6
+ }
7
+ /** A compact month-grid date picker for the Calendar sidebar, reusing `MonthView`'s own grid-generation
8
+ * approach (`date-fns`'s `startOfWeek`/`endOfWeek`/`eachDayOfInterval`, Monday-start) rather than
9
+ * re-deriving it — this component just renders that same grid far smaller and without any event data.
10
+ * Its own displayed month tracks `selected` (so navigating the main view keeps this in sync) but can
11
+ * also be paged independently via the arrows without moving the main view until a day is actually
12
+ * clicked. */
13
+ export default function MiniDatePicker({ selected, onSelect }: MiniDatePickerProps): React.JSX.Element;
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ ///////////////////////////////////////////////////////////////////////////////
3
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
4
+ // SPDX-License-Identifier: MPL-2.0
5
+ ///////////////////////////////////////////////////////////////////////////////
6
+ import { useState } from "react";
7
+ import { addMonths, eachDayOfInterval, endOfMonth, endOfWeek, format, isSameDay, isSameMonth, isToday, startOfMonth, startOfWeek } from "date-fns";
8
+ const WEEKDAY_LABELS = ["M", "T", "W", "T", "F", "S", "S"];
9
+ /** A compact month-grid date picker for the Calendar sidebar, reusing `MonthView`'s own grid-generation
10
+ * approach (`date-fns`'s `startOfWeek`/`endOfWeek`/`eachDayOfInterval`, Monday-start) rather than
11
+ * re-deriving it — this component just renders that same grid far smaller and without any event data.
12
+ * Its own displayed month tracks `selected` (so navigating the main view keeps this in sync) but can
13
+ * also be paged independently via the arrows without moving the main view until a day is actually
14
+ * clicked. */
15
+ export default function MiniDatePicker({ selected, onSelect }) {
16
+ const [shownMonth, setShownMonth] = useState(() => startOfMonth(selected));
17
+ // Tracks the last `selected` month this picker synced to, in the standard React
18
+ // "adjust state during render" shape — resyncs `shownMonth` whenever the caller's selected date
19
+ // moves to a different month (e.g. via the main view's own Previous/Next/Today controls), but
20
+ // otherwise leaves it alone so paging this picker's own arrows isn't immediately undone.
21
+ const [trackedSelectedMonth, setTrackedSelectedMonth] = useState(() => startOfMonth(selected));
22
+ if (!isSameMonth(trackedSelectedMonth, selected)) {
23
+ setTrackedSelectedMonth(startOfMonth(selected));
24
+ setShownMonth(startOfMonth(selected));
25
+ }
26
+ const gridStart = startOfWeek(startOfMonth(shownMonth), { weekStartsOn: 1 });
27
+ const gridEnd = endOfWeek(endOfMonth(shownMonth), { weekStartsOn: 1 });
28
+ const days = eachDayOfInterval({ start: gridStart, end: gridEnd });
29
+ return (_jsxs("nav", { "aria-label": "Mini calendar", className: "p-2", children: [_jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [_jsx("button", { type: "button", "aria-label": "Previous month", onClick: () => setShownMonth((m) => addMonths(m, -1)), className: "w-6 h-6 text-xs rounded-sm hover:bg-surface-alt", children: "\u2039" }), _jsx("span", { className: "text-xs font-semibold", children: format(shownMonth, "MMMM yyyy") }), _jsx("button", { type: "button", "aria-label": "Next month", onClick: () => setShownMonth((m) => addMonths(m, 1)), className: "w-6 h-6 text-xs rounded-sm hover:bg-surface-alt", children: "\u203A" })] }), _jsxs("div", { className: "grid grid-cols-7 gap-0.5", children: [WEEKDAY_LABELS.map((label, i) => (_jsx("div", { className: "text-[10px] text-text-muted text-center", children: label }, i))), days.map((day) => (_jsx("button", { type: "button", onClick: () => {
30
+ onSelect(day);
31
+ setShownMonth(startOfMonth(day));
32
+ }, className: [
33
+ "text-[11px] w-6 h-6 rounded-full flex items-center justify-center mx-auto",
34
+ isSameDay(day, selected)
35
+ ? "bg-primary text-white"
36
+ : isToday(day)
37
+ ? "text-primary-dark font-semibold"
38
+ : isSameMonth(day, shownMonth)
39
+ ? "text-text hover:bg-surface-alt"
40
+ : "text-text-muted/50 hover:bg-surface-alt",
41
+ ].join(" "), children: format(day, "d") }, day.toISOString())))] })] }));
42
+ }
@@ -0,0 +1,174 @@
1
+ /** Typed wrappers over `@rapidmx/restapi`'s `/mail/contacts` REST surface — see `mailApi.ts`'s own header
2
+ * comment for the shared ACL/authorization model every wrapper file here follows. */
3
+ import { ApiClient } from "../util/api.js";
4
+ import { ListParams } from "../util/apiQuery.js";
5
+ import { type EncryptionPreference, type KeyConflict, type PreviousKey, type PublicKey, type RejectedKey } from "../crypto/keyvaultApi.js";
6
+ export type ContactAddressKind = "home" | "work" | "other";
7
+ export interface ContactEmail {
8
+ address: string;
9
+ type: ContactAddressKind;
10
+ }
11
+ export interface ContactPhone {
12
+ phoneNumber: string;
13
+ type: ContactAddressKind;
14
+ }
15
+ export interface ContactPostalAddress {
16
+ street?: string;
17
+ city?: string;
18
+ state?: string;
19
+ postalCode?: string;
20
+ country?: string;
21
+ type: ContactAddressKind;
22
+ }
23
+ export interface Contact {
24
+ uid: string;
25
+ version: number;
26
+ dateCreated: string;
27
+ dateModified: string;
28
+ mailboxUid: string;
29
+ folderUid: string;
30
+ /** The `ContactList` (group) this contact belongs to, if any. */
31
+ contactListUid?: string;
32
+ displayName: string;
33
+ givenName?: string;
34
+ surname?: string;
35
+ emails: ContactEmail[];
36
+ phones: ContactPhone[];
37
+ addresses: ContactPostalAddress[];
38
+ company?: string;
39
+ jobTitle?: string;
40
+ notes?: string;
41
+ photoBlobKey?: string;
42
+ sourceUid?: string;
43
+ /** Whether the caller has starred/favorited this contact. Absent is equivalent to `false`. */
44
+ favorite?: boolean;
45
+ /** Free-form category labels (Outlook-style colored categories) applied to this contact, if any. */
46
+ categories?: string[];
47
+ /** Present (and `true`) only when fetched via `listDeletedContacts()` — a soft-deleted `RecoverableBaseEntity`
48
+ * record still exists server-side so it can be restored, per `@rapidmx/restapi`'s own soft-delete model. */
49
+ deleted?: boolean;
50
+ /** This contact's known encryption preference, per `specs/end-to-end_encryption.md` — discovered
51
+ * via `crypto/keyvaultApi.ts`'s `lookupKeys()` at compose time, never fetched on message receipt
52
+ * (that would leak read timing to the sender's server). */
53
+ encryptPreference?: EncryptionPreference;
54
+ /** This contact's pinned public keys. Trust is TOFU (trust-on-first-use) — see `keyConflicts` for what
55
+ * happens when a newly observed key differs from one of these. */
56
+ keys?: PublicKey[];
57
+ /** Observed keys that conflict with the currently pinned key of the same `useType`, at most one per `useType` —
58
+ * each blocks silent acceptance until the user resolves it (`keyvaultApi.ts`'s `resolveKeyConflict()`, the spec's
59
+ * Key Conflict Handling). The pinned `keys` are retained unchanged while a conflict is set. */
60
+ keyConflicts?: KeyConflict[];
61
+ /** Keys that were pinned before and replaced (by the user accepting a conflict, or by restapi's automatic
62
+ * same-issuer renewal of an expired or revoked key), newest first, at most 5 per `useType`. Signing keys here
63
+ * still count as trusted signers — see `signingKeyFingerprints()`. */
64
+ previousKeys?: PreviousKey[];
65
+ /** Keys the user rejected when resolving a conflict. */
66
+ rejectedKeys?: RejectedKey[];
67
+ }
68
+ /** Lists a folder's contacts, alphabetically by display name. Never includes soft-deleted contacts — see
69
+ * `listDeletedContacts()` for those. */
70
+ export declare function listContacts(folderUid: string, params?: ListParams, client?: ApiClient): Promise<Contact[]>;
71
+ /** The trusted signing-key fingerprints of every contact in `contacts` with an email equal (case-insensitively) to
72
+ * `address`: each contact's pinned `keys` and its `previousKeys`, so mail signed before a key rotation still verifies -
73
+ * see `keyvaultApi.ts`'s `signingKeyFingerprints()` for the rules (expired and superseded keys kept, compromised or reasonless revoked keys excluded). De-duplicated;
74
+ * `[]` when no contact matches or none has a trusted signing key. */
75
+ export declare function pinnedSigningFingerprintsFor(contacts: Contact[], address: string): string[];
76
+ /** Page size and page cap for `fetchPinnedSigningFingerprints()` and `fetchSignerKeyState()` (500 is restapi's own
77
+ * `limit` cap). */
78
+ export declare const PINNED_FINGERPRINT_PAGE_SIZE = 500;
79
+ export declare const PINNED_FINGERPRINT_MAX_PAGES = 20;
80
+ /**
81
+ * Fetches the trusted signing-key fingerprints (pinned and previous - see `pinnedSigningFingerprintsFor()`) for a
82
+ * message sender's `address` from the contacts in `folderUids` (the reader's contacts folders), for
83
+ * `evaluateMessageSecurity()`'s `pinnedSignerFingerprints`. Reads only what is already stored on the reader's own
84
+ * contacts - never triggers a Discovery lookup, which must not happen on message receipt (it would leak read timing to
85
+ * the sender's server). Pages through each folder (`PINNED_FINGERPRINT_PAGE_SIZE`, at most
86
+ * `PINNED_FINGERPRINT_MAX_PAGES` pages per folder). A caller rendering many messages should cache the contact list and
87
+ * use `pinnedSigningFingerprintsFor()` instead.
88
+ */
89
+ export declare function fetchPinnedSigningFingerprints(folderUids: string[], address: string, client?: ApiClient): Promise<string[]>;
90
+ /** A sender's stored signing-key state, for a key-changed comparison - see `signerKeyStateFor()`. */
91
+ export interface SignerKeyState {
92
+ /** The currently pinned signing keys (every `useType: "sign"` key, revoked and expired ones included, so a UI can
93
+ * show their dates and status), de-duplicated by fingerprint. */
94
+ pinned: PublicKey[];
95
+ /** Previously pinned signing keys, newest `replacedAt` first, de-duplicated by fingerprint. */
96
+ previous: PreviousKey[];
97
+ /** The first unresolved signing-key conflict found, if any. */
98
+ conflict?: KeyConflict;
99
+ }
100
+ /** The signing-key state of every contact in `contacts` with an email equal (case-insensitively) to `address`, merged -
101
+ * what a UI needs to compare a `signer_key_changed` message's certificate with the pinned and previous keys (their
102
+ * fingerprints and `notBefore`/`notAfter`/`revokedAt`/`replacedAt` dates) before calling `resolveKeyConflict()`. Empty
103
+ * `pinned`/`previous` and no `conflict` when no contact matches. */
104
+ export declare function signerKeyStateFor(contacts: Contact[], address: string): SignerKeyState;
105
+ /** Fetches `signerKeyStateFor()` for `address` from the contacts in `folderUids`, paging exactly like
106
+ * `fetchPinnedSigningFingerprints()`. Reads only stored contacts - never triggers a Discovery lookup. */
107
+ export declare function fetchSignerKeyState(folderUids: string[], address: string, client?: ApiClient): Promise<SignerKeyState>;
108
+ /**
109
+ * Lists a folder's soft-deleted contacts
110
+ (for an Outlook-style "Deleted" view) — `deleted` is an ordinary
111
+ * queryable field on `Contact` (a `RecoverableBaseEntity`), so this is the same `find()` the plain listing
112
+ * above uses, just constrained to `deleted: true` instead of the framework's own default of excluding them.
113
+ *
114
+ * Read-only for now — deliberately no `restoreContact()`: `@rapidmx/restapi`'s generic
115
+ * `BaseScopedChildRoute.update()` looks the target record up via a plain `findOne()` with no
116
+ * `includeDeleted` option, so it 404s on an already-deleted record before ever reaching the point where
117
+ * setting `deleted: false` would matter. Restoring would need a real fix in `@rapidmx/restapi` itself
118
+ * (passing `includeDeleted: true` into that lookup) — out of scope for this pass; the "Deleted" view here
119
+ * is browse-only until that lands.
120
+ */
121
+ export declare function listDeletedContacts(folderUid: string, params?: ListParams, client?: ApiClient): Promise<Contact[]>;
122
+ export declare function getContact(uid: string, client?: ApiClient): Promise<Contact>;
123
+ export interface ContactInput {
124
+ mailboxUid: string;
125
+ folderUid: string;
126
+ contactListUid?: string;
127
+ displayName: string;
128
+ givenName?: string;
129
+ surname?: string;
130
+ emails?: ContactEmail[];
131
+ phones?: ContactPhone[];
132
+ addresses?: ContactPostalAddress[];
133
+ company?: string;
134
+ jobTitle?: string;
135
+ notes?: string;
136
+ favorite?: boolean;
137
+ categories?: string[];
138
+ }
139
+ export declare function createContact(input: ContactInput, client?: ApiClient): Promise<Contact>;
140
+ export interface UpdateContactInput extends ContactInput {
141
+ uid: string;
142
+ version: number;
143
+ }
144
+ /** A minimal contact update: only `uid`/`version` are required, every other field is sent only if
145
+ * present. The server merges just the fields in the body and rejects server-managed ones
146
+ * (`dateCreated`/`dateModified`/etc.), so prefer sending only what actually changed over a whole
147
+ * fetched `Contact`. An `UpdateContactInput` is also a valid `ContactPatch`. */
148
+ export type ContactPatch = Partial<Contact> & Pick<Contact, "uid" | "version">;
149
+ export declare function updateContact(patch: ContactPatch, client?: ApiClient): Promise<Contact>;
150
+ /** Thin `updateContact()` wrapper for toggling favorite/star status — same pattern as `mailApi.ts`'s
151
+ * `setMessageRead()`/`tasksApi.ts`'s `setTaskCompleted()`. Sends only `uid`/`version`/`favorite`, never
152
+ * the rest of `contact` (the server rejects its managed fields). */
153
+ export declare function setContactFavorite(contact: Contact, favorite: boolean, client?: ApiClient): Promise<Contact>;
154
+ export declare function deleteContact(uid: string, version: number, client?: ApiClient): Promise<void>;
155
+ export interface ContactList {
156
+ uid: string;
157
+ version: number;
158
+ dateCreated: string;
159
+ dateModified: string;
160
+ mailboxUid: string;
161
+ name: string;
162
+ }
163
+ /** Lists a mailbox's contact lists (Outlook-style "Your contact lists"), alphabetically by name. */
164
+ export declare function listContactLists(mailboxUid: string, params?: ListParams, client?: ApiClient): Promise<ContactList[]>;
165
+ export declare function createContactList(input: {
166
+ mailboxUid: string;
167
+ name: string;
168
+ }, client?: ApiClient): Promise<ContactList>;
169
+ export declare function updateContactList(input: {
170
+ uid: string;
171
+ version: number;
172
+ name: string;
173
+ }, client?: ApiClient): Promise<ContactList>;
174
+ export declare function deleteContactList(uid: string, version: number, client?: ApiClient): Promise<void>;
@@ -0,0 +1,139 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /** Typed wrappers over `@rapidmx/restapi`'s `/mail/contacts` REST surface — see `mailApi.ts`'s own header
6
+ * comment for the shared ACL/authorization model every wrapper file here follows. */
7
+ import { withClient } from "../util/api.js";
8
+ import { buildQuery } from "../util/apiQuery.js";
9
+ import { signingKeyFingerprints, } from "../crypto/keyvaultApi.js";
10
+ /** Lists a folder's contacts, alphabetically by display name. Never includes soft-deleted contacts — see
11
+ * `listDeletedContacts()` for those. */
12
+ export function listContacts(folderUid, params = {}, client) {
13
+ return withClient(client, `/mail/contacts?${buildQuery(params, { folderUid, sort: JSON.stringify({ displayName: "ASC" }) })}`);
14
+ }
15
+ function contactsMatching(contacts, address) {
16
+ const wanted = address.trim().toLowerCase();
17
+ return contacts.filter((contact) => contact.emails.some((email) => email.address.trim().toLowerCase() === wanted));
18
+ }
19
+ /** The trusted signing-key fingerprints of every contact in `contacts` with an email equal (case-insensitively) to
20
+ * `address`: each contact's pinned `keys` and its `previousKeys`, so mail signed before a key rotation still verifies -
21
+ * see `keyvaultApi.ts`'s `signingKeyFingerprints()` for the rules (expired and superseded keys kept, compromised or reasonless revoked keys excluded). De-duplicated;
22
+ * `[]` when no contact matches or none has a trusted signing key. */
23
+ export function pinnedSigningFingerprintsFor(contacts, address) {
24
+ return [...new Set(contactsMatching(contacts, address).flatMap((contact) => signingKeyFingerprints(contact.keys, contact.previousKeys)))];
25
+ }
26
+ /** Page size and page cap for `fetchPinnedSigningFingerprints()` and `fetchSignerKeyState()` (500 is restapi's own
27
+ * `limit` cap). */
28
+ export const PINNED_FINGERPRINT_PAGE_SIZE = 500;
29
+ export const PINNED_FINGERPRINT_MAX_PAGES = 20;
30
+ /** Every contact in `folderUids`, paged (`PINNED_FINGERPRINT_PAGE_SIZE`, at most `PINNED_FINGERPRINT_MAX_PAGES` pages
31
+ * per folder). A plain contacts read - never a Discovery lookup. */
32
+ async function listContactsInFolders(folderUids, client) {
33
+ const contacts = [];
34
+ for (const folderUid of folderUids) {
35
+ for (let page = 0; page < PINNED_FINGERPRINT_MAX_PAGES; page++) {
36
+ const batch = await listContacts(folderUid, { limit: PINNED_FINGERPRINT_PAGE_SIZE, page }, client);
37
+ contacts.push(...batch);
38
+ if (batch.length < PINNED_FINGERPRINT_PAGE_SIZE) {
39
+ break;
40
+ }
41
+ }
42
+ }
43
+ return contacts;
44
+ }
45
+ /**
46
+ * Fetches the trusted signing-key fingerprints (pinned and previous - see `pinnedSigningFingerprintsFor()`) for a
47
+ * message sender's `address` from the contacts in `folderUids` (the reader's contacts folders), for
48
+ * `evaluateMessageSecurity()`'s `pinnedSignerFingerprints`. Reads only what is already stored on the reader's own
49
+ * contacts - never triggers a Discovery lookup, which must not happen on message receipt (it would leak read timing to
50
+ * the sender's server). Pages through each folder (`PINNED_FINGERPRINT_PAGE_SIZE`, at most
51
+ * `PINNED_FINGERPRINT_MAX_PAGES` pages per folder). A caller rendering many messages should cache the contact list and
52
+ * use `pinnedSigningFingerprintsFor()` instead.
53
+ */
54
+ export async function fetchPinnedSigningFingerprints(folderUids, address, client) {
55
+ return pinnedSigningFingerprintsFor(await listContactsInFolders(folderUids, client), address);
56
+ }
57
+ function uniqueByFingerprint(keys) {
58
+ const seen = new Set();
59
+ return keys.filter((key) => {
60
+ const fingerprint = key.fingerprint.toLowerCase();
61
+ if (seen.has(fingerprint)) {
62
+ return false;
63
+ }
64
+ seen.add(fingerprint);
65
+ return true;
66
+ });
67
+ }
68
+ /** The signing-key state of every contact in `contacts` with an email equal (case-insensitively) to `address`, merged -
69
+ * what a UI needs to compare a `signer_key_changed` message's certificate with the pinned and previous keys (their
70
+ * fingerprints and `notBefore`/`notAfter`/`revokedAt`/`replacedAt` dates) before calling `resolveKeyConflict()`. Empty
71
+ * `pinned`/`previous` and no `conflict` when no contact matches. */
72
+ export function signerKeyStateFor(contacts, address) {
73
+ const matching = contactsMatching(contacts, address);
74
+ const pinned = uniqueByFingerprint(matching.flatMap((contact) => (contact.keys ?? []).filter((key) => key.useType === "sign")));
75
+ const previous = uniqueByFingerprint(matching.flatMap((contact) => (contact.previousKeys ?? []).filter((key) => key.useType === "sign")).sort((a, b) => b.replacedAt - a.replacedAt));
76
+ const conflict = matching.flatMap((contact) => contact.keyConflicts ?? []).find((entry) => entry.useType === "sign");
77
+ return { pinned, previous, ...(conflict ? { conflict } : {}) };
78
+ }
79
+ /** Fetches `signerKeyStateFor()` for `address` from the contacts in `folderUids`, paging exactly like
80
+ * `fetchPinnedSigningFingerprints()`. Reads only stored contacts - never triggers a Discovery lookup. */
81
+ export async function fetchSignerKeyState(folderUids, address, client) {
82
+ return signerKeyStateFor(await listContactsInFolders(folderUids, client), address);
83
+ }
84
+ /**
85
+ * Lists a folder's soft-deleted contacts
86
+ (for an Outlook-style "Deleted" view) — `deleted` is an ordinary
87
+ * queryable field on `Contact` (a `RecoverableBaseEntity`), so this is the same `find()` the plain listing
88
+ * above uses, just constrained to `deleted: true` instead of the framework's own default of excluding them.
89
+ *
90
+ * Read-only for now — deliberately no `restoreContact()`: `@rapidmx/restapi`'s generic
91
+ * `BaseScopedChildRoute.update()` looks the target record up via a plain `findOne()` with no
92
+ * `includeDeleted` option, so it 404s on an already-deleted record before ever reaching the point where
93
+ * setting `deleted: false` would matter. Restoring would need a real fix in `@rapidmx/restapi` itself
94
+ * (passing `includeDeleted: true` into that lookup) — out of scope for this pass; the "Deleted" view here
95
+ * is browse-only until that lands.
96
+ */
97
+ export function listDeletedContacts(folderUid, params = {}, client) {
98
+ return withClient(client, `/mail/contacts?${buildQuery(params, { folderUid, deleted: "true", sort: JSON.stringify({ displayName: "ASC" }) })}`);
99
+ }
100
+ export function getContact(uid, client) {
101
+ return withClient(client, `/mail/contacts/${encodeURIComponent(uid)}`);
102
+ }
103
+ export function createContact(input, client) {
104
+ return withClient(client, "/mail/contacts", {
105
+ method: "POST",
106
+ body: JSON.stringify({ emails: [], phones: [], addresses: [], ...input }),
107
+ });
108
+ }
109
+ export function updateContact(patch, client) {
110
+ return withClient(client, `/mail/contacts/${encodeURIComponent(patch.uid)}`, {
111
+ method: "PUT",
112
+ body: JSON.stringify(patch),
113
+ });
114
+ }
115
+ /** Thin `updateContact()` wrapper for toggling favorite/star status — same pattern as `mailApi.ts`'s
116
+ * `setMessageRead()`/`tasksApi.ts`'s `setTaskCompleted()`. Sends only `uid`/`version`/`favorite`, never
117
+ * the rest of `contact` (the server rejects its managed fields). */
118
+ export function setContactFavorite(contact, favorite, client) {
119
+ return updateContact({ uid: contact.uid, version: contact.version, favorite }, client);
120
+ }
121
+ export function deleteContact(uid, version, client) {
122
+ return withClient(client, `/mail/contacts/${encodeURIComponent(uid)}?version=${version}`, { method: "DELETE" });
123
+ }
124
+ /** Lists a mailbox's contact lists (Outlook-style "Your contact lists"), alphabetically by name. */
125
+ export function listContactLists(mailboxUid, params = {}, client) {
126
+ return withClient(client, `/mail/contact-lists?${buildQuery(params, { mailboxUid, sort: JSON.stringify({ name: "ASC" }) })}`);
127
+ }
128
+ export function createContactList(input, client) {
129
+ return withClient(client, "/mail/contact-lists", { method: "POST", body: JSON.stringify(input) });
130
+ }
131
+ export function updateContactList(input, client) {
132
+ return withClient(client, `/mail/contact-lists/${encodeURIComponent(input.uid)}`, {
133
+ method: "PUT",
134
+ body: JSON.stringify(input),
135
+ });
136
+ }
137
+ export function deleteContactList(uid, version, client) {
138
+ return withClient(client, `/mail/contact-lists/${encodeURIComponent(uid)}?version=${version}`, { method: "DELETE" });
139
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Pure client-side vCard 3.0 generate/parse — `@rapidmx/restapi` has no vCard import/export support of its
3
+ * own, and Outlook's Contacts UI treats this as a purely local file-format concern (a `.vcf` file never
4
+ * touches the server as anything but ordinary `Contact` field values), so there's nothing to add there.
5
+ */
6
+ import type { Contact, ContactInput } from "./contactsApi.js";
7
+ /** Builds a single vCard 3.0 record for one contact. */
8
+ export declare function contactToVCard(contact: Contact): string;
9
+ /** Builds a single `.vcf` file's text content from multiple contacts (one `BEGIN:VCARD`/`END:VCARD` block
10
+ * per contact — the standard way multiple vCards share one file). */
11
+ export declare function contactsToVCardFile(contacts: Contact[]): string;
12
+ /** A parsed vCard's fields, shaped as a partial `ContactInput` missing only the `mailboxUid`/`folderUid`
13
+ * scope (the caller supplies those, since they're not part of the vCard format itself). */
14
+ export type ParsedVCardContact = Omit<ContactInput, "mailboxUid" | "folderUid">;
15
+ /**
16
+ * Parses one or more vCard 2.1/3.0/4.0 records from a `.vcf` file's text content. Deliberately tolerant of
17
+ * fields this app doesn't model (PHOTO, BDAY, etc. — silently ignored) and of the `TYPE=` parameter being
18
+ * absent (defaults to "other") — real-world exported vCards vary a lot in exactly which optional parameters
19
+ * they include. Folded lines (a line break followed by a space or tab) are unfolded first; property group
20
+ * prefixes (`item1.EMAIL`, as Apple Contacts writes) are ignored; `TYPE` values are normalized (see
21
+ * `normalizeType()`); structured values are split on unescaped `;` only.
22
+ */
23
+ export declare function parseVCards(text: string): ParsedVCardContact[];