@rapidmx/web-client 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (906) hide show
  1. package/README.md +415 -381
  2. package/apps/admin/_layout.tsx +2 -2
  3. package/apps/admin/audit-log/index.tsx +4 -4
  4. package/apps/admin/branding/index.tsx +39 -39
  5. package/apps/admin/data-requests/index.tsx +482 -482
  6. package/apps/admin/distribution-lists/[uid].tsx +3 -3
  7. package/apps/admin/distribution-lists/index.tsx +4 -4
  8. package/apps/admin/distribution-lists/new/index.tsx +5 -5
  9. package/apps/admin/domains/[uid].tsx +166 -166
  10. package/apps/admin/domains/index.tsx +4 -4
  11. package/apps/admin/domains/new/index.tsx +5 -5
  12. package/apps/admin/encryption-policy/index.tsx +1 -1
  13. package/apps/admin/escrow-scopes/[uid].tsx +350 -350
  14. package/apps/admin/escrow-scopes/index.tsx +4 -4
  15. package/apps/admin/escrow-scopes/new/index.tsx +5 -5
  16. package/apps/admin/index.tsx +129 -129
  17. package/apps/admin/ingest-queue/index.tsx +4 -4
  18. package/apps/admin/mailbox-policy/index.tsx +1 -1
  19. package/apps/admin/mailboxes/[uid].tsx +271 -271
  20. package/apps/admin/mailboxes/new/index.tsx +30 -30
  21. package/apps/admin/plugins/index.tsx +15 -15
  22. package/apps/admin/quarantine/index.tsx +5 -5
  23. package/apps/admin/retention-policy/index.tsx +39 -39
  24. package/apps/admin/signing-certificates/index.tsx +343 -343
  25. package/apps/admin/transport-rules/[uid].tsx +5 -5
  26. package/apps/admin/transport-rules/_transportRuleConfig.tsx +3 -3
  27. package/apps/admin/transport-rules/index.tsx +4 -4
  28. package/apps/admin/transport-rules/new/index.tsx +5 -5
  29. package/apps/escrow/_layout.tsx +1 -1
  30. package/apps/escrow/audit-log/index.tsx +196 -196
  31. package/apps/escrow/index.tsx +4 -4
  32. package/apps/escrow/matters/[uid].tsx +621 -621
  33. package/apps/escrow/matters/new/index.tsx +6 -6
  34. package/apps/shared/appearance/AppearanceForm.tsx +3 -3
  35. package/apps/shared/appearance/AppearanceHead.tsx +1 -1
  36. package/apps/shared/appearance/AppearanceProvider.tsx +3 -3
  37. package/apps/shared/appearance/appearanceCache.ts +1 -1
  38. package/apps/shared/appearance/appearanceContext.ts +1 -1
  39. package/apps/shared/appearance/theme.ts +1 -1
  40. package/apps/shared/auth/adminAccess.ts +99 -99
  41. package/apps/shared/calendar/bookingPlugin.ts +1 -1
  42. package/apps/shared/calendar/calendarLiveUpdates.ts +1 -1
  43. package/apps/shared/calendar/calendarReminders.ts +1 -1
  44. package/apps/shared/calendar/useCalendarReminders.ts +1 -1
  45. package/apps/shared/components/admin/diagnostics/DiagnosticsManager.tsx +1 -1
  46. package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +2 -2
  47. package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +2 -2
  48. package/apps/shared/components/admin/diagnostics/PackagesTable.tsx +1 -1
  49. package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
  50. package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +2 -2
  51. package/apps/shared/components/admin/diagnostics/VersionsPanel.tsx +1 -1
  52. package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +1 -1
  53. package/apps/shared/components/admin/diagnostics/format.ts +1 -1
  54. package/apps/shared/components/admin/diagnostics/logClient.ts +1 -1
  55. package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
  56. package/apps/shared/components/admin/elevation.ts +1 -1
  57. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +3 -3
  58. package/apps/shared/components/admin/layout/AdminShell.tsx +384 -384
  59. package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +238 -238
  60. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +154 -152
  61. package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +194 -194
  62. package/apps/shared/components/admin/mailboxes/MailboxTable.tsx +1 -1
  63. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +19 -14
  64. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +5 -5
  65. package/apps/shared/components/admin/settings/BrandingForm.tsx +423 -423
  66. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +5 -5
  67. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +119 -119
  68. package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +2 -2
  69. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +32 -27
  70. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +198 -198
  71. package/apps/shared/components/admin/settings/PluginsManager.tsx +2093 -2093
  72. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +182 -182
  73. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +288 -288
  74. package/apps/shared/components/admin/setup/SetupWizard.tsx +450 -446
  75. package/apps/shared/components/admin/signOut.ts +1 -1
  76. package/apps/shared/components/admin/usePagedList.tsx +129 -129
  77. package/apps/shared/components/calendar/AppointmentQuickForm.tsx +3 -3
  78. package/apps/shared/components/calendar/CalendarListSidebar.tsx +3 -3
  79. package/apps/shared/components/calendar/DescriptionEditor.tsx +1 -1
  80. package/apps/shared/components/calendar/EventDescriptionView.tsx +1 -1
  81. package/apps/shared/components/calendar/EventDetails.tsx +16 -14
  82. package/apps/shared/components/calendar/EventEditor.tsx +54 -39
  83. package/apps/shared/components/calendar/EventExpandedForm.tsx +3 -3
  84. package/apps/shared/components/calendar/EventFormParts.tsx +2 -2
  85. package/apps/shared/components/calendar/EventModal.tsx +206 -206
  86. package/apps/shared/components/calendar/EventQuickForm.tsx +3 -3
  87. package/apps/shared/components/calendar/EventShell.tsx +1 -1
  88. package/apps/shared/components/calendar/FindATime.tsx +6 -4
  89. package/apps/shared/components/calendar/GuestInput.tsx +2 -2
  90. package/apps/shared/components/calendar/MonthView.tsx +185 -185
  91. package/apps/shared/components/calendar/QuickCreateFaces.tsx +1 -1
  92. package/apps/shared/components/calendar/QuickFaceFrame.tsx +1 -1
  93. package/apps/shared/components/calendar/RecurrenceEditor.tsx +227 -227
  94. package/apps/shared/components/calendar/RequestChangeForm.tsx +8 -6
  95. package/apps/shared/components/calendar/ResourcePicker.tsx +7 -5
  96. package/apps/shared/components/calendar/SplitDayView.tsx +144 -144
  97. package/apps/shared/components/calendar/TaskQuickForm.tsx +23 -18
  98. package/apps/shared/components/calendar/TimeGridView.tsx +246 -246
  99. package/apps/shared/components/calendar/allDay.ts +124 -124
  100. package/apps/shared/components/calendar/eventDialogFields.ts +3 -3
  101. package/apps/shared/components/calendar/eventForm.ts +3 -3
  102. package/apps/shared/components/calendar/eventFormat.ts +3 -3
  103. package/apps/shared/components/calendar/findTimeGrid.ts +2 -2
  104. package/apps/shared/components/calendar/layout/CalendarShell.tsx +11 -9
  105. package/apps/shared/components/contacts/ContactDetailPane.tsx +4 -4
  106. package/apps/shared/components/contacts/ContactForm.tsx +393 -383
  107. package/apps/shared/components/contacts/ContactsSidebar.tsx +7 -5
  108. package/apps/shared/components/contacts/ContactsToolbar.tsx +103 -103
  109. package/apps/shared/components/contacts/KeyChangeReview.tsx +5 -5
  110. package/apps/shared/components/contacts/contactKeys.ts +3 -3
  111. package/apps/shared/components/contacts/layout/ContactsShell.tsx +9 -7
  112. package/apps/shared/components/escrow/layout/EscrowShell.tsx +155 -155
  113. package/apps/shared/components/forms/StringListField.tsx +1 -1
  114. package/apps/shared/components/layout/AppShell.tsx +465 -461
  115. package/apps/shared/components/layout/BrandingChrome.tsx +1 -1
  116. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +398 -398
  117. package/apps/shared/components/layout/MailboxProvisioning.tsx +170 -168
  118. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +9 -9
  119. package/apps/shared/components/layout/ResponsiveToolbar.tsx +315 -315
  120. package/apps/shared/components/layout/ThemeSwitch.tsx +84 -84
  121. package/apps/shared/components/layout/UnlockPromptProvider.tsx +6 -6
  122. package/apps/shared/components/layout/UserMenu.tsx +441 -439
  123. package/apps/shared/components/mail/ConversationList.tsx +334 -332
  124. package/apps/shared/components/mail/ConversationThreadPane.tsx +624 -613
  125. package/apps/shared/components/mail/InviteCard.tsx +11 -9
  126. package/apps/shared/components/mail/LazyReadingPane.tsx +2 -2
  127. package/apps/shared/components/mail/MailAddress.tsx +1 -1
  128. package/apps/shared/components/mail/MailListToolbar.tsx +2 -2
  129. package/apps/shared/components/mail/MailSelectionBar.tsx +240 -240
  130. package/apps/shared/components/mail/MenuButton.tsx +404 -404
  131. package/apps/shared/components/mail/MessageDetailPane.tsx +1759 -1757
  132. package/apps/shared/components/mail/MoveToFolderDialog.tsx +8 -6
  133. package/apps/shared/components/mail/OutboxRowStatus.tsx +1 -1
  134. package/apps/shared/components/mail/PermanentDeleteDialog.tsx +2 -2
  135. package/apps/shared/components/mail/compose/ComposeContext.tsx +323 -312
  136. package/apps/shared/components/mail/compose/ComposeToolbar.tsx +422 -422
  137. package/apps/shared/components/mail/compose/ComposeWindow.tsx +1709 -1681
  138. package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +4 -4
  139. package/apps/shared/components/mail/compose/EmojiPicker.tsx +2 -2
  140. package/apps/shared/components/mail/compose/GifPicker.tsx +3 -3
  141. package/apps/shared/components/mail/compose/RecipientInput.tsx +1 -1
  142. package/apps/shared/components/mail/compose/RichTextEditor.tsx +147 -147
  143. package/apps/shared/components/mail/compose/ScheduleSendPicker.tsx +1 -1
  144. package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -60
  145. package/apps/shared/components/mail/compose/encryptionRequirement.ts +2 -2
  146. package/apps/shared/components/mail/compose/quotedBody.ts +161 -161
  147. package/apps/shared/components/mail/compose/recipients.ts +1 -1
  148. package/apps/shared/components/mail/invite/InviteRowChip.tsx +2 -2
  149. package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +9 -7
  150. package/apps/shared/components/mail/invite/InviteTimeline.tsx +1 -1
  151. package/apps/shared/components/mail/invite/ProposeTimeForm.tsx +2 -2
  152. package/apps/shared/components/mail/invite/inviteFormat.ts +2 -2
  153. package/apps/shared/components/mail/invite/inviteStore.ts +14 -6
  154. package/apps/shared/components/mail/labelMenu.tsx +9 -7
  155. package/apps/shared/components/mail/layout/MailShell.tsx +4 -4
  156. package/apps/shared/components/mail/listPreferences.ts +2 -2
  157. package/apps/shared/components/mail/pinnedSigners.ts +45 -19
  158. package/apps/shared/components/mail/reading/EncryptedBody.tsx +2 -2
  159. package/apps/shared/components/mail/reading/MessageBody.tsx +6 -6
  160. package/apps/shared/components/mail/reading/MessageCard.tsx +3 -3
  161. package/apps/shared/components/mail/reading/MessageMoreMenu.tsx +258 -258
  162. package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +79 -79
  163. package/apps/shared/components/mail/reading/PendingMessageCard.tsx +1 -1
  164. package/apps/shared/components/mail/reading/bodyContent.ts +3 -3
  165. package/apps/shared/components/mail/reading/bodyHtml.ts +1 -1
  166. package/apps/shared/components/mail/reading/messageExport.ts +59 -59
  167. package/apps/shared/components/mail/reading/printMessage.ts +99 -99
  168. package/apps/shared/components/mail/reading/useMessageActions.ts +450 -443
  169. package/apps/shared/components/mail/unreadStyle.tsx +1 -1
  170. package/apps/shared/components/mail/verificationSeals.ts +129 -125
  171. package/apps/shared/components/mail/writableMailboxes.ts +14 -7
  172. package/apps/shared/components/rules/RuleBuilder.tsx +311 -311
  173. package/apps/shared/components/settings/SigningCertificateCard.tsx +344 -344
  174. package/apps/shared/components/settings/layout/SettingsShell.tsx +8 -6
  175. package/apps/shared/components/sharing/PrincipalListField.tsx +1 -1
  176. package/apps/shared/components/sharing/PrincipalPicker.tsx +1 -1
  177. package/apps/shared/components/sharing/PrincipalResolver.tsx +4 -4
  178. package/apps/shared/components/tasks/TasksSidebar.tsx +7 -5
  179. package/apps/shared/components/tasks/layout/TasksShell.tsx +9 -7
  180. package/apps/shared/keyboard/GlobalShortcuts.tsx +51 -51
  181. package/apps/shared/keyboard/ShortcutProvider.tsx +62 -62
  182. package/apps/shared/keyboard/ShortcutsDialog.tsx +84 -84
  183. package/apps/shared/keyboard/dispatch.ts +124 -124
  184. package/apps/shared/keyboard/format.ts +89 -89
  185. package/apps/shared/keyboard/keymap.ts +114 -114
  186. package/apps/shared/keyboard/registry.ts +65 -65
  187. package/apps/shared/keyboard/targets.ts +79 -79
  188. package/apps/shared/mail/findWellKnownFolderUid.ts +6 -4
  189. package/apps/shared/mail/folderCounts.ts +8 -4
  190. package/apps/shared/mail/folderOfType.ts +51 -49
  191. package/apps/shared/mail/folderTree.ts +143 -143
  192. package/apps/shared/mail/listAllPages.ts +39 -39
  193. package/apps/shared/mail/listSnapshots.ts +2 -2
  194. package/apps/shared/mail/messageReadState.ts +6 -5
  195. package/apps/shared/mail/newMailNotifications.ts +171 -171
  196. package/apps/shared/mail/outbox/composeBridge.ts +2 -2
  197. package/apps/shared/mail/outbox/outboxState.ts +1 -1
  198. package/apps/shared/mail/outbox/outgoingReplies.ts +2 -2
  199. package/apps/shared/mail/outbox/sendDecision.ts +2 -2
  200. package/apps/shared/mail/outbox/sendJob.ts +450 -445
  201. package/apps/shared/mail/outbox/sendOutcomes.ts +160 -155
  202. package/apps/shared/mail/outbox/useOutboxStatus.ts +5 -3
  203. package/apps/shared/mail/permanentDelete.ts +8 -7
  204. package/apps/shared/mail/primaryMailbox.ts +1 -1
  205. package/apps/shared/mail/reportNotices.ts +66 -66
  206. package/apps/shared/mail/senderBlocking.ts +157 -141
  207. package/apps/shared/mail/useMailConnection.ts +207 -205
  208. package/apps/shared/mail/useMailLiveUpdates.ts +277 -277
  209. package/apps/shared/mail/useMailboxUpdateAccess.ts +84 -60
  210. package/apps/shared/mail/useMarkMessageRead.ts +54 -47
  211. package/apps/shared/mail/useNewMailNotifications.ts +178 -178
  212. package/apps/shared/mail/usePermanentDelete.tsx +5 -3
  213. package/apps/shared/navigation/pageTitle.ts +1 -1
  214. package/apps/shared/notifications/NotificationCenter.tsx +1 -1
  215. package/apps/shared/notifications/NotificationHistoryDialog.tsx +2 -2
  216. package/apps/shared/notifications/apiErrors.ts +2 -2
  217. package/apps/shared/notifications/pushStatus.ts +1 -1
  218. package/apps/shared/notifications/store.ts +560 -560
  219. package/apps/shared/notifications/systemErrors.ts +1 -1
  220. package/apps/shared/search/LocalIndexLifecycle.tsx +120 -114
  221. package/apps/shared/search/crossMailboxSearch.ts +3 -3
  222. package/apps/shared/search/localIndexBuilder.ts +493 -481
  223. package/apps/shared/search/localIndexKey.ts +1 -1
  224. package/apps/shared/search/localIndexRpcClient.ts +150 -30
  225. package/apps/shared/search/localIndexTransport.ts +84 -0
  226. package/apps/shared/search/localIndexWorker.ts +1 -1
  227. package/apps/shared/search/searchTier2.ts +3 -3
  228. package/apps/shared/signing/enrollmentStorage.ts +33 -33
  229. package/apps/shared/signing/enrollmentTracker.ts +385 -385
  230. package/apps/shared/signing/enrollmentView.ts +251 -251
  231. package/apps/shared/signing/signingInfo.ts +1 -1
  232. package/apps/shared/signing/useNow.ts +19 -19
  233. package/apps/shared/signing/useSigningEnrollmentWatcher.ts +92 -90
  234. package/apps/shared/styles/app.css +387 -396
  235. package/apps/www/_layout.tsx +2 -2
  236. package/apps/www/calendar/index.tsx +583 -581
  237. package/apps/www/contacts/[uid].tsx +114 -112
  238. package/apps/www/contacts/index.tsx +19 -17
  239. package/apps/www/index.tsx +3021 -3012
  240. package/apps/www/messages/[uid].tsx +141 -139
  241. package/apps/www/settings/auto-reply/index.tsx +138 -136
  242. package/apps/www/settings/blocked-senders/index.tsx +305 -303
  243. package/apps/www/settings/encryption/index.tsx +1296 -1290
  244. package/apps/www/settings/filters/[uid].tsx +184 -179
  245. package/apps/www/settings/filters/_mailFilterRuleConfig.tsx +2 -2
  246. package/apps/www/settings/filters/index.tsx +105 -105
  247. package/apps/www/settings/filters/new/index.tsx +167 -165
  248. package/apps/www/settings/labels/index.tsx +209 -207
  249. package/apps/www/settings/privacy/index.tsx +499 -495
  250. package/apps/www/settings/profile/index.tsx +256 -251
  251. package/apps/www/settings/read-receipts/index.tsx +155 -150
  252. package/apps/www/settings/sharing/index.tsx +259 -259
  253. package/apps/www/settings/signatures/[uid].tsx +175 -175
  254. package/apps/www/settings/signatures/index.tsx +91 -91
  255. package/apps/www/settings/signatures/new/index.tsx +138 -138
  256. package/apps/www/settings/signatures/signatureDefaults.ts +1 -1
  257. package/apps/www/tasks/index.tsx +659 -654
  258. package/dist/apps/admin/_layout.d.ts +1 -1
  259. package/dist/apps/admin/_layout.js +1 -1
  260. package/dist/apps/admin/audit-log/index.d.ts +1 -1
  261. package/dist/apps/admin/audit-log/index.js +4 -4
  262. package/dist/apps/admin/branding/index.js +3 -3
  263. package/dist/apps/admin/data-requests/index.js +8 -8
  264. package/dist/apps/admin/distribution-lists/[uid].js +3 -3
  265. package/dist/apps/admin/distribution-lists/index.js +4 -4
  266. package/dist/apps/admin/distribution-lists/new/index.js +5 -5
  267. package/dist/apps/admin/domains/[uid].js +6 -6
  268. package/dist/apps/admin/domains/index.js +4 -4
  269. package/dist/apps/admin/domains/new/index.js +5 -5
  270. package/dist/apps/admin/encryption-policy/index.js +1 -1
  271. package/dist/apps/admin/escrow-scopes/[uid].d.ts +1 -1
  272. package/dist/apps/admin/escrow-scopes/[uid].js +7 -7
  273. package/dist/apps/admin/escrow-scopes/index.js +4 -4
  274. package/dist/apps/admin/escrow-scopes/new/index.js +5 -5
  275. package/dist/apps/admin/index.js +6 -6
  276. package/dist/apps/admin/ingest-queue/index.js +4 -4
  277. package/dist/apps/admin/mailbox-policy/index.js +1 -1
  278. package/dist/apps/admin/mailboxes/[uid].js +5 -5
  279. package/dist/apps/admin/quarantine/index.js +5 -5
  280. package/dist/apps/admin/retention-policy/index.js +3 -3
  281. package/dist/apps/admin/signing-certificates/index.js +5 -5
  282. package/dist/apps/admin/transport-rules/[uid].js +5 -5
  283. package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +1 -1
  284. package/dist/apps/admin/transport-rules/_transportRuleConfig.js +2 -2
  285. package/dist/apps/admin/transport-rules/index.js +4 -4
  286. package/dist/apps/admin/transport-rules/new/index.js +5 -5
  287. package/dist/apps/escrow/_layout.d.ts +1 -1
  288. package/dist/apps/escrow/audit-log/index.d.ts +1 -1
  289. package/dist/apps/escrow/audit-log/index.js +4 -4
  290. package/dist/apps/escrow/index.js +4 -4
  291. package/dist/apps/escrow/matters/[uid].js +10 -10
  292. package/dist/apps/escrow/matters/new/index.js +6 -6
  293. package/dist/apps/shared/appearance/AppearanceForm.js +3 -3
  294. package/dist/apps/shared/appearance/AppearanceHead.js +1 -1
  295. package/dist/apps/shared/appearance/AppearanceProvider.d.ts +1 -1
  296. package/dist/apps/shared/appearance/AppearanceProvider.js +3 -3
  297. package/dist/apps/shared/appearance/appearanceCache.d.ts +1 -1
  298. package/dist/apps/shared/appearance/appearanceCache.js +1 -1
  299. package/dist/apps/shared/appearance/appearanceContext.d.ts +1 -1
  300. package/dist/apps/shared/appearance/theme.d.ts +1 -1
  301. package/dist/apps/shared/auth/adminAccess.js +1 -1
  302. package/dist/apps/shared/calendar/bookingPlugin.js +1 -1
  303. package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +1 -1
  304. package/dist/apps/shared/calendar/calendarReminders.d.ts +1 -1
  305. package/dist/apps/shared/calendar/useCalendarReminders.js +1 -1
  306. package/dist/apps/shared/components/admin/diagnostics/DiagnosticsManager.js +1 -1
  307. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.d.ts +1 -1
  308. package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +2 -2
  309. package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +2 -2
  310. package/dist/apps/shared/components/admin/diagnostics/PackagesTable.js +1 -1
  311. package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
  312. package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +2 -2
  313. package/dist/apps/shared/components/admin/diagnostics/VersionsPanel.js +1 -1
  314. package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.js +1 -1
  315. package/dist/apps/shared/components/admin/diagnostics/format.js +1 -1
  316. package/dist/apps/shared/components/admin/diagnostics/logClient.js +1 -1
  317. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +1 -1
  318. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
  319. package/dist/apps/shared/components/admin/elevation.js +1 -1
  320. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +3 -3
  321. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
  322. package/dist/apps/shared/components/admin/layout/AdminShell.js +8 -8
  323. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.d.ts +1 -1
  324. package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +6 -6
  325. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +1 -1
  326. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +10 -8
  327. package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
  328. package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +1 -1
  329. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +1 -1
  330. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +7 -5
  331. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +5 -5
  332. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +1 -1
  333. package/dist/apps/shared/components/admin/settings/BrandingForm.js +8 -8
  334. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +1 -1
  335. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +5 -5
  336. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +1 -1
  337. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +4 -4
  338. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +2 -2
  339. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +1 -1
  340. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +14 -12
  341. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +1 -1
  342. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +4 -4
  343. package/dist/apps/shared/components/admin/settings/PluginsManager.js +5 -5
  344. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +1 -1
  345. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +5 -5
  346. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +7 -7
  347. package/dist/apps/shared/components/admin/setup/SetupWizard.js +26 -22
  348. package/dist/apps/shared/components/admin/signOut.js +1 -1
  349. package/dist/apps/shared/components/admin/usePagedList.js +2 -2
  350. package/dist/apps/shared/components/calendar/AppointmentQuickForm.js +3 -3
  351. package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +1 -1
  352. package/dist/apps/shared/components/calendar/CalendarListSidebar.js +2 -2
  353. package/dist/apps/shared/components/calendar/DescriptionEditor.js +1 -1
  354. package/dist/apps/shared/components/calendar/EventDescriptionView.js +1 -1
  355. package/dist/apps/shared/components/calendar/EventDetails.d.ts +2 -2
  356. package/dist/apps/shared/components/calendar/EventDetails.js +16 -14
  357. package/dist/apps/shared/components/calendar/EventEditor.d.ts +2 -2
  358. package/dist/apps/shared/components/calendar/EventEditor.js +22 -20
  359. package/dist/apps/shared/components/calendar/EventExpandedForm.js +2 -2
  360. package/dist/apps/shared/components/calendar/EventFormParts.d.ts +1 -1
  361. package/dist/apps/shared/components/calendar/EventFormParts.js +1 -1
  362. package/dist/apps/shared/components/calendar/EventModal.d.ts +2 -2
  363. package/dist/apps/shared/components/calendar/EventModal.js +3 -3
  364. package/dist/apps/shared/components/calendar/EventQuickForm.js +3 -3
  365. package/dist/apps/shared/components/calendar/EventShell.js +1 -1
  366. package/dist/apps/shared/components/calendar/FindATime.js +6 -4
  367. package/dist/apps/shared/components/calendar/GuestInput.d.ts +2 -2
  368. package/dist/apps/shared/components/calendar/MonthView.d.ts +1 -1
  369. package/dist/apps/shared/components/calendar/MonthView.js +1 -1
  370. package/dist/apps/shared/components/calendar/QuickCreateFaces.js +1 -1
  371. package/dist/apps/shared/components/calendar/QuickFaceFrame.js +1 -1
  372. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +1 -1
  373. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +1 -1
  374. package/dist/apps/shared/components/calendar/RequestChangeForm.js +8 -6
  375. package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +1 -1
  376. package/dist/apps/shared/components/calendar/ResourcePicker.js +7 -5
  377. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +1 -1
  378. package/dist/apps/shared/components/calendar/TaskQuickForm.d.ts +1 -1
  379. package/dist/apps/shared/components/calendar/TaskQuickForm.js +9 -7
  380. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +1 -1
  381. package/dist/apps/shared/components/calendar/TimeGridView.js +1 -1
  382. package/dist/apps/shared/components/calendar/allDay.d.ts +2 -2
  383. package/dist/apps/shared/components/calendar/allDay.js +1 -1
  384. package/dist/apps/shared/components/calendar/eventDialogFields.d.ts +2 -2
  385. package/dist/apps/shared/components/calendar/eventDialogFields.js +2 -2
  386. package/dist/apps/shared/components/calendar/eventForm.d.ts +3 -3
  387. package/dist/apps/shared/components/calendar/eventFormat.d.ts +1 -1
  388. package/dist/apps/shared/components/calendar/eventFormat.js +2 -2
  389. package/dist/apps/shared/components/calendar/findTimeGrid.d.ts +1 -1
  390. package/dist/apps/shared/components/calendar/findTimeGrid.js +1 -1
  391. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
  392. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +11 -9
  393. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +1 -1
  394. package/dist/apps/shared/components/contacts/ContactDetailPane.js +2 -2
  395. package/dist/apps/shared/components/contacts/ContactForm.d.ts +2 -2
  396. package/dist/apps/shared/components/contacts/ContactForm.js +12 -8
  397. package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +1 -1
  398. package/dist/apps/shared/components/contacts/ContactsSidebar.js +7 -5
  399. package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +1 -1
  400. package/dist/apps/shared/components/contacts/KeyChangeReview.js +5 -5
  401. package/dist/apps/shared/components/contacts/contactKeys.d.ts +2 -2
  402. package/dist/apps/shared/components/contacts/contactKeys.js +2 -2
  403. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
  404. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +9 -7
  405. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +7 -7
  406. package/dist/apps/shared/components/forms/StringListField.js +1 -1
  407. package/dist/apps/shared/components/layout/AppShell.d.ts +2 -2
  408. package/dist/apps/shared/components/layout/AppShell.js +14 -10
  409. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +1 -1
  410. package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +1 -1
  411. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +9 -9
  412. package/dist/apps/shared/components/layout/MailboxProvisioning.js +8 -6
  413. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +1 -1
  414. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +9 -9
  415. package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +2 -2
  416. package/dist/apps/shared/components/layout/UnlockPromptProvider.js +5 -5
  417. package/dist/apps/shared/components/layout/UserMenu.js +6 -4
  418. package/dist/apps/shared/components/mail/ConversationList.d.ts +2 -2
  419. package/dist/apps/shared/components/mail/ConversationList.js +6 -4
  420. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +3 -3
  421. package/dist/apps/shared/components/mail/ConversationThreadPane.js +13 -11
  422. package/dist/apps/shared/components/mail/InviteCard.js +10 -8
  423. package/dist/apps/shared/components/mail/LazyReadingPane.js +2 -2
  424. package/dist/apps/shared/components/mail/MailAddress.d.ts +1 -1
  425. package/dist/apps/shared/components/mail/MailAddress.js +1 -1
  426. package/dist/apps/shared/components/mail/MailListToolbar.d.ts +2 -2
  427. package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +2 -2
  428. package/dist/apps/shared/components/mail/MenuButton.js +1 -1
  429. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +3 -3
  430. package/dist/apps/shared/components/mail/MessageDetailPane.js +30 -28
  431. package/dist/apps/shared/components/mail/MoveToFolderDialog.d.ts +1 -1
  432. package/dist/apps/shared/components/mail/MoveToFolderDialog.js +8 -6
  433. package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +1 -1
  434. package/dist/apps/shared/components/mail/PermanentDeleteDialog.js +2 -2
  435. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +10 -1
  436. package/dist/apps/shared/components/mail/compose/ComposeContext.js +4 -2
  437. package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +7 -1
  438. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +54 -31
  439. package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +4 -4
  440. package/dist/apps/shared/components/mail/compose/EmojiPicker.js +2 -2
  441. package/dist/apps/shared/components/mail/compose/GifPicker.js +3 -3
  442. package/dist/apps/shared/components/mail/compose/RecipientInput.d.ts +1 -1
  443. package/dist/apps/shared/components/mail/compose/RecipientInput.js +1 -1
  444. package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.js +1 -1
  445. package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +2 -2
  446. package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +1 -1
  447. package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +3 -3
  448. package/dist/apps/shared/components/mail/compose/quotedBody.js +3 -3
  449. package/dist/apps/shared/components/mail/compose/recipients.d.ts +1 -1
  450. package/dist/apps/shared/components/mail/invite/InviteRowChip.d.ts +1 -1
  451. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +1 -1
  452. package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +9 -7
  453. package/dist/apps/shared/components/mail/invite/InviteTimeline.d.ts +1 -1
  454. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.d.ts +1 -1
  455. package/dist/apps/shared/components/mail/invite/ProposeTimeForm.js +1 -1
  456. package/dist/apps/shared/components/mail/invite/inviteFormat.d.ts +2 -2
  457. package/dist/apps/shared/components/mail/invite/inviteStore.d.ts +9 -3
  458. package/dist/apps/shared/components/mail/invite/inviteStore.js +13 -6
  459. package/dist/apps/shared/components/mail/labelMenu.d.ts +1 -1
  460. package/dist/apps/shared/components/mail/labelMenu.js +9 -7
  461. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +1 -1
  462. package/dist/apps/shared/components/mail/layout/MailShell.js +3 -3
  463. package/dist/apps/shared/components/mail/listPreferences.d.ts +2 -2
  464. package/dist/apps/shared/components/mail/listPreferences.js +1 -1
  465. package/dist/apps/shared/components/mail/pinnedSigners.d.ts +12 -5
  466. package/dist/apps/shared/components/mail/pinnedSigners.js +37 -18
  467. package/dist/apps/shared/components/mail/reading/EncryptedBody.js +2 -2
  468. package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +2 -2
  469. package/dist/apps/shared/components/mail/reading/MessageBody.js +4 -4
  470. package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +1 -1
  471. package/dist/apps/shared/components/mail/reading/MessageCard.js +2 -2
  472. package/dist/apps/shared/components/mail/reading/MessageSourceDialog.js +3 -3
  473. package/dist/apps/shared/components/mail/reading/PendingMessageCard.js +1 -1
  474. package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +2 -2
  475. package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -2
  476. package/dist/apps/shared/components/mail/reading/bodyHtml.js +1 -1
  477. package/dist/apps/shared/components/mail/reading/messageExport.js +1 -1
  478. package/dist/apps/shared/components/mail/reading/printMessage.d.ts +2 -2
  479. package/dist/apps/shared/components/mail/reading/printMessage.js +11 -11
  480. package/dist/apps/shared/components/mail/reading/useMessageActions.d.ts +1 -1
  481. package/dist/apps/shared/components/mail/reading/useMessageActions.js +18 -16
  482. package/dist/apps/shared/components/mail/unreadStyle.d.ts +1 -1
  483. package/dist/apps/shared/components/mail/verificationSeals.d.ts +27 -6
  484. package/dist/apps/shared/components/mail/verificationSeals.js +15 -11
  485. package/dist/apps/shared/components/mail/writableMailboxes.d.ts +8 -3
  486. package/dist/apps/shared/components/mail/writableMailboxes.js +12 -6
  487. package/dist/apps/shared/components/rules/RuleBuilder.js +1 -1
  488. package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +1 -1
  489. package/dist/apps/shared/components/settings/SigningCertificateCard.js +3 -3
  490. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
  491. package/dist/apps/shared/components/settings/layout/SettingsShell.js +8 -6
  492. package/dist/apps/shared/components/sharing/PrincipalListField.d.ts +1 -1
  493. package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +1 -1
  494. package/dist/apps/shared/components/sharing/PrincipalPicker.js +1 -1
  495. package/dist/apps/shared/components/sharing/PrincipalResolver.d.ts +1 -1
  496. package/dist/apps/shared/components/sharing/PrincipalResolver.js +3 -3
  497. package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +1 -1
  498. package/dist/apps/shared/components/tasks/TasksSidebar.js +7 -5
  499. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
  500. package/dist/apps/shared/components/tasks/layout/TasksShell.js +9 -7
  501. package/dist/apps/shared/keyboard/ShortcutsDialog.js +1 -1
  502. package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -3
  503. package/dist/apps/shared/mail/findWellKnownFolderUid.js +5 -4
  504. package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
  505. package/dist/apps/shared/mail/folderCounts.js +6 -4
  506. package/dist/apps/shared/mail/folderOfType.d.ts +3 -2
  507. package/dist/apps/shared/mail/folderOfType.js +4 -4
  508. package/dist/apps/shared/mail/folderTree.d.ts +1 -1
  509. package/dist/apps/shared/mail/listSnapshots.d.ts +2 -2
  510. package/dist/apps/shared/mail/messageReadState.d.ts +4 -3
  511. package/dist/apps/shared/mail/messageReadState.js +5 -5
  512. package/dist/apps/shared/mail/newMailNotifications.d.ts +1 -1
  513. package/dist/apps/shared/mail/newMailNotifications.js +1 -1
  514. package/dist/apps/shared/mail/outbox/composeBridge.d.ts +2 -2
  515. package/dist/apps/shared/mail/outbox/outboxState.d.ts +1 -1
  516. package/dist/apps/shared/mail/outbox/outgoingReplies.d.ts +2 -2
  517. package/dist/apps/shared/mail/outbox/sendDecision.d.ts +2 -2
  518. package/dist/apps/shared/mail/outbox/sendDecision.js +1 -1
  519. package/dist/apps/shared/mail/outbox/sendJob.d.ts +10 -6
  520. package/dist/apps/shared/mail/outbox/sendJob.js +39 -35
  521. package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +6 -3
  522. package/dist/apps/shared/mail/outbox/sendOutcomes.js +19 -15
  523. package/dist/apps/shared/mail/outbox/useOutboxStatus.js +5 -3
  524. package/dist/apps/shared/mail/permanentDelete.d.ts +4 -3
  525. package/dist/apps/shared/mail/permanentDelete.js +8 -8
  526. package/dist/apps/shared/mail/primaryMailbox.d.ts +1 -1
  527. package/dist/apps/shared/mail/primaryMailbox.js +1 -1
  528. package/dist/apps/shared/mail/reportNotices.d.ts +1 -1
  529. package/dist/apps/shared/mail/senderBlocking.d.ts +5 -4
  530. package/dist/apps/shared/mail/senderBlocking.js +19 -16
  531. package/dist/apps/shared/mail/useMailConnection.d.ts +1 -1
  532. package/dist/apps/shared/mail/useMailConnection.js +12 -10
  533. package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +2 -2
  534. package/dist/apps/shared/mail/useMailLiveUpdates.js +2 -2
  535. package/dist/apps/shared/mail/useMailboxUpdateAccess.d.ts +3 -2
  536. package/dist/apps/shared/mail/useMailboxUpdateAccess.js +31 -10
  537. package/dist/apps/shared/mail/useMarkMessageRead.d.ts +1 -1
  538. package/dist/apps/shared/mail/useMarkMessageRead.js +5 -3
  539. package/dist/apps/shared/mail/useNewMailNotifications.d.ts +1 -1
  540. package/dist/apps/shared/mail/usePermanentDelete.d.ts +1 -1
  541. package/dist/apps/shared/mail/usePermanentDelete.js +4 -2
  542. package/dist/apps/shared/navigation/pageTitle.d.ts +1 -1
  543. package/dist/apps/shared/notifications/NotificationCenter.js +1 -1
  544. package/dist/apps/shared/notifications/NotificationHistoryDialog.js +2 -2
  545. package/dist/apps/shared/notifications/apiErrors.js +2 -2
  546. package/dist/apps/shared/notifications/pushStatus.js +1 -1
  547. package/dist/apps/shared/notifications/systemErrors.js +1 -1
  548. package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +2 -2
  549. package/dist/apps/shared/search/LocalIndexLifecycle.js +15 -10
  550. package/dist/apps/shared/search/crossMailboxSearch.d.ts +1 -1
  551. package/dist/apps/shared/search/crossMailboxSearch.js +2 -2
  552. package/dist/apps/shared/search/localIndexBuilder.d.ts +4 -3
  553. package/dist/apps/shared/search/localIndexBuilder.js +15 -12
  554. package/dist/apps/shared/search/localIndexKey.js +1 -1
  555. package/dist/apps/shared/search/localIndexRpcClient.d.ts +43 -31
  556. package/dist/apps/shared/search/localIndexRpcClient.js +113 -20
  557. package/dist/apps/shared/search/localIndexTransport.d.ts +77 -0
  558. package/dist/apps/shared/search/localIndexTransport.js +1 -0
  559. package/dist/apps/shared/search/localIndexWorker.d.ts +1 -1
  560. package/dist/apps/shared/search/searchTier2.d.ts +3 -3
  561. package/dist/apps/shared/signing/enrollmentTracker.d.ts +1 -1
  562. package/dist/apps/shared/signing/enrollmentTracker.js +3 -3
  563. package/dist/apps/shared/signing/enrollmentView.d.ts +1 -1
  564. package/dist/apps/shared/signing/signingInfo.d.ts +1 -1
  565. package/dist/apps/shared/signing/signingInfo.js +1 -1
  566. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +1 -1
  567. package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +5 -3
  568. package/dist/apps/shared/styles/app.css +387 -396
  569. package/dist/apps/www/_layout.d.ts +1 -1
  570. package/dist/apps/www/_layout.js +1 -1
  571. package/dist/apps/www/calendar/index.d.ts +1 -1
  572. package/dist/apps/www/calendar/index.js +20 -18
  573. package/dist/apps/www/contacts/[uid].d.ts +1 -1
  574. package/dist/apps/www/contacts/[uid].js +8 -6
  575. package/dist/apps/www/contacts/index.d.ts +1 -1
  576. package/dist/apps/www/contacts/index.js +19 -17
  577. package/dist/apps/www/index.d.ts +1 -1
  578. package/dist/apps/www/index.js +54 -50
  579. package/dist/apps/www/messages/[uid].d.ts +1 -1
  580. package/dist/apps/www/messages/[uid].js +11 -9
  581. package/dist/apps/www/settings/appearance/index.d.ts +1 -1
  582. package/dist/apps/www/settings/auto-reply/index.d.ts +1 -1
  583. package/dist/apps/www/settings/auto-reply/index.js +6 -4
  584. package/dist/apps/www/settings/blocked-senders/index.d.ts +1 -1
  585. package/dist/apps/www/settings/blocked-senders/index.js +6 -4
  586. package/dist/apps/www/settings/encryption/index.d.ts +1 -1
  587. package/dist/apps/www/settings/encryption/index.js +31 -29
  588. package/dist/apps/www/settings/filters/[uid].d.ts +1 -1
  589. package/dist/apps/www/settings/filters/[uid].js +11 -9
  590. package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +2 -2
  591. package/dist/apps/www/settings/filters/index.d.ts +1 -1
  592. package/dist/apps/www/settings/filters/index.js +4 -4
  593. package/dist/apps/www/settings/filters/new/index.d.ts +1 -1
  594. package/dist/apps/www/settings/filters/new/index.js +10 -8
  595. package/dist/apps/www/settings/labels/index.d.ts +1 -1
  596. package/dist/apps/www/settings/labels/index.js +12 -10
  597. package/dist/apps/www/settings/privacy/index.d.ts +1 -1
  598. package/dist/apps/www/settings/privacy/index.js +18 -14
  599. package/dist/apps/www/settings/profile/index.d.ts +1 -1
  600. package/dist/apps/www/settings/profile/index.js +7 -5
  601. package/dist/apps/www/settings/read-receipts/index.d.ts +1 -1
  602. package/dist/apps/www/settings/read-receipts/index.js +5 -3
  603. package/dist/apps/www/settings/sharing/index.d.ts +1 -1
  604. package/dist/apps/www/settings/sharing/index.js +6 -6
  605. package/dist/apps/www/settings/signatures/[uid].d.ts +1 -1
  606. package/dist/apps/www/settings/signatures/[uid].js +5 -5
  607. package/dist/apps/www/settings/signatures/index.d.ts +1 -1
  608. package/dist/apps/www/settings/signatures/index.js +4 -4
  609. package/dist/apps/www/settings/signatures/new/index.d.ts +1 -1
  610. package/dist/apps/www/settings/signatures/new/index.js +4 -4
  611. package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +1 -1
  612. package/dist/apps/www/settings/signatures/signatureDefaults.js +1 -1
  613. package/dist/apps/www/tasks/index.d.ts +1 -1
  614. package/dist/apps/www/tasks/index.js +17 -15
  615. package/dist/lib/admin/auditLogApi.d.ts +32 -0
  616. package/dist/lib/admin/auditLogApi.js +27 -0
  617. package/dist/lib/admin/distributionListsApi.d.ts +47 -0
  618. package/dist/lib/admin/distributionListsApi.js +34 -0
  619. package/dist/lib/admin/domainsApi.d.ts +75 -0
  620. package/dist/lib/admin/domainsApi.js +44 -0
  621. package/dist/lib/admin/escrowAccessRequestsApi.d.ts +79 -0
  622. package/dist/lib/admin/escrowAccessRequestsApi.js +46 -0
  623. package/dist/lib/admin/escrowAuditLogApi.d.ts +66 -0
  624. package/dist/lib/admin/escrowAuditLogApi.js +31 -0
  625. package/dist/lib/admin/escrowScopesApi.d.ts +78 -0
  626. package/dist/lib/admin/escrowScopesApi.js +50 -0
  627. package/dist/lib/admin/leftoverMailboxApi.d.ts +73 -0
  628. package/dist/lib/admin/leftoverMailboxApi.js +67 -0
  629. package/dist/lib/admin/mailboxPolicyApi.d.ts +27 -0
  630. package/dist/lib/admin/mailboxPolicyApi.js +21 -0
  631. package/dist/lib/admin/matterExportApi.d.ts +40 -0
  632. package/dist/lib/admin/matterExportApi.js +39 -0
  633. package/dist/lib/admin/matterSearchApi.d.ts +20 -0
  634. package/dist/lib/admin/matterSearchApi.js +27 -0
  635. package/dist/lib/admin/mattersApi.d.ts +56 -0
  636. package/dist/lib/admin/mattersApi.js +40 -0
  637. package/dist/lib/admin/pluginsApi.d.ts +265 -0
  638. package/dist/lib/admin/pluginsApi.js +102 -0
  639. package/dist/lib/admin/retentionPolicyApi.d.ts +32 -0
  640. package/dist/lib/admin/retentionPolicyApi.js +29 -0
  641. package/dist/lib/admin/setupApi.d.ts +23 -0
  642. package/dist/lib/admin/setupApi.js +26 -0
  643. package/dist/lib/admin/transportRulesApi.d.ts +66 -0
  644. package/dist/lib/admin/transportRulesApi.js +43 -0
  645. package/dist/lib/appearance/preferencesApi.d.ts +128 -0
  646. package/dist/lib/appearance/preferencesApi.js +257 -0
  647. package/dist/lib/auth/profileApi.d.ts +33 -0
  648. package/dist/lib/auth/profileApi.js +52 -0
  649. package/dist/lib/auth/session.d.ts +70 -0
  650. package/dist/lib/auth/session.js +210 -0
  651. package/dist/lib/branding/brandingApi.d.ts +47 -0
  652. package/dist/lib/branding/brandingApi.js +61 -0
  653. package/dist/lib/branding/useBranding.d.ts +23 -0
  654. package/dist/lib/branding/useBranding.js +65 -0
  655. package/dist/lib/calendar/calendarApi.d.ts +230 -0
  656. package/dist/lib/calendar/calendarApi.js +106 -0
  657. package/dist/lib/calendar/calendarColors.d.ts +18 -0
  658. package/dist/lib/calendar/calendarColors.js +39 -0
  659. package/dist/lib/calendar/calendarDragIds.d.ts +42 -0
  660. package/dist/lib/calendar/calendarDragIds.js +92 -0
  661. package/dist/lib/calendar/calendarMutations.d.ts +68 -0
  662. package/dist/lib/calendar/calendarMutations.js +190 -0
  663. package/dist/lib/calendar/eventDescription.d.ts +43 -0
  664. package/dist/lib/calendar/eventDescription.js +195 -0
  665. package/dist/lib/calendar/freeBusyApi.d.ts +100 -0
  666. package/dist/lib/calendar/freeBusyApi.js +119 -0
  667. package/dist/lib/calendar/inviteApi.d.ts +121 -0
  668. package/dist/lib/calendar/inviteApi.js +54 -0
  669. package/dist/lib/calendar/recurrence.d.ts +60 -0
  670. package/dist/lib/calendar/recurrence.js +225 -0
  671. package/dist/lib/components/avatar/ContactAvatar.d.ts +8 -0
  672. package/dist/lib/components/avatar/ContactAvatar.js +26 -0
  673. package/dist/lib/components/buttons/Button.d.ts +9 -0
  674. package/dist/lib/components/buttons/Button.js +14 -0
  675. package/dist/lib/components/buttons/CopyButton.d.ts +18 -0
  676. package/dist/lib/components/buttons/CopyButton.js +14 -0
  677. package/dist/lib/components/feedback/Alert.d.ts +4 -0
  678. package/dist/lib/components/feedback/Alert.js +4 -0
  679. package/dist/lib/components/feedback/Skeleton.d.ts +21 -0
  680. package/dist/lib/components/feedback/Skeleton.js +14 -0
  681. package/dist/lib/components/forms/FormField.d.ts +8 -0
  682. package/dist/lib/components/forms/FormField.js +5 -0
  683. package/dist/lib/components/navigation/BottomTabBar.d.ts +27 -0
  684. package/dist/lib/components/navigation/BottomTabBar.js +32 -0
  685. package/dist/lib/components/overlays/Drawer.d.ts +20 -0
  686. package/dist/lib/components/overlays/Drawer.js +27 -0
  687. package/dist/lib/components/overlays/Modal.d.ts +17 -0
  688. package/dist/lib/components/overlays/Modal.js +25 -0
  689. package/dist/lib/components/overlays/PopoverPortal.d.ts +23 -0
  690. package/dist/lib/components/overlays/PopoverPortal.js +53 -0
  691. package/dist/lib/components/overlays/overlayStack.d.ts +31 -0
  692. package/dist/lib/components/overlays/overlayStack.js +143 -0
  693. package/dist/lib/components/pickers/MiniDatePicker.d.ts +13 -0
  694. package/dist/lib/components/pickers/MiniDatePicker.js +42 -0
  695. package/dist/lib/contacts/contactsApi.d.ts +174 -0
  696. package/dist/lib/contacts/contactsApi.js +139 -0
  697. package/dist/lib/contacts/vcard.d.ts +23 -0
  698. package/dist/lib/contacts/vcard.js +179 -0
  699. package/dist/lib/crypto/composeSecurity.d.ts +67 -0
  700. package/dist/lib/crypto/composeSecurity.js +93 -0
  701. package/dist/lib/crypto/encoding.d.ts +9 -0
  702. package/dist/lib/crypto/encoding.js +32 -0
  703. package/dist/lib/crypto/escrowKeys.d.ts +25 -0
  704. package/dist/lib/crypto/escrowKeys.js +59 -0
  705. package/dist/lib/crypto/idleTimeout.d.ts +16 -0
  706. package/dist/lib/crypto/idleTimeout.js +47 -0
  707. package/dist/lib/crypto/keySession.d.ts +159 -0
  708. package/dist/lib/crypto/keySession.js +367 -0
  709. package/dist/lib/crypto/keys.d.ts +50 -0
  710. package/dist/lib/crypto/keys.js +89 -0
  711. package/dist/lib/crypto/keyvaultApi.d.ts +394 -0
  712. package/dist/lib/crypto/keyvaultApi.js +350 -0
  713. package/dist/lib/crypto/masterKey.d.ts +59 -0
  714. package/dist/lib/crypto/masterKey.js +104 -0
  715. package/dist/lib/crypto/masterKeyWraps.d.ts +108 -0
  716. package/dist/lib/crypto/masterKeyWraps.js +228 -0
  717. package/dist/lib/crypto/messageSecurity.d.ts +248 -0
  718. package/dist/lib/crypto/messageSecurity.js +367 -0
  719. package/dist/lib/crypto/mime.d.ts +143 -0
  720. package/dist/lib/crypto/mime.js +504 -0
  721. package/dist/lib/crypto/passkeyUnlock.d.ts +20 -0
  722. package/dist/lib/crypto/passkeyUnlock.js +79 -0
  723. package/dist/lib/crypto/passwordUnlock.d.ts +39 -0
  724. package/dist/lib/crypto/passwordUnlock.js +73 -0
  725. package/dist/lib/crypto/recoveryCode.d.ts +28 -0
  726. package/dist/lib/crypto/recoveryCode.js +86 -0
  727. package/dist/lib/crypto/signingProviderApi.d.ts +95 -0
  728. package/dist/lib/crypto/signingProviderApi.js +60 -0
  729. package/dist/lib/crypto/smime.d.ts +128 -0
  730. package/dist/lib/crypto/smime.js +402 -0
  731. package/dist/lib/crypto/smimeMessage.d.ts +132 -0
  732. package/dist/lib/crypto/smimeMessage.js +341 -0
  733. package/dist/lib/crypto/useIdleKeyTimeout.d.ts +10 -0
  734. package/dist/lib/crypto/useIdleKeyTimeout.js +163 -0
  735. package/dist/lib/crypto/verificationSeal.d.ts +56 -0
  736. package/dist/lib/crypto/verificationSeal.js +220 -0
  737. package/dist/lib/mail/compose/composeQuoting.d.ts +88 -0
  738. package/dist/lib/mail/compose/composeQuoting.js +204 -0
  739. package/dist/lib/mail/compose/emojiData.d.ts +9 -0
  740. package/dist/lib/mail/compose/emojiData.js +18 -0
  741. package/dist/lib/mail/compose/giphyApi.d.ts +17 -0
  742. package/dist/lib/mail/compose/giphyApi.js +20 -0
  743. package/dist/lib/mail/conversationsApi.d.ts +80 -0
  744. package/dist/lib/mail/conversationsApi.js +44 -0
  745. package/dist/lib/mail/dataExportApi.d.ts +50 -0
  746. package/dist/lib/mail/dataExportApi.js +40 -0
  747. package/dist/lib/mail/directoryApi.d.ts +49 -0
  748. package/dist/lib/mail/directoryApi.js +101 -0
  749. package/dist/lib/mail/erasureRequestApi.d.ts +45 -0
  750. package/dist/lib/mail/erasureRequestApi.js +43 -0
  751. package/dist/lib/mail/flaggedMessages.d.ts +22 -0
  752. package/dist/lib/mail/flaggedMessages.js +73 -0
  753. package/dist/lib/mail/focusedInboxOverridesApi.d.ts +37 -0
  754. package/dist/lib/mail/focusedInboxOverridesApi.js +34 -0
  755. package/dist/lib/mail/labelsApi.d.ts +47 -0
  756. package/dist/lib/mail/labelsApi.js +38 -0
  757. package/dist/lib/mail/mailAddress.d.ts +27 -0
  758. package/dist/lib/mail/mailAddress.js +54 -0
  759. package/dist/lib/mail/mailApi.d.ts +850 -0
  760. package/dist/lib/mail/mailApi.js +602 -0
  761. package/dist/lib/mail/mailDetailHooks.d.ts +10 -0
  762. package/dist/lib/mail/mailDetailHooks.js +53 -0
  763. package/dist/lib/mail/mailFilterRulesApi.d.ts +76 -0
  764. package/dist/lib/mail/mailFilterRulesApi.js +45 -0
  765. package/dist/lib/mail/mailSignaturesApi.d.ts +49 -0
  766. package/dist/lib/mail/mailSignaturesApi.js +42 -0
  767. package/dist/lib/mail/mailboxAccessApi.d.ts +74 -0
  768. package/dist/lib/mail/mailboxAccessApi.js +56 -0
  769. package/dist/lib/mail/mailboxImportApi.d.ts +53 -0
  770. package/dist/lib/mail/mailboxImportApi.js +51 -0
  771. package/dist/lib/mail/messageBodySanitizer.d.ts +16 -0
  772. package/dist/lib/mail/messageBodySanitizer.js +118 -0
  773. package/dist/lib/mail/pushClient.d.ts +106 -0
  774. package/dist/lib/mail/pushClient.js +317 -0
  775. package/dist/lib/mail/sendEvents.d.ts +33 -0
  776. package/dist/lib/mail/sendEvents.js +44 -0
  777. package/dist/lib/mail/sendFailure.d.ts +16 -0
  778. package/dist/lib/mail/sendFailure.js +86 -0
  779. package/dist/lib/mail/senderListsApi.d.ts +69 -0
  780. package/dist/lib/mail/senderListsApi.js +126 -0
  781. package/dist/lib/search/queryGrammar.d.ts +51 -0
  782. package/dist/lib/search/queryGrammar.js +111 -0
  783. package/dist/lib/search/searchApi.d.ts +100 -0
  784. package/dist/lib/search/searchApi.js +107 -0
  785. package/dist/lib/search/searchScoring.d.ts +34 -0
  786. package/dist/lib/search/searchScoring.js +44 -0
  787. package/dist/lib/search/searchTier3.d.ts +64 -0
  788. package/dist/lib/search/searchTier3.js +335 -0
  789. package/dist/lib/tasks/tasksApi.d.ts +85 -0
  790. package/dist/lib/tasks/tasksApi.js +55 -0
  791. package/dist/lib/util/api.d.ts +160 -0
  792. package/dist/lib/util/api.js +251 -0
  793. package/dist/lib/util/apiClientContext.d.ts +7 -0
  794. package/dist/lib/util/apiClientContext.js +32 -0
  795. package/dist/lib/util/apiQuery.d.ts +32 -0
  796. package/dist/lib/util/apiQuery.js +42 -0
  797. package/dist/lib/util/clipboard.d.ts +7 -0
  798. package/dist/lib/util/clipboard.js +56 -0
  799. package/dist/lib/util/dateInput.d.ts +6 -0
  800. package/dist/lib/util/dateInput.js +14 -0
  801. package/dist/lib/util/timeZone.d.ts +12 -0
  802. package/dist/lib/util/timeZone.js +32 -0
  803. package/dist/lib/util/useCopyToClipboard.d.ts +12 -0
  804. package/dist/lib/util/useCopyToClipboard.js +34 -0
  805. package/dist/lib/util/useIsMobile.d.ts +10 -0
  806. package/dist/lib/util/useIsMobile.js +29 -0
  807. package/dist/lib/videoconf/videoMeetingsApi.d.ts +116 -0
  808. package/dist/lib/videoconf/videoMeetingsApi.js +49 -0
  809. package/lib/admin/auditLogApi.ts +48 -0
  810. package/lib/admin/distributionListsApi.ts +77 -0
  811. package/lib/admin/domainsApi.ts +113 -0
  812. package/lib/admin/escrowAccessRequestsApi.ts +110 -0
  813. package/lib/admin/escrowAuditLogApi.ts +101 -0
  814. package/lib/admin/escrowScopesApi.ts +112 -0
  815. package/lib/admin/leftoverMailboxApi.ts +120 -0
  816. package/lib/admin/mailboxPolicyApi.ts +38 -0
  817. package/lib/admin/matterExportApi.ts +62 -0
  818. package/lib/admin/matterSearchApi.ts +35 -0
  819. package/lib/admin/mattersApi.ts +86 -0
  820. package/lib/admin/pluginsApi.ts +339 -0
  821. package/lib/admin/retentionPolicyApi.ts +46 -0
  822. package/lib/admin/setupApi.ts +40 -0
  823. package/lib/admin/transportRulesApi.ts +106 -0
  824. package/lib/appearance/preferencesApi.ts +335 -0
  825. package/lib/auth/profileApi.ts +77 -0
  826. package/lib/auth/session.ts +238 -0
  827. package/lib/branding/brandingApi.ts +97 -0
  828. package/lib/branding/useBranding.ts +81 -0
  829. package/lib/calendar/calendarApi.ts +309 -0
  830. package/lib/calendar/calendarColors.ts +45 -0
  831. package/lib/calendar/calendarDragIds.ts +112 -0
  832. package/lib/calendar/calendarMutations.ts +236 -0
  833. package/lib/calendar/eventDescription.ts +211 -0
  834. package/lib/calendar/freeBusyApi.ts +197 -0
  835. package/lib/calendar/inviteApi.ts +154 -0
  836. package/lib/calendar/recurrence.ts +285 -0
  837. package/lib/components/avatar/ContactAvatar.tsx +47 -0
  838. package/lib/components/buttons/Button.tsx +40 -0
  839. package/lib/components/buttons/CopyButton.tsx +45 -0
  840. package/lib/components/feedback/Alert.tsx +13 -0
  841. package/lib/components/feedback/Skeleton.tsx +38 -0
  842. package/lib/components/forms/FormField.tsx +23 -0
  843. package/lib/components/navigation/BottomTabBar.tsx +66 -0
  844. package/lib/components/overlays/Drawer.tsx +72 -0
  845. package/lib/components/overlays/Modal.tsx +64 -0
  846. package/lib/components/overlays/PopoverPortal.tsx +74 -0
  847. package/lib/components/overlays/overlayStack.ts +165 -0
  848. package/lib/components/pickers/MiniDatePicker.tsx +90 -0
  849. package/lib/contacts/contactsApi.ts +289 -0
  850. package/lib/contacts/vcard.ts +197 -0
  851. package/lib/crypto/composeSecurity.ts +140 -0
  852. package/lib/crypto/encoding.ts +36 -0
  853. package/lib/crypto/escrowKeys.ts +74 -0
  854. package/lib/crypto/idleTimeout.ts +49 -0
  855. package/lib/crypto/keySession.ts +483 -0
  856. package/lib/crypto/keys.ts +105 -0
  857. package/lib/crypto/keyvaultApi.ts +674 -0
  858. package/lib/crypto/masterKey.ts +134 -0
  859. package/lib/crypto/masterKeyWraps.ts +269 -0
  860. package/lib/crypto/messageSecurity.ts +600 -0
  861. package/lib/crypto/mime.ts +568 -0
  862. package/lib/crypto/passkeyUnlock.ts +103 -0
  863. package/lib/crypto/passwordUnlock.ts +98 -0
  864. package/lib/crypto/recoveryCode.ts +93 -0
  865. package/lib/crypto/signingProviderApi.ts +135 -0
  866. package/lib/crypto/smime.ts +459 -0
  867. package/lib/crypto/smimeMessage.ts +491 -0
  868. package/lib/crypto/useIdleKeyTimeout.ts +176 -0
  869. package/lib/crypto/verificationSeal.ts +288 -0
  870. package/lib/mail/compose/composeQuoting.ts +243 -0
  871. package/lib/mail/compose/emojiData.ts +34 -0
  872. package/lib/mail/compose/giphyApi.ts +31 -0
  873. package/lib/mail/conversationsApi.ts +123 -0
  874. package/lib/mail/dataExportApi.ts +73 -0
  875. package/lib/mail/directoryApi.ts +161 -0
  876. package/lib/mail/erasureRequestApi.ts +71 -0
  877. package/lib/mail/flaggedMessages.ts +80 -0
  878. package/lib/mail/focusedInboxOverridesApi.ts +64 -0
  879. package/lib/mail/labelsApi.ts +71 -0
  880. package/lib/mail/mailAddress.ts +76 -0
  881. package/lib/mail/mailApi.ts +1286 -0
  882. package/lib/mail/mailDetailHooks.ts +57 -0
  883. package/lib/mail/mailFilterRulesApi.ts +116 -0
  884. package/lib/mail/mailSignaturesApi.ts +84 -0
  885. package/lib/mail/mailboxAccessApi.ts +106 -0
  886. package/lib/mail/mailboxImportApi.ts +87 -0
  887. package/lib/mail/messageBodySanitizer.ts +129 -0
  888. package/lib/mail/pushClient.ts +375 -0
  889. package/lib/mail/sendEvents.ts +72 -0
  890. package/lib/mail/sendFailure.ts +98 -0
  891. package/lib/mail/senderListsApi.ts +161 -0
  892. package/lib/search/queryGrammar.ts +179 -0
  893. package/lib/search/searchApi.ts +199 -0
  894. package/lib/search/searchScoring.ts +46 -0
  895. package/lib/search/searchTier3.ts +406 -0
  896. package/lib/tasks/tasksApi.ts +128 -0
  897. package/lib/util/api.ts +318 -0
  898. package/lib/util/apiClientContext.ts +35 -0
  899. package/lib/util/apiQuery.ts +61 -0
  900. package/lib/util/clipboard.ts +55 -0
  901. package/lib/util/dateInput.ts +15 -0
  902. package/lib/util/timeZone.ts +33 -0
  903. package/lib/util/useCopyToClipboard.ts +48 -0
  904. package/lib/util/useIsMobile.ts +34 -0
  905. package/lib/videoconf/videoMeetingsApi.ts +144 -0
  906. package/package.json +10 -4
@@ -0,0 +1,600 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /**
6
+ * Evaluates a *received* message's raw MIME source into one of `specs/end-to-end_encryption.md`'s
7
+ * "Message Security Indicators" states, and recovers the plaintext body when applicable. Reads the
8
+ * outer envelope's own `Content-Type` (via `mime.ts`'s `parseMimeEntity()`) to decide whether the message
9
+ * is `multipart/signed`, `application/pkcs7-mime; smime-type="enveloped-data"`, or neither.
10
+ *
11
+ * **What a verified state means.** `"signed_verified"`/`"encrypted_verified"` require ALL of: (1) a
12
+ * cryptographically valid CMS signature (`smime.ts` - detached signatures carrying their own eContent are
13
+ * rejected, the signer certificate is the one matched to the SignerInfo, never simply the first embedded
14
+ * certificate, and a `multipart/signed` body must hold exactly the signed part and the signature); (2) the
15
+ * signer certificate's fingerprint is one the reader already trusts - a pinned `Contact` signing key passed
16
+ * as `pinnedSignerFingerprints`, or the unlocked mailbox's own `signingFingerprint`; (3) the signer
17
+ * certificate names the sender: one of its email addresses (SAN rfc822Name, else subject emailAddress /
18
+ * email-shaped CN) equals the single address in the protected `From` (or the outer `From` when the signed
19
+ * content carries no protected headers, as with non-RFC 9788 senders); (4) the protected `From`/`To`/`Cc`
20
+ * address sets (when present) equal the outer envelope's, a signed-only message's protected `Subject` equals
21
+ * its outer one (what the mail list shows), and neither header block carries more than one
22
+ * `From`/`To`/`Cc`/`Sender` field.
23
+ *
24
+ * **No trust anchor, no verified badge.** Certificates aren't chain-validated (there is no trust store), so
25
+ * checks 1, 3 and 4 alone prove only that *someone* holding a certificate naming the sender signed it - a
26
+ * self-issued certificate with SAN `ceo@victim.com` passes them. Without a matching pin the result is
27
+ * `"signed_unverified_signer"`/`"encrypted_unverified_signer"` instead, carrying `signerFingerprint` and
28
+ * `signerEmails` so a UI can show "signed by an unverified certificate" and offer to trust it. A failure of checks 1, 3
29
+ * or 4 is `"signature_failed"` with `signatureFailureReason` saying which check failed.
30
+ *
31
+ * **Pinned, but a different key.** When pins were supplied and checks 1, 3 and 4 pass but the signer matches no pin, the
32
+ * result is `"signature_failed"` with `signatureFailureReason: "signer_key_changed"`: the sender's certificate names
33
+ * them and the message is intact, but it isn't the key the reader pinned (a rotation the reader hasn't accepted, or an
34
+ * impersonation). Only this failure also carries `signerCertificate`, so a UI can compare it with the pinned keys
35
+ * (`contactsApi.ts`'s `fetchSignerKeyState()`) and let the user accept or reject it (`keyvaultApi.ts`'s
36
+ * `resolveKeyConflict()`). A pin mismatch whose certificate also fails check 3 or 4 (or couldn't be resolved) stays
37
+ * `untrusted_signer`. Previously pinned keys count as pins (see `signingKeyFingerprints()`), so mail signed before an
38
+ * accepted or automatic rotation still verifies.
39
+ */
40
+ import { DisplayBody, MimeAttachment, MimeHeaderField, decodeHeaderText, extractAddresses, parseMimeEntity, parseParameterizedHeader, plainTextToHtml } from "./mime.js";
41
+ import { toBase64 } from "./encoding.js";
42
+ import { computeCertFingerprint, extractCertificateEmails } from "./smime.js";
43
+ import { ComparableOuterHeaders, ProtectedHeaders, parseEncryptedMessageWithKeys, parseSignedOnlyMessage } from "./smimeMessage.js";
44
+ import { type PublicKey, isTrustedForVerification } from "./keyvaultApi.js";
45
+ import { KeysLockedError } from "./masterKey.js";
46
+ import { type SealKeyMaterial, type SealedVerificationState, buildVerificationSeal, openVerificationSeal, rawMimeSha256 } from "./verificationSeal.js";
47
+
48
+ export { signingKeyFingerprints } from "./keyvaultApi.js";
49
+
50
+
51
+ /** `"signed_unverified_signer"`/`"encrypted_unverified_signer"`: the signature is valid and its certificate
52
+ * names the sender, but the certificate isn't one the reader trusts (no pinned key matched) - see this module's
53
+ * doc comment. The encrypted variant's content was decrypted like `"encrypted_verified"`'s.
54
+ *
55
+ * `"verified_at_first_open"`: only ever returned by `evaluateMessageSecurityWithSeal()`. The live check now fails only
56
+ * because of the signer key's status (`signer_key_changed`, or `*_unverified_signer` - the pins are gone or no longer
57
+ * trust the key), but the message carries a valid verification seal (`verificationSeal.ts`) for this exact raw MIME and
58
+ * this same signer certificate, recording that it verified when first opened. The result carries `verifiedAt`,
59
+ * `sealedState`, `signerFingerprint`, the recovered content, `liveState`/`liveSignatureFailureReason`, and
60
+ * `laterCompromised` when the signer key has since been revoked as compromised. A UI should show it as "verified when
61
+ * first opened" - distinct from the live verified states, and with a warning when `laterCompromised` is set. */
62
+ export type MessageSecurityState =
63
+ | "encrypted"
64
+ | "signed_verified"
65
+ | "encrypted_verified"
66
+ | "signed_unverified_signer"
67
+ | "encrypted_unverified_signer"
68
+ | "signature_failed"
69
+ | "verified_at_first_open"
70
+ | "unprotected";
71
+
72
+ /** Why a message is `"signature_failed"`. `invalid_signature`: the CMS signature itself is malformed or
73
+ * doesn't verify over the content (or a `multipart/signed` body doesn't hold exactly two parts).
74
+ * `signer_key_changed`: pinned fingerprints were supplied and the signer certificate matches none of them, but it
75
+ * names the sender and every header check passes - the sender appears to use a new key (see this module's doc
76
+ * comment); the result carries `signerCertificate`. `untrusted_signer`: pinned fingerprints were supplied and the signer
77
+ * certificate matches none of them and also fails the identity or header checks (or no signer certificate could be
78
+ * resolved at all). `signer_identity_mismatch`: the signer certificate doesn't name the message's `From` address (or
79
+ * `From` doesn't hold exactly one address). `header_mismatch`: the signed/protected `From`/`To`/`Cc` (or a signed-only
80
+ * message's `Subject`) disagree with the outer envelope's, or either header block repeats a `From`/`To`/`Cc`/`Sender`
81
+ * field. */
82
+ export type SignatureFailureReason = "invalid_signature" | "signer_key_changed" | "untrusted_signer" | "signer_identity_mismatch" | "header_mismatch";
83
+
84
+ /** The header fields recovered from inside the signed/encrypted entity (RFC 9788 header protection), decoded
85
+ * for display where they are text. */
86
+ export interface MessageProtectedHeaders {
87
+ from: string;
88
+ to: string;
89
+ cc?: string;
90
+ subject: string;
91
+ }
92
+
93
+ export interface MessageSecurityResult {
94
+ state: MessageSecurityState;
95
+ /** The verified/decrypted content as HTML - still needs client-side sanitization before touching the
96
+ * DOM (this module does none itself; see `MessageDetailPane.tsx`). For a `text/html` body this is that
97
+ * HTML; for a `text/plain` body it is the text HTML-escaped inside a whitespace-preserving `<pre>`
98
+ * (never plain text passed through as markup), with the raw text in `text`. Absent for
99
+ * `"unprotected"` (the caller should keep using the server's own sanitized `/content` body) and for an
100
+ * encrypted message this device couldn't open (see `decryptError`). */
101
+ html?: string;
102
+ /** The raw plain text, present only when the recovered body was `text/plain` (not `text/html`). */
103
+ text?: string;
104
+ /** `true` when `evaluateMessageSecurity()` was given a `readerAddress` and recovered protected `To`/`Cc`
105
+ * headers that don't include it - e.g. a genuinely signed message re-sent verbatim to someone it was
106
+ * never addressed to. Informational, orthogonal to `state` (a Bcc recipient legitimately sees this
107
+ * too), so a UI can say "this message wasn't addressed to you" next to an otherwise valid signature.
108
+ * `undefined` when no reader address was given or nothing protected was recovered. */
109
+ notAddressedToReader?: boolean;
110
+ /** Present only for `"signature_failed"`: which verification step failed. */
111
+ signatureFailureReason?: SignatureFailureReason;
112
+ /** Present only when the message was encrypted but this device couldn't decrypt it (a wrong or
113
+ * since-rotated key, non-AEAD content encryption, or corrupt/foreign data) - the caller should keep
114
+ * showing whatever `GET /:id/content` already produced alongside this explanation. */
115
+ decryptError?: string;
116
+ /** See `ParsedEncryptedMessage.headerTamperDetected`'s own doc comment - a deliberately separate,
117
+ * orthogonal signal from `state`, since RFC 9788's `HP-Outer` is written on every encrypted message
118
+ * regardless of whether it's also signed. `undefined` for anything that isn't an encrypted message
119
+ * this device could decrypt. */
120
+ headerTamperDetected?: boolean;
121
+ /** The real subject recovered from the message's protected headers - RFC 9788 header protection
122
+ * obscures the outer envelope's own `Subject` to `"[...]"`. Populated only when content was actually
123
+ * recovered and it carried a protected Subject. */
124
+ subject?: string;
125
+ /** Every protected header recovered from inside the signed/decrypted entity - present only when that entity
126
+ * carries RFC 9788 protected headers (a protected `From`). Absent for a legacy S/MIME sender's signed-only
127
+ * message: its outer Subject/To/Cc were then never signed, and a UI should not present them as verified. */
128
+ protectedHeaders?: MessageProtectedHeaders;
129
+ /** The attachments inside the verified/decrypted entity - for a signed-only message the only attachments the
130
+ * signature covers, so a UI showing a verified badge should list these rather than the server's attachment
131
+ * records (which include anything outside the signed part). Present whenever content was recovered. */
132
+ attachments?: MimeAttachment[];
133
+ /** SHA-256 fingerprint (hex) of the certificate that produced a cryptographically valid signature - present
134
+ * for `"signed_verified"`, `"encrypted_verified"`, the `*_unverified_signer` states and a `"signature_failed"`
135
+ * whose signature itself was valid. Compare against / pin as a `PublicKey.fingerprint`. */
136
+ signerFingerprint?: string;
137
+ /** The email addresses that signer certificate asserts (lowercased), alongside `signerFingerprint`. */
138
+ signerEmails?: string[];
139
+ /** Base64 DER of the certificate that verified the signature - what `keyvaultApi.ts`'s `trustSigner()` pins for
140
+ * a "trust this signer" action. Present alongside `signerFingerprint` for `"signed_verified"`,
141
+ * `"encrypted_verified"`, the `*_unverified_signer` states, and `"signature_failed"` with reason
142
+ * `"signer_key_changed"` (for a key-changed comparison and `resolveKeyConflict()`'s `certificate`). Never for any
143
+ * other `"signature_failed"`, even when its signature itself was valid (a failed binding is not something to offer
144
+ * trusting). */
145
+ signerCertificate?: string;
146
+ /** Only from `evaluateMessageSecurityWithSeal()`: a seal for a live `"signed_verified"`/`"encrypted_verified"` result
147
+ * when no stored seal opens under the current master key generation, or the stored seal is from an older generation.
148
+ * Persist it best effort with `mailApi.ts`'s `setMessageVerificationSeal(messageUid, sealToWrite.seal,
149
+ * sealToWrite.masterKeyGeneration)` (a `VerificationSealConflictError` means the server kept the stored seal - ignore
150
+ * it). */
151
+ sealToWrite?: SealToWrite;
152
+ /** For `"verified_at_first_open"`: when the sealed verification happened (epoch ms). */
153
+ verifiedAt?: number;
154
+ /** For `"verified_at_first_open"`: the verified state the seal recorded. */
155
+ sealedState?: SealedVerificationState;
156
+ /** For `"verified_at_first_open"`: the live state the seal overrode (`"signature_failed"` or `*_unverified_signer`). */
157
+ liveState?: MessageSecurityState;
158
+ /** For `"verified_at_first_open"` over a live `"signature_failed"`: its reason (always `"signer_key_changed"`). */
159
+ liveSignatureFailureReason?: SignatureFailureReason;
160
+ /** For `"verified_at_first_open"`: `true` when the caller's `signerKeys` show the signer key is now revoked as
161
+ * compromised (or revoked with no reason) - the seal proves it verified then, not that the key was safe then. */
162
+ laterCompromised?: boolean;
163
+ }
164
+
165
+ /** A seal for the caller to store, with the master key generation it was written under. */
166
+ export interface SealToWrite {
167
+ seal: string;
168
+ masterKeyGeneration: number;
169
+ }
170
+
171
+ function isSignedOnlyContentType(contentTypeValue: string): boolean {
172
+ return contentTypeValue === "multipart/signed";
173
+ }
174
+
175
+ /** Matches `buildEncryptedMessage()`'s own output shape, and leniently accepts the equivalent legacy/
176
+ * AEAD `smime-type` values a foreign S/MIME sender could produce (mirrors `@rapidmx/restapi`'s own
177
+ * server-side `SmimeUtils.isEncryptedBody()` classification, so the two systems agree on what counts as
178
+ * encrypted). Parameters are matched case-insensitively, quoted or not. */
179
+ function isEncryptedContentType(contentType: { value: string; params: Record<string, string> }): boolean {
180
+ if (contentType.value === "multipart/encrypted") {
181
+ return true;
182
+ }
183
+ if (!contentType.value.endsWith("pkcs7-mime")) {
184
+ return false;
185
+ }
186
+ const smimeType = contentType.params["smime-type"]?.toLowerCase();
187
+ return smimeType === "enveloped-data" || smimeType === "authenveloped-data";
188
+ }
189
+
190
+ const NO_KEY_ERROR = "This device doesn't have the key needed to decrypt this message.";
191
+ const UNSUPPORTED_ENCRYPTION_ERROR =
192
+ "This message uses an older, unauthenticated encryption algorithm that RapidMX doesn't accept, so it can't be opened safely.";
193
+
194
+ function renderDisplayBody(display: DisplayBody | undefined): Pick<MessageSecurityResult, "html" | "text"> {
195
+ if (display?.html !== undefined) {
196
+ return { html: display.html };
197
+ }
198
+ if (display?.text !== undefined) {
199
+ return { html: plainTextToHtml(display.text), text: display.text };
200
+ }
201
+ return {};
202
+ }
203
+
204
+ function sameAddressSet(a: string[], b: string[]): boolean {
205
+ const left = new Set(a);
206
+ const right = new Set(b);
207
+ return left.size === right.size && [...left].every((address) => right.has(address));
208
+ }
209
+
210
+ /** Normalizes whitespace runs, so a Subject refolded in transit still compares equal. */
211
+ function normalizeSubject(value: string | undefined): string {
212
+ return decodeHeaderText(value ?? "")
213
+ .replace(/\s+/g, " ")
214
+ .trim();
215
+ }
216
+
217
+
218
+ export interface SignerBindingInput {
219
+ /** The certificate matched to the verified SignerInfo; `undefined` fails closed. */
220
+ signerCertificateDer: Uint8Array | undefined;
221
+ /** Headers recovered from inside the signed content (RFC 9788), if any. */
222
+ protectedHeaders: (Pick<ProtectedHeaders, "from" | "to"> & Partial<Pick<ProtectedHeaders, "cc" | "subject">>) | undefined;
223
+ /** The received message's outer header map (lowercased names), as `parseMimeEntity()` returns it. */
224
+ outerHeaders: Record<string, string>;
225
+ /** Every outer header field in order (`parseMimeEntity()`'s `fields`) - checked for repeated
226
+ * `From`/`To`/`Cc`/`Sender`. Omitted, only the first-occurrence map above is available. */
227
+ outerFields?: MimeHeaderField[];
228
+ /** Every protected header field in order - checked for repeats the same way. */
229
+ protectedFields?: MimeHeaderField[];
230
+ /** One trusted fingerprint or several (any match is accepted). An empty array counts as none supplied. */
231
+ pinnedSignerFingerprint?: string | string[];
232
+ /** Also require the protected `Subject` (when protected headers are present) to equal the outer one - right for
233
+ * a signed-only (`hp="clear"`) message, wrong for an encrypted one whose outer Subject is obscured. */
234
+ compareSubject?: boolean;
235
+ }
236
+
237
+ /** Address header fields a message must carry at most once (RFC 5322 §3.6 allows exactly zero or one). */
238
+ const SINGLETON_ADDRESS_FIELDS = ["from", "to", "cc", "sender"];
239
+
240
+ function hasRepeatedAddressField(fields: MimeHeaderField[] | undefined): boolean {
241
+ const counts = new Map<string, number>();
242
+ for (const { name } of fields ?? []) {
243
+ const key = name.toLowerCase();
244
+ counts.set(key, (counts.get(key) ?? 0) + 1);
245
+ }
246
+ return SINGLETON_ADDRESS_FIELDS.some((name) => (counts.get(name) ?? 0) > 1);
247
+ }
248
+
249
+ function normalizePins(pins: string | string[] | undefined): string[] {
250
+ return (Array.isArray(pins) ? pins : pins === undefined ? [] : [pins]).map((pin) => pin.toLowerCase());
251
+ }
252
+
253
+ /** Checks 2-4 from this module's doc comment for an already cryptographically verified signature.
254
+ * Returns `undefined` when the signer is accepted, otherwise the failure reason. A pin mismatch is
255
+ * `"signer_key_changed"` when checks 3 and 4 pass for the certificate, and `"untrusted_signer"` when they don't (or no
256
+ * certificate was resolved).
257
+ *
258
+ * With no `pinnedSignerFingerprint` (or an empty array), check 2 is skipped and `undefined` means only that the
259
+ * certificate names the sender consistently - NOT that the signer is trusted. Use `evaluateMessageSecurity()`
260
+ * (which reports that case as `*_unverified_signer`) unless you enforce a pin yourself. */
261
+ export async function checkSignerBinding(input: SignerBindingInput): Promise<SignatureFailureReason | undefined> {
262
+ const pins = normalizePins(input.pinnedSignerFingerprint);
263
+ // Fail closed: an absent certificate hashes/extracts as empty, which can never match a pin or From.
264
+ const certDer = input.signerCertificateDer ?? new Uint8Array();
265
+ if (pins.length > 0 && !pins.includes(await computeCertFingerprint(certDer))) {
266
+ // A certificate that otherwise binds cleanly to the sender is a key change for the user to judge; anything else
267
+ // (no certificate, wrong identity, header tampering) stays a plain untrusted signer.
268
+ return input.signerCertificateDer && checkIdentityAndHeaders(input, certDer) === undefined ? "signer_key_changed" : "untrusted_signer";
269
+ }
270
+ return checkIdentityAndHeaders(input, certDer);
271
+ }
272
+
273
+ /** Checks 3-4 from this module's doc comment. */
274
+ function checkIdentityAndHeaders(input: SignerBindingInput, certDer: Uint8Array): SignatureFailureReason | undefined {
275
+ const { protectedHeaders, outerHeaders } = input;
276
+ if (hasRepeatedAddressField(input.outerFields) || hasRepeatedAddressField(input.protectedFields)) {
277
+ return "header_mismatch";
278
+ }
279
+ const outerFrom = extractAddresses(outerHeaders["from"]);
280
+ const protectedFrom = extractAddresses(protectedHeaders?.from);
281
+ const senderAddresses = protectedFrom.length > 0 ? protectedFrom : outerFrom;
282
+ if (senderAddresses.length !== 1 || !extractCertificateEmails(certDer).includes(senderAddresses[0])) {
283
+ return "signer_identity_mismatch";
284
+ }
285
+ const protectedTo = extractAddresses(protectedHeaders?.to);
286
+ if (!sameAddressSet(senderAddresses, outerFrom) || (protectedTo.length > 0 && !sameAddressSet(protectedTo, extractAddresses(outerHeaders["to"])))) {
287
+ return "header_mismatch";
288
+ }
289
+ if (protectedFrom.length > 0) {
290
+ // RFC 9788 protected headers are present, so Cc (possibly absent on both sides) and - for a signed-only
291
+ // message - Subject were signed: an outer copy that differs was changed (or added) after signing.
292
+ if (!sameAddressSet(extractAddresses(protectedHeaders?.cc), extractAddresses(outerHeaders["cc"]))) {
293
+ return "header_mismatch";
294
+ }
295
+ if (input.compareSubject && normalizeSubject(protectedHeaders?.subject) !== normalizeSubject(outerHeaders["subject"])) {
296
+ return "header_mismatch";
297
+ }
298
+ }
299
+ return undefined;
300
+ }
301
+
302
+ /**
303
+ * Evaluates one received message's raw MIME source (see `mailApi.ts`'s `getMessageRawContent()`) into
304
+ * a security state + recovered plaintext. Never throws — a parse failure, wrong key, or unrecognized
305
+ * content type all degrade to a result the caller can render directly.
306
+ *
307
+ * `pinnedSignerFingerprints` - the sender's trusted signing-key fingerprint(s): `signingKeyFingerprints()` of the
308
+ * sender's `Contact.keys` and `Contact.previousKeys` (see `contactsApi.ts`'s `fetchPinnedSigningFingerprints()`). A
309
+ * supplied pin that the signer doesn't match is `signer_key_changed` or `untrusted_signer`. The unlocked mailbox's own
310
+ * `signingFingerprint` is always trusted too (mail this mailbox signed itself). Omitted or empty, a valid signature
311
+ * from any other certificate is `*_unverified_signer`, never verified. `readerAddress` - the unlocked mailbox's own
312
+ * address - enables `notAddressedToReader`.
313
+ *
314
+ * An encrypted message is decrypted with `unlocked`'s active encryption key or any of its `retainedEncryptionKeys` (the
315
+ * older keys a rotation replaced - see `keySession.ts`), matched by recipient identifier first.
316
+ */
317
+ export async function evaluateMessageSecurity(
318
+ rawMime: string,
319
+ unlocked: MessageSecurityKeys | undefined,
320
+ pinnedSignerFingerprints?: string | string[],
321
+ readerAddress?: string,
322
+ ): Promise<MessageSecurityResult> {
323
+ return (await evaluateLive(rawMime, unlocked, pinnedSignerFingerprints, readerAddress)).result;
324
+ }
325
+
326
+ /** The keys `evaluateMessageSecurity()` reads from an unlocked session (`keySession.ts`'s `UnlockedKeys`). */
327
+ export interface MessageSecurityKeys {
328
+ encryptionPrivateKey?: CryptoKey;
329
+ encryptionCertDer?: Uint8Array;
330
+ retainedEncryptionKeys?: { certDer: Uint8Array; privateKey: CryptoKey }[];
331
+ signingFingerprint?: string;
332
+ }
333
+
334
+ /** `evaluateMessageSecurity()`'s result plus what the seal-aware wrapper needs: which kind of protected message it was,
335
+ * and a signed-only message's verified content, which a `signer_key_changed` result doesn't carry publicly. */
336
+ interface LiveEvaluation {
337
+ result: MessageSecurityResult;
338
+ kind: "signed" | "encrypted" | "other";
339
+ signedContent?: Partial<MessageSecurityResult>;
340
+ }
341
+
342
+ async function evaluateLive(
343
+ rawMime: string,
344
+ unlocked: MessageSecurityKeys | undefined,
345
+ pinnedSignerFingerprints: string | string[] | undefined,
346
+ readerAddress: string | undefined,
347
+ ): Promise<LiveEvaluation> {
348
+ const { headers, body, fields } = parseMimeEntity(rawMime);
349
+ const rawContentType = headers["content-type"];
350
+ if (!rawContentType) {
351
+ return { result: { state: "unprotected" }, kind: "other" };
352
+ }
353
+ const contentType = parseParameterizedHeader(rawContentType);
354
+ const callerPins = normalizePins(pinnedSignerFingerprints);
355
+
356
+ // The received message's own *real* outer envelope - what `HP-Outer`'s field copies (written at
357
+ // send time, inside the encrypted content) are compared against to detect post-send tampering.
358
+ const actualOuterHeaders: ComparableOuterHeaders = {
359
+ from: headers["from"],
360
+ to: headers["to"],
361
+ cc: headers["cc"],
362
+ date: headers["date"],
363
+ subject: headers["subject"],
364
+ };
365
+
366
+ /** Runs checks 2-4 and resolves the trust outcome: a failure reason, or whether a pin matched. */
367
+ const checkSigner = async (
368
+ signerCertificateDer: Uint8Array | undefined,
369
+ protectedHeaders: ProtectedHeaders | undefined,
370
+ protectedFields: MimeHeaderField[] | undefined,
371
+ compareSubject: boolean,
372
+ ): Promise<{
373
+ failure?: SignatureFailureReason;
374
+ trusted: boolean;
375
+ signer: Pick<MessageSecurityResult, "signerFingerprint" | "signerEmails">;
376
+ acceptedSigner: Pick<MessageSecurityResult, "signerFingerprint" | "signerEmails" | "signerCertificate">;
377
+ }> => {
378
+ const certDer = signerCertificateDer ?? new Uint8Array();
379
+ const fingerprint = await computeCertFingerprint(certDer);
380
+ const signer = signerCertificateDer ? { signerFingerprint: fingerprint, signerEmails: extractCertificateEmails(certDer) } : {};
381
+ // The certificate itself (for "trust this signer" or a key-changed comparison) only accompanies a signature that
382
+ // didn't fail or failed only as `signer_key_changed` - both always have a certificate (a missing one fails the
383
+ // binding check closed as another reason), so `certDer` is the real one.
384
+ const acceptedSigner = { ...signer, signerCertificate: toBase64(certDer) };
385
+ const trustedPins = unlocked?.signingFingerprint ? [...callerPins, unlocked.signingFingerprint.toLowerCase()] : callerPins;
386
+ const failure = await checkSignerBinding({
387
+ signerCertificateDer,
388
+ protectedHeaders,
389
+ outerHeaders: headers,
390
+ outerFields: fields,
391
+ protectedFields,
392
+ // Only pins the caller supplied make a mismatch a failure; the mailbox's own key alone never does.
393
+ pinnedSignerFingerprint: callerPins.length > 0 ? trustedPins : undefined,
394
+ compareSubject,
395
+ });
396
+ return { failure, trusted: trustedPins.includes(fingerprint), signer, acceptedSigner };
397
+ };
398
+
399
+ const addressing = (protectedHeaders: ProtectedHeaders | undefined): Pick<MessageSecurityResult, "notAddressedToReader"> => {
400
+ const recipients = [...extractAddresses(protectedHeaders?.to), ...extractAddresses(protectedHeaders?.cc)];
401
+ if (!readerAddress || recipients.length === 0) {
402
+ return {};
403
+ }
404
+ return { notAddressedToReader: !recipients.includes(readerAddress.trim().toLowerCase()) };
405
+ };
406
+
407
+ const exposedHeaders = (protectedHeaders: ProtectedHeaders | undefined): Pick<MessageSecurityResult, "protectedHeaders"> => {
408
+ if (!protectedHeaders || extractAddresses(protectedHeaders.from).length === 0) {
409
+ return {};
410
+ }
411
+ const { from, to, cc, subject } = protectedHeaders;
412
+ return { protectedHeaders: { from, to, ...(cc !== undefined ? { cc } : {}), subject } };
413
+ };
414
+
415
+ if (isSignedOnlyContentType(contentType.value)) {
416
+ const parsed = await parseSignedOnlyMessage(rawContentType, body);
417
+ if (!parsed.verified) {
418
+ return { result: { state: "signature_failed", signatureFailureReason: "invalid_signature" }, kind: "signed" };
419
+ }
420
+ const { failure, trusted, signer, acceptedSigner } = await checkSigner(parsed.signerCertificateDer, parsed.protectedHeaders, parsed.protectedHeaderFields, true);
421
+ const content = {
422
+ ...renderDisplayBody(parsed.displayBody),
423
+ subject: parsed.protectedHeaders?.subject || undefined,
424
+ ...exposedHeaders(parsed.protectedHeaders),
425
+ attachments: parsed.attachments,
426
+ };
427
+ if (failure) {
428
+ const result: MessageSecurityResult = { state: "signature_failed", signatureFailureReason: failure, ...(failure === "signer_key_changed" ? acceptedSigner : signer) };
429
+ return { result, kind: "signed", ...(failure === "signer_key_changed" ? { signedContent: { ...content, ...addressing(parsed.protectedHeaders) } } : {}) };
430
+ }
431
+ return {
432
+ result: { state: trusted ? "signed_verified" : "signed_unverified_signer", ...content, ...acceptedSigner, ...addressing(parsed.protectedHeaders) },
433
+ kind: "signed",
434
+ };
435
+ }
436
+
437
+ if (isEncryptedContentType(contentType)) {
438
+ // The active key first, then the retained older ones (see `keySession.ts`'s `retainedEncryptionKeys`), so mail
439
+ // encrypted to a key since replaced still opens. Only ever used to decrypt here - never to encrypt or sign.
440
+ const keys = [
441
+ ...(unlocked?.encryptionPrivateKey && unlocked.encryptionCertDer ? [{ certDer: unlocked.encryptionCertDer, privateKey: unlocked.encryptionPrivateKey }] : []),
442
+ ...(unlocked?.retainedEncryptionKeys ?? []).map(({ certDer, privateKey }) => ({ certDer, privateKey })),
443
+ ];
444
+ if (keys.length === 0) {
445
+ return { result: { state: "encrypted", decryptError: NO_KEY_ERROR }, kind: "encrypted" };
446
+ }
447
+ const parsed = await parseEncryptedMessageWithKeys(body, keys, actualOuterHeaders);
448
+ if (!parsed.decrypted) {
449
+ return { result: { state: "encrypted", decryptError: parsed.unsupportedContentEncryption ? UNSUPPORTED_ENCRYPTION_ERROR : NO_KEY_ERROR }, kind: "encrypted" };
450
+ }
451
+ const content = {
452
+ ...renderDisplayBody(parsed.displayBody),
453
+ headerTamperDetected: parsed.headerTamperDetected,
454
+ subject: parsed.protectedHeaders?.subject || undefined,
455
+ ...exposedHeaders(parsed.protectedHeaders),
456
+ attachments: parsed.attachments,
457
+ ...addressing(parsed.protectedHeaders),
458
+ };
459
+ if (parsed.signatureVerified === undefined) {
460
+ return { result: { state: "encrypted", ...content }, kind: "encrypted" };
461
+ }
462
+ if (!parsed.signatureVerified) {
463
+ return { result: { state: "signature_failed", signatureFailureReason: "invalid_signature", ...content }, kind: "encrypted" };
464
+ }
465
+ const { failure, trusted, signer, acceptedSigner } = await checkSigner(parsed.signerCertificateDer, parsed.protectedHeaders, parsed.protectedHeaderFields, false);
466
+ if (failure) {
467
+ return { result: { state: "signature_failed", signatureFailureReason: failure, ...content, ...(failure === "signer_key_changed" ? acceptedSigner : signer) }, kind: "encrypted" };
468
+ }
469
+ return { result: { state: trusted ? "encrypted_verified" : "encrypted_unverified_signer", ...content, ...acceptedSigner }, kind: "encrypted" };
470
+ }
471
+
472
+ return { result: { state: "unprotected" }, kind: "other" };
473
+ }
474
+
475
+ /** Options for `evaluateMessageSecurityWithSeal()`. */
476
+ export interface VerificationSealOptions {
477
+ mailboxUid: string;
478
+ messageUid: string;
479
+ /** The message's stored `Message.verificationSeal`, if any. */
480
+ seal?: string;
481
+ /** The vault's current `KeyVault.masterKeyGeneration` (`0` when it reports none): the generation a stored seal must
482
+ * carry to be honoured, and the one a new `sealToWrite` is written under. */
483
+ masterKeyGeneration: number;
484
+ /** The message's stored `Message.verificationSealGeneration`, if any. When it is older than `masterKeyGeneration`, a
485
+ * live verified message is re-sealed (after a `rekey()`). */
486
+ sealGeneration?: number;
487
+ /** The signer's key records the caller knows about, to tell whether the sealed signer key has since been revoked as
488
+ * compromised: e.g. `[...state.pinned, ...state.previous]` from `contactsApi.ts`'s `fetchSignerKeyState()` for the
489
+ * sender, plus the mailbox's own `keys` for mail from its own address. A record whose fingerprint equals the signer's
490
+ * and fails `isTrustedForVerification()` sets `laterCompromised`. Omitted, `laterCompromised` is never set. */
491
+ signerKeys?: readonly PublicKey[];
492
+ /** The `verifiedAt` recorded in a new `sealToWrite`. Defaults to `Date.now()`. */
493
+ now?: number;
494
+ }
495
+
496
+ const LIVE_VERIFIED_STATES: readonly MessageSecurityState[] = ["signed_verified", "encrypted_verified"];
497
+
498
+ /** Whether a live result failed only because of the signer key's status - the cases a seal may override. Every other
499
+ * failure (an invalid signature, identity or header mismatch, `untrusted_signer`, HP-Outer tampering) never is. */
500
+ function failedOnlyOnKeyStatus(result: MessageSecurityResult): boolean {
501
+ if (result.headerTamperDetected) {
502
+ return false;
503
+ }
504
+ return (
505
+ result.state === "signed_unverified_signer" ||
506
+ result.state === "encrypted_unverified_signer" ||
507
+ (result.state === "signature_failed" && result.signatureFailureReason === "signer_key_changed")
508
+ );
509
+ }
510
+
511
+ /**
512
+ * `evaluateMessageSecurity()` with verification seals (`verificationSeal.ts`). The live evaluation always runs first,
513
+ * with the same arguments; then:
514
+ *
515
+ * **Live verified** (`"signed_verified"`/`"encrypted_verified"`, no HP-Outer tampering), and either no seal opens for this
516
+ * mailbox, message, raw MIME and `options.masterKeyGeneration`, or `options.sealGeneration` is older than
517
+ * `options.masterKeyGeneration`: the result gains `sealToWrite` (`{ seal, masterKeyGeneration }`), sealing the live
518
+ * `signerFingerprint` and state at `options.now` under the current generation. The caller persists it best effort
519
+ * (`setMessageVerificationSeal()`). This is how messages are re-sealed, lazily, after a `rekey()`: seals are never
520
+ * carried across a master key rotation (see `verificationSeal.ts`).
521
+ *
522
+ * **Live failure caused only by key status** (`signer_key_changed`, `signed_unverified_signer`,
523
+ * `encrypted_unverified_signer` - which also covers a signer key since revoked, since `signingKeyFingerprints()` drops
524
+ * such pins): when the seal opens, its `signerFingerprint` equals the live one and its state matches the message kind
525
+ * (signed-only vs. encrypted), the result is `"verified_at_first_open"` with `verifiedAt`, `sealedState`,
526
+ * `signerFingerprint`, the recovered content (for a signed-only `signer_key_changed` message too), `liveState`,
527
+ * `liveSignatureFailureReason` and `laterCompromised` (see `VerificationSealOptions.signerKeys`).
528
+ * `signatureFailureReason` is dropped.
529
+ *
530
+ * **Everything else** returns the live result unchanged: an invalid signature, identity or header mismatch,
531
+ * `untrusted_signer`, HP-Outer tampering, a seal whose MAC fails or whose hash, uids, generation or signer fingerprint differ, and
532
+ * every unsigned state.
533
+ *
534
+ * With `unlocked` undefined (no master key) the seal is ignored and no seal is built. Throws `KeysLockedError` when
535
+ * `unlocked` was destroyed (`keySession.ts`), before evaluating anything, or if it is destroyed while sealing; otherwise
536
+ * never throws - a seal that can't be built (e.g. uids too long for the size limit) just leaves `sealToWrite` unset.
537
+ */
538
+ export async function evaluateMessageSecurityWithSeal(
539
+ rawMime: string,
540
+ unlocked: (MessageSecurityKeys & SealKeyMaterial) | undefined,
541
+ pinnedSignerFingerprints: string | string[] | undefined,
542
+ readerAddress: string | undefined,
543
+ options: VerificationSealOptions,
544
+ ): Promise<MessageSecurityResult> {
545
+ if (unlocked?.destroyed) {
546
+ throw new KeysLockedError();
547
+ }
548
+ const live = await evaluateLive(rawMime, unlocked, pinnedSignerFingerprints, readerAddress);
549
+ const { result } = live;
550
+ const isLiveVerified = LIVE_VERIFIED_STATES.includes(result.state) && !result.headerTamperDetected;
551
+ // Every verified and key-status result carries the signer fingerprint (a certificate was always resolved).
552
+ if (!unlocked || !result.signerFingerprint || (!isLiveVerified && !failedOnlyOnKeyStatus(result))) {
553
+ return result;
554
+ }
555
+
556
+ const rawSha256 = await rawMimeSha256(rawMime);
557
+ const generation = options.masterKeyGeneration;
558
+ const opened = options.seal ? await openVerificationSeal(options.mailboxUid, unlocked, options.messageUid, options.seal, rawSha256, generation) : undefined;
559
+ const signerFingerprint = result.signerFingerprint.toLowerCase();
560
+
561
+ if (isLiveVerified) {
562
+ const storedSealIsOlder = options.sealGeneration !== undefined && options.sealGeneration < generation;
563
+ if (opened && !storedSealIsOlder) {
564
+ return result;
565
+ }
566
+ try {
567
+ const seal = await buildVerificationSeal(options.mailboxUid, unlocked, {
568
+ messageUid: options.messageUid,
569
+ rawSha256,
570
+ signerFingerprint,
571
+ state: result.state as SealedVerificationState,
572
+ verifiedAt: options.now ?? Date.now(),
573
+ masterKeyGeneration: generation,
574
+ });
575
+ return { ...result, sealToWrite: { seal, masterKeyGeneration: generation } };
576
+ } catch (err) {
577
+ if (err instanceof KeysLockedError) {
578
+ throw err;
579
+ }
580
+ return result;
581
+ }
582
+ }
583
+
584
+ const expectedSealedState: SealedVerificationState = live.kind === "signed" ? "signed_verified" : "encrypted_verified";
585
+ if (!opened || opened.signerFingerprint !== signerFingerprint || opened.state !== expectedSealedState) {
586
+ return result;
587
+ }
588
+ const laterCompromised = (options.signerKeys ?? []).some((key) => key.fingerprint.toLowerCase() === signerFingerprint && !isTrustedForVerification(key));
589
+ const { signatureFailureReason, ...rest } = result;
590
+ return {
591
+ ...live.signedContent,
592
+ ...rest,
593
+ state: "verified_at_first_open",
594
+ verifiedAt: opened.verifiedAt,
595
+ sealedState: opened.state,
596
+ liveState: result.state,
597
+ ...(signatureFailureReason ? { liveSignatureFailureReason: signatureFailureReason } : {}),
598
+ ...(laterCompromised ? { laterCompromised: true } : {}),
599
+ };
600
+ }