@rapidmx/web-client 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -14
- package/apps/admin/_layout.tsx +2 -2
- package/apps/admin/audit-log/index.tsx +4 -4
- package/apps/admin/branding/index.tsx +3 -3
- package/apps/admin/data-requests/index.tsx +8 -8
- package/apps/admin/distribution-lists/[uid].tsx +3 -3
- package/apps/admin/distribution-lists/index.tsx +4 -4
- package/apps/admin/distribution-lists/new/index.tsx +5 -5
- package/apps/admin/domains/[uid].tsx +6 -6
- package/apps/admin/domains/index.tsx +4 -4
- package/apps/admin/domains/new/index.tsx +5 -5
- package/apps/admin/encryption-policy/index.tsx +1 -1
- package/apps/admin/escrow-scopes/[uid].tsx +7 -7
- package/apps/admin/escrow-scopes/index.tsx +4 -4
- package/apps/admin/escrow-scopes/new/index.tsx +5 -5
- package/apps/admin/index.tsx +6 -6
- package/apps/admin/ingest-queue/index.tsx +4 -4
- package/apps/admin/mailbox-policy/index.tsx +1 -1
- package/apps/admin/mailboxes/[uid].tsx +5 -5
- package/apps/admin/quarantine/index.tsx +5 -5
- package/apps/admin/retention-policy/index.tsx +3 -3
- package/apps/admin/signing-certificates/index.tsx +5 -5
- package/apps/admin/transport-rules/[uid].tsx +5 -5
- package/apps/admin/transport-rules/_transportRuleConfig.tsx +3 -3
- package/apps/admin/transport-rules/index.tsx +4 -4
- package/apps/admin/transport-rules/new/index.tsx +5 -5
- package/apps/escrow/_layout.tsx +1 -1
- package/apps/escrow/audit-log/index.tsx +4 -4
- package/apps/escrow/index.tsx +4 -4
- package/apps/escrow/matters/[uid].tsx +10 -10
- package/apps/escrow/matters/new/index.tsx +6 -6
- package/apps/shared/appearance/AppearanceForm.tsx +3 -3
- package/apps/shared/appearance/AppearanceHead.tsx +1 -1
- package/apps/shared/appearance/AppearanceProvider.tsx +3 -3
- package/apps/shared/appearance/appearanceCache.ts +1 -1
- package/apps/shared/appearance/appearanceContext.ts +1 -1
- package/apps/shared/appearance/theme.ts +1 -1
- package/apps/shared/auth/adminAccess.ts +1 -1
- package/apps/shared/calendar/bookingPlugin.ts +1 -1
- package/apps/shared/calendar/calendarLiveUpdates.ts +1 -1
- package/apps/shared/calendar/calendarReminders.ts +1 -1
- package/apps/shared/calendar/useCalendarReminders.ts +1 -1
- package/apps/shared/components/admin/diagnostics/DiagnosticsManager.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +2 -2
- package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +2 -2
- package/apps/shared/components/admin/diagnostics/PackagesTable.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +2 -2
- package/apps/shared/components/admin/diagnostics/VersionsPanel.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +1 -1
- package/apps/shared/components/admin/diagnostics/format.ts +1 -1
- package/apps/shared/components/admin/diagnostics/logClient.ts +1 -1
- package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
- package/apps/shared/components/admin/elevation.ts +1 -1
- package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +3 -3
- package/apps/shared/components/admin/layout/AdminShell.tsx +8 -8
- package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +6 -6
- package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +10 -8
- package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +4 -4
- package/apps/shared/components/admin/mailboxes/MailboxTable.tsx +1 -1
- package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +19 -14
- package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +5 -5
- package/apps/shared/components/admin/settings/BrandingForm.tsx +5 -5
- package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +5 -5
- package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +4 -4
- package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +2 -2
- package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +32 -27
- package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +4 -4
- package/apps/shared/components/admin/settings/PluginsManager.tsx +5 -5
- package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +5 -5
- package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +7 -7
- package/apps/shared/components/admin/setup/SetupWizard.tsx +28 -24
- package/apps/shared/components/admin/signOut.ts +1 -1
- package/apps/shared/components/admin/usePagedList.tsx +2 -2
- package/apps/shared/components/calendar/AppointmentQuickForm.tsx +3 -3
- package/apps/shared/components/calendar/CalendarListSidebar.tsx +3 -3
- package/apps/shared/components/calendar/DescriptionEditor.tsx +1 -1
- package/apps/shared/components/calendar/EventDescriptionView.tsx +1 -1
- package/apps/shared/components/calendar/EventDetails.tsx +16 -14
- package/apps/shared/components/calendar/EventEditor.tsx +54 -39
- package/apps/shared/components/calendar/EventExpandedForm.tsx +3 -3
- package/apps/shared/components/calendar/EventFormParts.tsx +2 -2
- package/apps/shared/components/calendar/EventModal.tsx +5 -5
- package/apps/shared/components/calendar/EventQuickForm.tsx +3 -3
- package/apps/shared/components/calendar/EventShell.tsx +1 -1
- package/apps/shared/components/calendar/FindATime.tsx +6 -4
- package/apps/shared/components/calendar/GuestInput.tsx +2 -2
- package/apps/shared/components/calendar/MonthView.tsx +2 -2
- package/apps/shared/components/calendar/QuickCreateFaces.tsx +1 -1
- package/apps/shared/components/calendar/QuickFaceFrame.tsx +1 -1
- package/apps/shared/components/calendar/RecurrenceEditor.tsx +2 -2
- package/apps/shared/components/calendar/RequestChangeForm.tsx +8 -6
- package/apps/shared/components/calendar/ResourcePicker.tsx +7 -5
- package/apps/shared/components/calendar/SplitDayView.tsx +1 -1
- package/apps/shared/components/calendar/TaskQuickForm.tsx +23 -18
- package/apps/shared/components/calendar/TimeGridView.tsx +5 -3
- package/apps/shared/components/calendar/allDay.ts +2 -2
- package/apps/shared/components/calendar/eventDialogFields.ts +3 -3
- package/apps/shared/components/calendar/eventForm.ts +3 -3
- package/apps/shared/components/calendar/eventFormat.ts +3 -3
- package/apps/shared/components/calendar/findTimeGrid.ts +2 -2
- package/apps/shared/components/calendar/layout/CalendarShell.tsx +11 -9
- package/apps/shared/components/contacts/ContactDetailPane.tsx +4 -4
- package/apps/shared/components/contacts/ContactForm.tsx +27 -17
- package/apps/shared/components/contacts/ContactsSidebar.tsx +7 -5
- package/apps/shared/components/contacts/KeyChangeReview.tsx +5 -5
- package/apps/shared/components/contacts/contactKeys.ts +3 -3
- package/apps/shared/components/contacts/layout/ContactsShell.tsx +9 -7
- package/apps/shared/components/escrow/layout/EscrowShell.tsx +6 -6
- package/apps/shared/components/forms/StringListField.tsx +1 -1
- package/apps/shared/components/layout/AppShell.tsx +12 -10
- package/apps/shared/components/layout/BrandingChrome.tsx +1 -1
- package/apps/shared/components/layout/KeyEnrollmentGate.tsx +9 -9
- package/apps/shared/components/layout/MailboxProvisioning.tsx +8 -6
- package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +9 -9
- package/apps/shared/components/layout/ThemeSwitch.tsx +1 -1
- package/apps/shared/components/layout/UnlockPromptProvider.tsx +6 -6
- package/apps/shared/components/layout/UserMenu.tsx +6 -4
- package/apps/shared/components/mail/ConversationList.tsx +25 -10
- package/apps/shared/components/mail/ConversationThreadPane.tsx +33 -17
- package/apps/shared/components/mail/InviteCard.tsx +11 -9
- package/apps/shared/components/mail/LazyReadingPane.tsx +2 -2
- package/apps/shared/components/mail/MailAddress.tsx +1 -1
- package/apps/shared/components/mail/MailListToolbar.tsx +2 -2
- package/apps/shared/components/mail/MailSelectionBar.tsx +2 -2
- package/apps/shared/components/mail/MenuButton.tsx +1 -1
- package/apps/shared/components/mail/MessageDetailPane.tsx +69 -48
- package/apps/shared/components/mail/MoveToFolderDialog.tsx +8 -6
- package/apps/shared/components/mail/OutboxRowStatus.tsx +1 -1
- package/apps/shared/components/mail/PermanentDeleteDialog.tsx +2 -2
- package/apps/shared/components/mail/compose/ComposeContext.tsx +14 -3
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +34 -30
- package/apps/shared/components/mail/compose/ComposeWindowPlaceholder.tsx +4 -4
- package/apps/shared/components/mail/compose/EmojiPicker.tsx +2 -2
- package/apps/shared/components/mail/compose/GifPicker.tsx +3 -3
- package/apps/shared/components/mail/compose/RecipientInput.tsx +1 -1
- package/apps/shared/components/mail/compose/ScheduleSendPicker.tsx +1 -1
- package/apps/shared/components/mail/compose/encryptionRequirement.ts +2 -2
- package/apps/shared/components/mail/compose/quotedBody.ts +5 -5
- package/apps/shared/components/mail/compose/recipients.ts +1 -1
- package/apps/shared/components/mail/invite/InviteRowChip.tsx +10 -14
- package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +11 -9
- package/apps/shared/components/mail/invite/InviteTimeline.tsx +1 -1
- package/apps/shared/components/mail/invite/ProposeTimeForm.tsx +2 -2
- package/apps/shared/components/mail/invite/inviteFormat.ts +2 -2
- package/apps/shared/components/mail/invite/inviteStore.ts +14 -6
- package/apps/shared/components/mail/labelMenu.tsx +9 -7
- package/apps/shared/components/mail/layout/MailShell.tsx +4 -4
- package/apps/shared/components/mail/listPreferences.ts +2 -2
- package/apps/shared/components/mail/pinnedSigners.ts +45 -19
- package/apps/shared/components/mail/reading/EncryptedBody.tsx +2 -2
- package/apps/shared/components/mail/reading/MessageBody.tsx +6 -6
- package/apps/shared/components/mail/reading/MessageCard.tsx +3 -3
- package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +3 -3
- package/apps/shared/components/mail/reading/PendingMessageCard.tsx +1 -1
- package/apps/shared/components/mail/reading/bodyContent.ts +3 -3
- package/apps/shared/components/mail/reading/bodyHtml.ts +1 -1
- package/apps/shared/components/mail/reading/conversationPrint.ts +76 -0
- package/apps/shared/components/mail/reading/messageExport.ts +1 -1
- package/apps/shared/components/mail/reading/printMessage.ts +46 -9
- package/apps/shared/components/mail/reading/useMessageActions.ts +28 -21
- package/apps/shared/components/mail/unreadStyle.tsx +1 -1
- package/apps/shared/components/mail/verificationSeals.ts +16 -12
- package/apps/shared/components/mail/writableMailboxes.ts +14 -7
- package/apps/shared/components/rules/RuleBuilder.tsx +1 -1
- package/apps/shared/components/settings/SigningCertificateCard.tsx +4 -4
- package/apps/shared/components/settings/layout/SettingsShell.tsx +8 -6
- package/apps/shared/components/sharing/PrincipalListField.tsx +1 -1
- package/apps/shared/components/sharing/PrincipalPicker.tsx +1 -1
- package/apps/shared/components/sharing/PrincipalResolver.tsx +4 -4
- package/apps/shared/components/tasks/TasksSidebar.tsx +7 -5
- package/apps/shared/components/tasks/layout/TasksShell.tsx +9 -7
- package/apps/shared/keyboard/ShortcutsDialog.tsx +1 -1
- package/apps/shared/keyboard/keymap.ts +1 -0
- package/apps/shared/mail/decryptedMessages.ts +116 -0
- package/apps/shared/mail/findWellKnownFolderUid.ts +6 -4
- package/apps/shared/mail/folderCounts.ts +8 -4
- package/apps/shared/mail/folderOfType.ts +5 -3
- package/apps/shared/mail/folderTree.ts +1 -1
- package/apps/shared/mail/listSnapshots.ts +2 -2
- package/apps/shared/mail/messageReadState.ts +6 -5
- package/apps/shared/mail/newMailNotifications.ts +2 -2
- package/apps/shared/mail/outbox/composeBridge.ts +2 -2
- package/apps/shared/mail/outbox/outboxState.ts +1 -1
- package/apps/shared/mail/outbox/outgoingReplies.ts +2 -2
- package/apps/shared/mail/outbox/sendDecision.ts +2 -2
- package/apps/shared/mail/outbox/sendJob.ts +40 -35
- package/apps/shared/mail/outbox/sendOutcomes.ts +20 -15
- package/apps/shared/mail/outbox/useOutboxStatus.ts +5 -3
- package/apps/shared/mail/permanentDelete.ts +8 -7
- package/apps/shared/mail/primaryMailbox.ts +1 -1
- package/apps/shared/mail/reportNotices.ts +1 -1
- package/apps/shared/mail/senderBlocking.ts +36 -20
- package/apps/shared/mail/useMailConnection.ts +12 -10
- package/apps/shared/mail/useMailLiveUpdates.ts +3 -3
- package/apps/shared/mail/useMailboxUpdateAccess.ts +35 -11
- package/apps/shared/mail/useMarkMessageRead.ts +14 -7
- package/apps/shared/mail/useNewMailNotifications.ts +1 -1
- package/apps/shared/mail/usePermanentDelete.tsx +5 -3
- package/apps/shared/navigation/pageTitle.ts +1 -1
- package/apps/shared/notifications/NotificationCenter.tsx +1 -1
- package/apps/shared/notifications/NotificationHistoryDialog.tsx +2 -2
- package/apps/shared/notifications/apiErrors.ts +2 -2
- package/apps/shared/notifications/pushStatus.ts +1 -1
- package/apps/shared/notifications/systemErrors.ts +1 -1
- package/apps/shared/search/LocalIndexLifecycle.tsx +18 -12
- package/apps/shared/search/crossMailboxSearch.ts +3 -3
- package/apps/shared/search/localIndexBuilder.ts +24 -12
- package/apps/shared/search/localIndexKey.ts +1 -1
- package/apps/shared/search/localIndexRpcClient.ts +150 -30
- package/apps/shared/search/localIndexTransport.ts +84 -0
- package/apps/shared/search/localIndexWorker.ts +1 -1
- package/apps/shared/search/searchTier2.ts +3 -3
- package/apps/shared/signing/enrollmentTracker.ts +3 -3
- package/apps/shared/signing/enrollmentView.ts +1 -1
- package/apps/shared/signing/signingInfo.ts +1 -1
- package/apps/shared/signing/useSigningEnrollmentWatcher.ts +6 -4
- package/apps/shared/styles/app.css +14 -23
- package/apps/www/_layout.tsx +2 -2
- package/apps/www/calendar/index.tsx +20 -18
- package/apps/www/contacts/[uid].tsx +8 -6
- package/apps/www/contacts/index.tsx +19 -17
- package/apps/www/index.tsx +68 -48
- package/apps/www/messages/[uid].tsx +11 -9
- package/apps/www/settings/auto-reply/index.tsx +6 -4
- package/apps/www/settings/blocked-senders/index.tsx +9 -7
- package/apps/www/settings/encryption/index.tsx +38 -32
- package/apps/www/settings/filters/[uid].tsx +19 -14
- package/apps/www/settings/filters/_mailFilterRuleConfig.tsx +2 -2
- package/apps/www/settings/filters/index.tsx +4 -4
- package/apps/www/settings/filters/new/index.tsx +10 -8
- package/apps/www/settings/labels/index.tsx +12 -10
- package/apps/www/settings/privacy/index.tsx +18 -14
- package/apps/www/settings/profile/index.tsx +16 -11
- package/apps/www/settings/read-receipts/index.tsx +17 -12
- package/apps/www/settings/sharing/index.tsx +6 -6
- package/apps/www/settings/signatures/[uid].tsx +5 -5
- package/apps/www/settings/signatures/index.tsx +4 -4
- package/apps/www/settings/signatures/new/index.tsx +4 -4
- package/apps/www/settings/signatures/signatureDefaults.ts +1 -1
- package/apps/www/tasks/index.tsx +28 -23
- package/dist/apps/admin/_layout.d.ts +1 -1
- package/dist/apps/admin/_layout.js +1 -1
- package/dist/apps/admin/audit-log/index.d.ts +1 -1
- package/dist/apps/admin/audit-log/index.js +4 -4
- package/dist/apps/admin/branding/index.js +3 -3
- package/dist/apps/admin/data-requests/index.js +8 -8
- package/dist/apps/admin/distribution-lists/[uid].js +3 -3
- package/dist/apps/admin/distribution-lists/index.js +4 -4
- package/dist/apps/admin/distribution-lists/new/index.js +5 -5
- package/dist/apps/admin/domains/[uid].js +6 -6
- package/dist/apps/admin/domains/index.js +4 -4
- package/dist/apps/admin/domains/new/index.js +5 -5
- package/dist/apps/admin/encryption-policy/index.js +1 -1
- package/dist/apps/admin/escrow-scopes/[uid].d.ts +1 -1
- package/dist/apps/admin/escrow-scopes/[uid].js +7 -7
- package/dist/apps/admin/escrow-scopes/index.js +4 -4
- package/dist/apps/admin/escrow-scopes/new/index.js +5 -5
- package/dist/apps/admin/index.js +6 -6
- package/dist/apps/admin/ingest-queue/index.js +4 -4
- package/dist/apps/admin/mailbox-policy/index.js +1 -1
- package/dist/apps/admin/mailboxes/[uid].js +5 -5
- package/dist/apps/admin/quarantine/index.js +5 -5
- package/dist/apps/admin/retention-policy/index.js +3 -3
- package/dist/apps/admin/signing-certificates/index.js +5 -5
- package/dist/apps/admin/transport-rules/[uid].js +5 -5
- package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +1 -1
- package/dist/apps/admin/transport-rules/_transportRuleConfig.js +2 -2
- package/dist/apps/admin/transport-rules/index.js +4 -4
- package/dist/apps/admin/transport-rules/new/index.js +5 -5
- package/dist/apps/escrow/_layout.d.ts +1 -1
- package/dist/apps/escrow/audit-log/index.d.ts +1 -1
- package/dist/apps/escrow/audit-log/index.js +4 -4
- package/dist/apps/escrow/index.js +4 -4
- package/dist/apps/escrow/matters/[uid].js +10 -10
- package/dist/apps/escrow/matters/new/index.js +6 -6
- package/dist/apps/shared/appearance/AppearanceForm.js +3 -3
- package/dist/apps/shared/appearance/AppearanceHead.js +1 -1
- package/dist/apps/shared/appearance/AppearanceProvider.d.ts +1 -1
- package/dist/apps/shared/appearance/AppearanceProvider.js +3 -3
- package/dist/apps/shared/appearance/appearanceCache.d.ts +1 -1
- package/dist/apps/shared/appearance/appearanceCache.js +1 -1
- package/dist/apps/shared/appearance/appearanceContext.d.ts +1 -1
- package/dist/apps/shared/appearance/theme.d.ts +1 -1
- package/dist/apps/shared/auth/adminAccess.js +1 -1
- package/dist/apps/shared/calendar/bookingPlugin.js +1 -1
- package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +1 -1
- package/dist/apps/shared/calendar/calendarReminders.d.ts +1 -1
- package/dist/apps/shared/calendar/useCalendarReminders.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/DiagnosticsManager.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.d.ts +1 -1
- package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +2 -2
- package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +2 -2
- package/dist/apps/shared/components/admin/diagnostics/PackagesTable.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +2 -2
- package/dist/apps/shared/components/admin/diagnostics/VersionsPanel.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/format.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/logClient.js +1 -1
- package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +1 -1
- package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
- package/dist/apps/shared/components/admin/elevation.js +1 -1
- package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +3 -3
- package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +1 -1
- package/dist/apps/shared/components/admin/layout/AdminShell.js +7 -7
- package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.d.ts +1 -1
- package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +6 -6
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +1 -1
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +10 -8
- package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
- package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +1 -1
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +1 -1
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +7 -5
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +5 -5
- package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/BrandingForm.js +5 -5
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +5 -5
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +4 -4
- package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +2 -2
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +14 -12
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +4 -4
- package/dist/apps/shared/components/admin/settings/PluginsManager.js +5 -5
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +1 -1
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +5 -5
- package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +7 -7
- package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +4 -4
- package/dist/apps/shared/components/admin/setup/SetupWizard.js +27 -23
- package/dist/apps/shared/components/admin/signOut.js +1 -1
- package/dist/apps/shared/components/admin/usePagedList.js +2 -2
- package/dist/apps/shared/components/calendar/AppointmentQuickForm.js +3 -3
- package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +1 -1
- package/dist/apps/shared/components/calendar/CalendarListSidebar.js +2 -2
- package/dist/apps/shared/components/calendar/DescriptionEditor.js +1 -1
- package/dist/apps/shared/components/calendar/EventDescriptionView.js +1 -1
- package/dist/apps/shared/components/calendar/EventDetails.d.ts +2 -2
- package/dist/apps/shared/components/calendar/EventDetails.js +16 -14
- package/dist/apps/shared/components/calendar/EventEditor.d.ts +2 -2
- package/dist/apps/shared/components/calendar/EventEditor.js +22 -20
- package/dist/apps/shared/components/calendar/EventExpandedForm.js +2 -2
- package/dist/apps/shared/components/calendar/EventFormParts.d.ts +1 -1
- package/dist/apps/shared/components/calendar/EventFormParts.js +1 -1
- package/dist/apps/shared/components/calendar/EventModal.d.ts +2 -2
- package/dist/apps/shared/components/calendar/EventModal.js +3 -3
- package/dist/apps/shared/components/calendar/EventQuickForm.js +3 -3
- package/dist/apps/shared/components/calendar/EventShell.js +1 -1
- package/dist/apps/shared/components/calendar/FindATime.js +6 -4
- package/dist/apps/shared/components/calendar/GuestInput.d.ts +2 -2
- package/dist/apps/shared/components/calendar/MonthView.d.ts +1 -1
- package/dist/apps/shared/components/calendar/MonthView.js +1 -1
- package/dist/apps/shared/components/calendar/QuickCreateFaces.js +1 -1
- package/dist/apps/shared/components/calendar/QuickFaceFrame.js +1 -1
- package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +1 -1
- package/dist/apps/shared/components/calendar/RecurrenceEditor.js +1 -1
- package/dist/apps/shared/components/calendar/RequestChangeForm.js +8 -6
- package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +1 -1
- package/dist/apps/shared/components/calendar/ResourcePicker.js +7 -5
- package/dist/apps/shared/components/calendar/SplitDayView.d.ts +1 -1
- package/dist/apps/shared/components/calendar/TaskQuickForm.d.ts +1 -1
- package/dist/apps/shared/components/calendar/TaskQuickForm.js +9 -7
- package/dist/apps/shared/components/calendar/TimeGridView.d.ts +1 -1
- package/dist/apps/shared/components/calendar/TimeGridView.js +2 -2
- package/dist/apps/shared/components/calendar/allDay.d.ts +2 -2
- package/dist/apps/shared/components/calendar/allDay.js +1 -1
- package/dist/apps/shared/components/calendar/eventDialogFields.d.ts +2 -2
- package/dist/apps/shared/components/calendar/eventDialogFields.js +2 -2
- package/dist/apps/shared/components/calendar/eventForm.d.ts +3 -3
- package/dist/apps/shared/components/calendar/eventFormat.d.ts +1 -1
- package/dist/apps/shared/components/calendar/eventFormat.js +2 -2
- package/dist/apps/shared/components/calendar/findTimeGrid.d.ts +1 -1
- package/dist/apps/shared/components/calendar/findTimeGrid.js +1 -1
- package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +1 -1
- package/dist/apps/shared/components/calendar/layout/CalendarShell.js +11 -9
- package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +1 -1
- package/dist/apps/shared/components/contacts/ContactDetailPane.js +2 -2
- package/dist/apps/shared/components/contacts/ContactForm.d.ts +2 -2
- package/dist/apps/shared/components/contacts/ContactForm.js +12 -8
- package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +1 -1
- package/dist/apps/shared/components/contacts/ContactsSidebar.js +7 -5
- package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +1 -1
- package/dist/apps/shared/components/contacts/KeyChangeReview.js +5 -5
- package/dist/apps/shared/components/contacts/contactKeys.d.ts +2 -2
- package/dist/apps/shared/components/contacts/contactKeys.js +2 -2
- package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +1 -1
- package/dist/apps/shared/components/contacts/layout/ContactsShell.js +9 -7
- package/dist/apps/shared/components/escrow/layout/EscrowShell.js +6 -6
- package/dist/apps/shared/components/forms/StringListField.js +1 -1
- package/dist/apps/shared/components/layout/AppShell.d.ts +2 -2
- package/dist/apps/shared/components/layout/AppShell.js +11 -9
- package/dist/apps/shared/components/layout/BrandingChrome.d.ts +1 -1
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +1 -1
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +9 -9
- package/dist/apps/shared/components/layout/MailboxProvisioning.js +8 -6
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +1 -1
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +9 -9
- package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +2 -2
- package/dist/apps/shared/components/layout/UnlockPromptProvider.js +5 -5
- package/dist/apps/shared/components/layout/UserMenu.js +6 -4
- package/dist/apps/shared/components/mail/ConversationList.d.ts +2 -2
- package/dist/apps/shared/components/mail/ConversationList.js +23 -8
- package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +3 -3
- package/dist/apps/shared/components/mail/ConversationThreadPane.js +19 -13
- package/dist/apps/shared/components/mail/InviteCard.js +10 -8
- package/dist/apps/shared/components/mail/LazyReadingPane.js +2 -2
- package/dist/apps/shared/components/mail/MailAddress.d.ts +1 -1
- package/dist/apps/shared/components/mail/MailAddress.js +1 -1
- package/dist/apps/shared/components/mail/MailListToolbar.d.ts +2 -2
- package/dist/apps/shared/components/mail/MailSelectionBar.d.ts +2 -2
- package/dist/apps/shared/components/mail/MenuButton.js +1 -1
- package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +3 -3
- package/dist/apps/shared/components/mail/MessageDetailPane.js +61 -46
- package/dist/apps/shared/components/mail/MoveToFolderDialog.d.ts +1 -1
- package/dist/apps/shared/components/mail/MoveToFolderDialog.js +8 -6
- package/dist/apps/shared/components/mail/OutboxRowStatus.d.ts +1 -1
- package/dist/apps/shared/components/mail/PermanentDeleteDialog.js +2 -2
- package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +10 -1
- package/dist/apps/shared/components/mail/compose/ComposeContext.js +4 -2
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +34 -30
- package/dist/apps/shared/components/mail/compose/ComposeWindowPlaceholder.js +4 -4
- package/dist/apps/shared/components/mail/compose/EmojiPicker.js +2 -2
- package/dist/apps/shared/components/mail/compose/GifPicker.js +3 -3
- package/dist/apps/shared/components/mail/compose/RecipientInput.d.ts +1 -1
- package/dist/apps/shared/components/mail/compose/RecipientInput.js +1 -1
- package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.js +1 -1
- package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +2 -2
- package/dist/apps/shared/components/mail/compose/encryptionRequirement.js +1 -1
- package/dist/apps/shared/components/mail/compose/quotedBody.d.ts +3 -3
- package/dist/apps/shared/components/mail/compose/quotedBody.js +3 -3
- package/dist/apps/shared/components/mail/compose/recipients.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/InviteRowChip.d.ts +3 -3
- package/dist/apps/shared/components/mail/invite/InviteRowChip.js +7 -9
- package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +2 -2
- package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +11 -9
- package/dist/apps/shared/components/mail/invite/InviteTimeline.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/ProposeTimeForm.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/ProposeTimeForm.js +1 -1
- package/dist/apps/shared/components/mail/invite/inviteFormat.d.ts +2 -2
- package/dist/apps/shared/components/mail/invite/inviteStore.d.ts +9 -3
- package/dist/apps/shared/components/mail/invite/inviteStore.js +13 -6
- package/dist/apps/shared/components/mail/labelMenu.d.ts +1 -1
- package/dist/apps/shared/components/mail/labelMenu.js +9 -7
- package/dist/apps/shared/components/mail/layout/MailShell.d.ts +1 -1
- package/dist/apps/shared/components/mail/layout/MailShell.js +3 -3
- package/dist/apps/shared/components/mail/listPreferences.d.ts +2 -2
- package/dist/apps/shared/components/mail/listPreferences.js +1 -1
- package/dist/apps/shared/components/mail/pinnedSigners.d.ts +12 -5
- package/dist/apps/shared/components/mail/pinnedSigners.js +37 -18
- package/dist/apps/shared/components/mail/reading/EncryptedBody.js +2 -2
- package/dist/apps/shared/components/mail/reading/MessageBody.d.ts +2 -2
- package/dist/apps/shared/components/mail/reading/MessageBody.js +4 -4
- package/dist/apps/shared/components/mail/reading/MessageCard.d.ts +1 -1
- package/dist/apps/shared/components/mail/reading/MessageCard.js +2 -2
- package/dist/apps/shared/components/mail/reading/MessageSourceDialog.js +3 -3
- package/dist/apps/shared/components/mail/reading/PendingMessageCard.js +1 -1
- package/dist/apps/shared/components/mail/reading/bodyContent.d.ts +2 -2
- package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -2
- package/dist/apps/shared/components/mail/reading/bodyHtml.js +1 -1
- package/dist/apps/shared/components/mail/reading/conversationPrint.d.ts +15 -0
- package/dist/apps/shared/components/mail/reading/conversationPrint.js +69 -0
- package/dist/apps/shared/components/mail/reading/messageExport.js +1 -1
- package/dist/apps/shared/components/mail/reading/printMessage.d.ts +9 -3
- package/dist/apps/shared/components/mail/reading/printMessage.js +33 -6
- package/dist/apps/shared/components/mail/reading/useMessageActions.d.ts +1 -1
- package/dist/apps/shared/components/mail/reading/useMessageActions.js +18 -16
- package/dist/apps/shared/components/mail/unreadStyle.d.ts +1 -1
- package/dist/apps/shared/components/mail/verificationSeals.d.ts +27 -6
- package/dist/apps/shared/components/mail/verificationSeals.js +15 -11
- package/dist/apps/shared/components/mail/writableMailboxes.d.ts +8 -3
- package/dist/apps/shared/components/mail/writableMailboxes.js +12 -6
- package/dist/apps/shared/components/rules/RuleBuilder.js +1 -1
- package/dist/apps/shared/components/settings/SigningCertificateCard.d.ts +1 -1
- package/dist/apps/shared/components/settings/SigningCertificateCard.js +3 -3
- package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +1 -1
- package/dist/apps/shared/components/settings/layout/SettingsShell.js +8 -6
- package/dist/apps/shared/components/sharing/PrincipalListField.d.ts +1 -1
- package/dist/apps/shared/components/sharing/PrincipalPicker.d.ts +1 -1
- package/dist/apps/shared/components/sharing/PrincipalPicker.js +1 -1
- package/dist/apps/shared/components/sharing/PrincipalResolver.d.ts +1 -1
- package/dist/apps/shared/components/sharing/PrincipalResolver.js +3 -3
- package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +1 -1
- package/dist/apps/shared/components/tasks/TasksSidebar.js +7 -5
- package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +1 -1
- package/dist/apps/shared/components/tasks/layout/TasksShell.js +9 -7
- package/dist/apps/shared/keyboard/ShortcutsDialog.js +1 -1
- package/dist/apps/shared/keyboard/keymap.d.ts +6 -0
- package/dist/apps/shared/keyboard/keymap.js +1 -0
- package/dist/apps/shared/mail/decryptedMessages.d.ts +27 -0
- package/dist/apps/shared/mail/decryptedMessages.js +97 -0
- package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -3
- package/dist/apps/shared/mail/findWellKnownFolderUid.js +5 -4
- package/dist/apps/shared/mail/folderCounts.d.ts +1 -1
- package/dist/apps/shared/mail/folderCounts.js +6 -4
- package/dist/apps/shared/mail/folderOfType.d.ts +3 -2
- package/dist/apps/shared/mail/folderOfType.js +4 -4
- package/dist/apps/shared/mail/folderTree.d.ts +1 -1
- package/dist/apps/shared/mail/listSnapshots.d.ts +2 -2
- package/dist/apps/shared/mail/messageReadState.d.ts +4 -3
- package/dist/apps/shared/mail/messageReadState.js +5 -5
- package/dist/apps/shared/mail/newMailNotifications.d.ts +1 -1
- package/dist/apps/shared/mail/newMailNotifications.js +1 -1
- package/dist/apps/shared/mail/outbox/composeBridge.d.ts +2 -2
- package/dist/apps/shared/mail/outbox/outboxState.d.ts +1 -1
- package/dist/apps/shared/mail/outbox/outgoingReplies.d.ts +2 -2
- package/dist/apps/shared/mail/outbox/sendDecision.d.ts +2 -2
- package/dist/apps/shared/mail/outbox/sendDecision.js +1 -1
- package/dist/apps/shared/mail/outbox/sendJob.d.ts +10 -6
- package/dist/apps/shared/mail/outbox/sendJob.js +39 -35
- package/dist/apps/shared/mail/outbox/sendOutcomes.d.ts +6 -3
- package/dist/apps/shared/mail/outbox/sendOutcomes.js +19 -15
- package/dist/apps/shared/mail/outbox/useOutboxStatus.js +5 -3
- package/dist/apps/shared/mail/permanentDelete.d.ts +4 -3
- package/dist/apps/shared/mail/permanentDelete.js +8 -8
- package/dist/apps/shared/mail/primaryMailbox.d.ts +1 -1
- package/dist/apps/shared/mail/primaryMailbox.js +1 -1
- package/dist/apps/shared/mail/reportNotices.d.ts +1 -1
- package/dist/apps/shared/mail/senderBlocking.d.ts +5 -4
- package/dist/apps/shared/mail/senderBlocking.js +19 -16
- package/dist/apps/shared/mail/useMailConnection.d.ts +1 -1
- package/dist/apps/shared/mail/useMailConnection.js +12 -10
- package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +2 -2
- package/dist/apps/shared/mail/useMailLiveUpdates.js +2 -2
- package/dist/apps/shared/mail/useMailboxUpdateAccess.d.ts +3 -2
- package/dist/apps/shared/mail/useMailboxUpdateAccess.js +31 -10
- package/dist/apps/shared/mail/useMarkMessageRead.d.ts +1 -1
- package/dist/apps/shared/mail/useMarkMessageRead.js +5 -3
- package/dist/apps/shared/mail/useNewMailNotifications.d.ts +1 -1
- package/dist/apps/shared/mail/usePermanentDelete.d.ts +1 -1
- package/dist/apps/shared/mail/usePermanentDelete.js +4 -2
- package/dist/apps/shared/navigation/pageTitle.d.ts +1 -1
- package/dist/apps/shared/notifications/NotificationCenter.js +1 -1
- package/dist/apps/shared/notifications/NotificationHistoryDialog.js +2 -2
- package/dist/apps/shared/notifications/apiErrors.js +2 -2
- package/dist/apps/shared/notifications/pushStatus.js +1 -1
- package/dist/apps/shared/notifications/systemErrors.js +1 -1
- package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +2 -2
- package/dist/apps/shared/search/LocalIndexLifecycle.js +15 -10
- package/dist/apps/shared/search/crossMailboxSearch.d.ts +1 -1
- package/dist/apps/shared/search/crossMailboxSearch.js +2 -2
- package/dist/apps/shared/search/localIndexBuilder.d.ts +4 -3
- package/dist/apps/shared/search/localIndexBuilder.js +15 -12
- package/dist/apps/shared/search/localIndexKey.js +1 -1
- package/dist/apps/shared/search/localIndexRpcClient.d.ts +43 -31
- package/dist/apps/shared/search/localIndexRpcClient.js +113 -20
- package/dist/apps/shared/search/localIndexTransport.d.ts +77 -0
- package/dist/apps/shared/search/localIndexTransport.js +1 -0
- package/dist/apps/shared/search/localIndexWorker.d.ts +1 -1
- package/dist/apps/shared/search/searchTier2.d.ts +3 -3
- package/dist/apps/shared/signing/enrollmentTracker.d.ts +1 -1
- package/dist/apps/shared/signing/enrollmentTracker.js +3 -3
- package/dist/apps/shared/signing/enrollmentView.d.ts +1 -1
- package/dist/apps/shared/signing/signingInfo.d.ts +1 -1
- package/dist/apps/shared/signing/signingInfo.js +1 -1
- package/dist/apps/shared/signing/useSigningEnrollmentWatcher.d.ts +1 -1
- package/dist/apps/shared/signing/useSigningEnrollmentWatcher.js +5 -3
- package/dist/apps/shared/styles/app.css +14 -23
- package/dist/apps/www/_layout.d.ts +1 -1
- package/dist/apps/www/_layout.js +1 -1
- package/dist/apps/www/calendar/index.d.ts +1 -1
- package/dist/apps/www/calendar/index.js +20 -18
- package/dist/apps/www/contacts/[uid].d.ts +1 -1
- package/dist/apps/www/contacts/[uid].js +8 -6
- package/dist/apps/www/contacts/index.d.ts +1 -1
- package/dist/apps/www/contacts/index.js +19 -17
- package/dist/apps/www/index.d.ts +1 -1
- package/dist/apps/www/index.js +64 -50
- package/dist/apps/www/messages/[uid].d.ts +1 -1
- package/dist/apps/www/messages/[uid].js +11 -9
- package/dist/apps/www/settings/appearance/index.d.ts +1 -1
- package/dist/apps/www/settings/auto-reply/index.d.ts +1 -1
- package/dist/apps/www/settings/auto-reply/index.js +6 -4
- package/dist/apps/www/settings/blocked-senders/index.d.ts +1 -1
- package/dist/apps/www/settings/blocked-senders/index.js +6 -4
- package/dist/apps/www/settings/encryption/index.d.ts +1 -1
- package/dist/apps/www/settings/encryption/index.js +31 -29
- package/dist/apps/www/settings/filters/[uid].d.ts +1 -1
- package/dist/apps/www/settings/filters/[uid].js +11 -9
- package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +2 -2
- package/dist/apps/www/settings/filters/index.d.ts +1 -1
- package/dist/apps/www/settings/filters/index.js +4 -4
- package/dist/apps/www/settings/filters/new/index.d.ts +1 -1
- package/dist/apps/www/settings/filters/new/index.js +10 -8
- package/dist/apps/www/settings/labels/index.d.ts +1 -1
- package/dist/apps/www/settings/labels/index.js +12 -10
- package/dist/apps/www/settings/privacy/index.d.ts +1 -1
- package/dist/apps/www/settings/privacy/index.js +18 -14
- package/dist/apps/www/settings/profile/index.d.ts +1 -1
- package/dist/apps/www/settings/profile/index.js +7 -5
- package/dist/apps/www/settings/read-receipts/index.d.ts +1 -1
- package/dist/apps/www/settings/read-receipts/index.js +5 -3
- package/dist/apps/www/settings/sharing/index.d.ts +1 -1
- package/dist/apps/www/settings/sharing/index.js +6 -6
- package/dist/apps/www/settings/signatures/[uid].d.ts +1 -1
- package/dist/apps/www/settings/signatures/[uid].js +5 -5
- package/dist/apps/www/settings/signatures/index.d.ts +1 -1
- package/dist/apps/www/settings/signatures/index.js +4 -4
- package/dist/apps/www/settings/signatures/new/index.d.ts +1 -1
- package/dist/apps/www/settings/signatures/new/index.js +4 -4
- package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +1 -1
- package/dist/apps/www/settings/signatures/signatureDefaults.js +1 -1
- package/dist/apps/www/tasks/index.d.ts +1 -1
- package/dist/apps/www/tasks/index.js +17 -15
- package/dist/lib/admin/auditLogApi.d.ts +32 -0
- package/dist/lib/admin/auditLogApi.js +27 -0
- package/dist/lib/admin/distributionListsApi.d.ts +47 -0
- package/dist/lib/admin/distributionListsApi.js +34 -0
- package/dist/lib/admin/domainsApi.d.ts +75 -0
- package/dist/lib/admin/domainsApi.js +44 -0
- package/dist/lib/admin/escrowAccessRequestsApi.d.ts +79 -0
- package/dist/lib/admin/escrowAccessRequestsApi.js +46 -0
- package/dist/lib/admin/escrowAuditLogApi.d.ts +66 -0
- package/dist/lib/admin/escrowAuditLogApi.js +31 -0
- package/dist/lib/admin/escrowScopesApi.d.ts +78 -0
- package/dist/lib/admin/escrowScopesApi.js +50 -0
- package/dist/lib/admin/leftoverMailboxApi.d.ts +73 -0
- package/dist/lib/admin/leftoverMailboxApi.js +67 -0
- package/dist/lib/admin/mailboxPolicyApi.d.ts +27 -0
- package/dist/lib/admin/mailboxPolicyApi.js +21 -0
- package/dist/lib/admin/matterExportApi.d.ts +40 -0
- package/dist/lib/admin/matterExportApi.js +39 -0
- package/dist/lib/admin/matterSearchApi.d.ts +20 -0
- package/dist/lib/admin/matterSearchApi.js +27 -0
- package/dist/lib/admin/mattersApi.d.ts +56 -0
- package/dist/lib/admin/mattersApi.js +40 -0
- package/dist/lib/admin/pluginsApi.d.ts +265 -0
- package/dist/lib/admin/pluginsApi.js +102 -0
- package/dist/lib/admin/retentionPolicyApi.d.ts +32 -0
- package/dist/lib/admin/retentionPolicyApi.js +29 -0
- package/dist/lib/admin/setupApi.d.ts +23 -0
- package/dist/lib/admin/setupApi.js +26 -0
- package/dist/lib/admin/transportRulesApi.d.ts +66 -0
- package/dist/lib/admin/transportRulesApi.js +43 -0
- package/dist/lib/appearance/preferencesApi.d.ts +128 -0
- package/dist/lib/appearance/preferencesApi.js +257 -0
- package/dist/lib/auth/profileApi.d.ts +33 -0
- package/dist/lib/auth/profileApi.js +52 -0
- package/dist/lib/auth/session.d.ts +70 -0
- package/dist/lib/auth/session.js +210 -0
- package/dist/lib/branding/brandingApi.d.ts +47 -0
- package/dist/lib/branding/brandingApi.js +61 -0
- package/dist/lib/branding/useBranding.d.ts +23 -0
- package/dist/lib/branding/useBranding.js +65 -0
- package/dist/lib/calendar/calendarApi.d.ts +230 -0
- package/dist/lib/calendar/calendarApi.js +106 -0
- package/dist/lib/calendar/calendarColors.d.ts +18 -0
- package/dist/lib/calendar/calendarColors.js +39 -0
- package/dist/lib/calendar/calendarDragIds.d.ts +42 -0
- package/dist/lib/calendar/calendarDragIds.js +92 -0
- package/dist/lib/calendar/calendarMutations.d.ts +68 -0
- package/dist/lib/calendar/calendarMutations.js +190 -0
- package/dist/lib/calendar/eventDescription.d.ts +43 -0
- package/dist/lib/calendar/eventDescription.js +195 -0
- package/dist/lib/calendar/freeBusyApi.d.ts +100 -0
- package/dist/lib/calendar/freeBusyApi.js +119 -0
- package/dist/lib/calendar/inviteApi.d.ts +121 -0
- package/dist/lib/calendar/inviteApi.js +54 -0
- package/dist/lib/calendar/recurrence.d.ts +60 -0
- package/dist/lib/calendar/recurrence.js +225 -0
- package/dist/lib/components/avatar/ContactAvatar.d.ts +8 -0
- package/dist/lib/components/avatar/ContactAvatar.js +26 -0
- package/dist/lib/components/buttons/Button.d.ts +9 -0
- package/dist/lib/components/buttons/Button.js +14 -0
- package/dist/lib/components/buttons/CopyButton.d.ts +18 -0
- package/dist/lib/components/buttons/CopyButton.js +14 -0
- package/dist/lib/components/feedback/Alert.d.ts +4 -0
- package/dist/lib/components/feedback/Alert.js +4 -0
- package/dist/lib/components/feedback/Skeleton.d.ts +21 -0
- package/dist/lib/components/feedback/Skeleton.js +14 -0
- package/dist/lib/components/forms/FormField.d.ts +8 -0
- package/dist/lib/components/forms/FormField.js +5 -0
- package/dist/lib/components/navigation/BottomTabBar.d.ts +27 -0
- package/dist/lib/components/navigation/BottomTabBar.js +32 -0
- package/dist/lib/components/overlays/Drawer.d.ts +20 -0
- package/dist/lib/components/overlays/Drawer.js +27 -0
- package/dist/lib/components/overlays/Modal.d.ts +17 -0
- package/dist/lib/components/overlays/Modal.js +25 -0
- package/dist/lib/components/overlays/PopoverPortal.d.ts +23 -0
- package/dist/lib/components/overlays/PopoverPortal.js +53 -0
- package/dist/lib/components/overlays/overlayStack.d.ts +31 -0
- package/dist/lib/components/overlays/overlayStack.js +143 -0
- package/dist/lib/components/pickers/MiniDatePicker.d.ts +13 -0
- package/dist/lib/components/pickers/MiniDatePicker.js +42 -0
- package/dist/lib/contacts/contactsApi.d.ts +174 -0
- package/dist/lib/contacts/contactsApi.js +139 -0
- package/dist/lib/contacts/vcard.d.ts +23 -0
- package/dist/lib/contacts/vcard.js +179 -0
- package/dist/lib/crypto/composeSecurity.d.ts +67 -0
- package/dist/lib/crypto/composeSecurity.js +93 -0
- package/dist/lib/crypto/encoding.d.ts +9 -0
- package/dist/lib/crypto/encoding.js +32 -0
- package/dist/lib/crypto/escrowKeys.d.ts +25 -0
- package/dist/lib/crypto/escrowKeys.js +59 -0
- package/dist/lib/crypto/idleTimeout.d.ts +16 -0
- package/dist/lib/crypto/idleTimeout.js +47 -0
- package/dist/lib/crypto/keySession.d.ts +159 -0
- package/dist/lib/crypto/keySession.js +367 -0
- package/dist/lib/crypto/keys.d.ts +50 -0
- package/dist/lib/crypto/keys.js +89 -0
- package/dist/lib/crypto/keyvaultApi.d.ts +394 -0
- package/dist/lib/crypto/keyvaultApi.js +350 -0
- package/dist/lib/crypto/masterKey.d.ts +59 -0
- package/dist/lib/crypto/masterKey.js +104 -0
- package/dist/lib/crypto/masterKeyWraps.d.ts +108 -0
- package/dist/lib/crypto/masterKeyWraps.js +228 -0
- package/dist/lib/crypto/messageSecurity.d.ts +248 -0
- package/dist/lib/crypto/messageSecurity.js +367 -0
- package/dist/lib/crypto/mime.d.ts +143 -0
- package/dist/lib/crypto/mime.js +504 -0
- package/dist/lib/crypto/passkeyUnlock.d.ts +20 -0
- package/dist/lib/crypto/passkeyUnlock.js +79 -0
- package/dist/lib/crypto/passwordUnlock.d.ts +39 -0
- package/dist/lib/crypto/passwordUnlock.js +73 -0
- package/dist/lib/crypto/recoveryCode.d.ts +28 -0
- package/dist/lib/crypto/recoveryCode.js +86 -0
- package/dist/lib/crypto/signingProviderApi.d.ts +95 -0
- package/dist/lib/crypto/signingProviderApi.js +60 -0
- package/dist/lib/crypto/smime.d.ts +128 -0
- package/dist/lib/crypto/smime.js +402 -0
- package/dist/lib/crypto/smimeMessage.d.ts +132 -0
- package/dist/lib/crypto/smimeMessage.js +341 -0
- package/dist/lib/crypto/useIdleKeyTimeout.d.ts +10 -0
- package/dist/lib/crypto/useIdleKeyTimeout.js +163 -0
- package/dist/lib/crypto/verificationSeal.d.ts +56 -0
- package/dist/lib/crypto/verificationSeal.js +220 -0
- package/dist/lib/mail/compose/composeQuoting.d.ts +88 -0
- package/dist/lib/mail/compose/composeQuoting.js +204 -0
- package/dist/lib/mail/compose/emojiData.d.ts +9 -0
- package/dist/lib/mail/compose/emojiData.js +18 -0
- package/dist/lib/mail/compose/giphyApi.d.ts +17 -0
- package/dist/lib/mail/compose/giphyApi.js +20 -0
- package/dist/lib/mail/conversationsApi.d.ts +80 -0
- package/dist/lib/mail/conversationsApi.js +44 -0
- package/dist/lib/mail/dataExportApi.d.ts +50 -0
- package/dist/lib/mail/dataExportApi.js +40 -0
- package/dist/lib/mail/directoryApi.d.ts +49 -0
- package/dist/lib/mail/directoryApi.js +101 -0
- package/dist/lib/mail/erasureRequestApi.d.ts +45 -0
- package/dist/lib/mail/erasureRequestApi.js +43 -0
- package/dist/lib/mail/flaggedMessages.d.ts +22 -0
- package/dist/lib/mail/flaggedMessages.js +73 -0
- package/dist/lib/mail/focusedInboxOverridesApi.d.ts +37 -0
- package/dist/lib/mail/focusedInboxOverridesApi.js +34 -0
- package/dist/lib/mail/labelsApi.d.ts +47 -0
- package/dist/lib/mail/labelsApi.js +38 -0
- package/dist/lib/mail/mailAddress.d.ts +27 -0
- package/dist/lib/mail/mailAddress.js +54 -0
- package/dist/lib/mail/mailApi.d.ts +850 -0
- package/dist/lib/mail/mailApi.js +602 -0
- package/dist/lib/mail/mailDetailHooks.d.ts +10 -0
- package/dist/lib/mail/mailDetailHooks.js +53 -0
- package/dist/lib/mail/mailFilterRulesApi.d.ts +76 -0
- package/dist/lib/mail/mailFilterRulesApi.js +45 -0
- package/dist/lib/mail/mailSignaturesApi.d.ts +49 -0
- package/dist/lib/mail/mailSignaturesApi.js +42 -0
- package/dist/lib/mail/mailboxAccessApi.d.ts +74 -0
- package/dist/lib/mail/mailboxAccessApi.js +56 -0
- package/dist/lib/mail/mailboxImportApi.d.ts +53 -0
- package/dist/lib/mail/mailboxImportApi.js +51 -0
- package/dist/lib/mail/messageBodySanitizer.d.ts +16 -0
- package/dist/lib/mail/messageBodySanitizer.js +118 -0
- package/dist/lib/mail/pushClient.d.ts +106 -0
- package/dist/lib/mail/pushClient.js +317 -0
- package/dist/lib/mail/sendEvents.d.ts +33 -0
- package/dist/lib/mail/sendEvents.js +44 -0
- package/dist/lib/mail/sendFailure.d.ts +16 -0
- package/dist/lib/mail/sendFailure.js +86 -0
- package/dist/lib/mail/senderListsApi.d.ts +69 -0
- package/dist/lib/mail/senderListsApi.js +126 -0
- package/dist/lib/search/queryGrammar.d.ts +51 -0
- package/dist/lib/search/queryGrammar.js +111 -0
- package/dist/lib/search/searchApi.d.ts +100 -0
- package/dist/lib/search/searchApi.js +107 -0
- package/dist/lib/search/searchScoring.d.ts +34 -0
- package/dist/lib/search/searchScoring.js +44 -0
- package/dist/lib/search/searchTier3.d.ts +64 -0
- package/dist/lib/search/searchTier3.js +335 -0
- package/dist/lib/tasks/tasksApi.d.ts +85 -0
- package/dist/lib/tasks/tasksApi.js +55 -0
- package/dist/lib/util/api.d.ts +160 -0
- package/dist/lib/util/api.js +251 -0
- package/dist/lib/util/apiClientContext.d.ts +7 -0
- package/dist/lib/util/apiClientContext.js +32 -0
- package/dist/lib/util/apiQuery.d.ts +32 -0
- package/dist/lib/util/apiQuery.js +42 -0
- package/dist/lib/util/clipboard.d.ts +7 -0
- package/dist/lib/util/clipboard.js +56 -0
- package/dist/lib/util/dateInput.d.ts +6 -0
- package/dist/lib/util/dateInput.js +14 -0
- package/dist/lib/util/timeZone.d.ts +12 -0
- package/dist/lib/util/timeZone.js +32 -0
- package/dist/lib/util/useCopyToClipboard.d.ts +12 -0
- package/dist/lib/util/useCopyToClipboard.js +34 -0
- package/dist/lib/util/useIsMobile.d.ts +10 -0
- package/dist/lib/util/useIsMobile.js +29 -0
- package/dist/lib/videoconf/videoMeetingsApi.d.ts +116 -0
- package/dist/lib/videoconf/videoMeetingsApi.js +49 -0
- package/lib/admin/auditLogApi.ts +48 -0
- package/lib/admin/distributionListsApi.ts +77 -0
- package/lib/admin/domainsApi.ts +113 -0
- package/lib/admin/escrowAccessRequestsApi.ts +110 -0
- package/lib/admin/escrowAuditLogApi.ts +101 -0
- package/lib/admin/escrowScopesApi.ts +112 -0
- package/lib/admin/leftoverMailboxApi.ts +120 -0
- package/lib/admin/mailboxPolicyApi.ts +38 -0
- package/lib/admin/matterExportApi.ts +62 -0
- package/lib/admin/matterSearchApi.ts +35 -0
- package/lib/admin/mattersApi.ts +86 -0
- package/lib/admin/pluginsApi.ts +339 -0
- package/lib/admin/retentionPolicyApi.ts +46 -0
- package/lib/admin/setupApi.ts +40 -0
- package/lib/admin/transportRulesApi.ts +106 -0
- package/lib/appearance/preferencesApi.ts +335 -0
- package/lib/auth/profileApi.ts +77 -0
- package/lib/auth/session.ts +238 -0
- package/lib/branding/brandingApi.ts +97 -0
- package/lib/branding/useBranding.ts +81 -0
- package/lib/calendar/calendarApi.ts +309 -0
- package/lib/calendar/calendarColors.ts +45 -0
- package/lib/calendar/calendarDragIds.ts +112 -0
- package/lib/calendar/calendarMutations.ts +236 -0
- package/lib/calendar/eventDescription.ts +211 -0
- package/lib/calendar/freeBusyApi.ts +197 -0
- package/lib/calendar/inviteApi.ts +154 -0
- package/lib/calendar/recurrence.ts +285 -0
- package/lib/components/avatar/ContactAvatar.tsx +47 -0
- package/lib/components/buttons/Button.tsx +40 -0
- package/lib/components/buttons/CopyButton.tsx +45 -0
- package/lib/components/feedback/Alert.tsx +13 -0
- package/lib/components/feedback/Skeleton.tsx +38 -0
- package/lib/components/forms/FormField.tsx +23 -0
- package/lib/components/navigation/BottomTabBar.tsx +66 -0
- package/lib/components/overlays/Drawer.tsx +72 -0
- package/lib/components/overlays/Modal.tsx +64 -0
- package/lib/components/overlays/PopoverPortal.tsx +74 -0
- package/lib/components/overlays/overlayStack.ts +165 -0
- package/lib/components/pickers/MiniDatePicker.tsx +90 -0
- package/lib/contacts/contactsApi.ts +289 -0
- package/lib/contacts/vcard.ts +197 -0
- package/lib/crypto/composeSecurity.ts +140 -0
- package/lib/crypto/encoding.ts +36 -0
- package/lib/crypto/escrowKeys.ts +74 -0
- package/lib/crypto/idleTimeout.ts +49 -0
- package/lib/crypto/keySession.ts +483 -0
- package/lib/crypto/keys.ts +105 -0
- package/lib/crypto/keyvaultApi.ts +674 -0
- package/lib/crypto/masterKey.ts +134 -0
- package/lib/crypto/masterKeyWraps.ts +269 -0
- package/lib/crypto/messageSecurity.ts +600 -0
- package/lib/crypto/mime.ts +568 -0
- package/lib/crypto/passkeyUnlock.ts +103 -0
- package/lib/crypto/passwordUnlock.ts +98 -0
- package/lib/crypto/recoveryCode.ts +93 -0
- package/lib/crypto/signingProviderApi.ts +135 -0
- package/lib/crypto/smime.ts +459 -0
- package/lib/crypto/smimeMessage.ts +491 -0
- package/lib/crypto/useIdleKeyTimeout.ts +176 -0
- package/lib/crypto/verificationSeal.ts +288 -0
- package/lib/mail/compose/composeQuoting.ts +243 -0
- package/lib/mail/compose/emojiData.ts +34 -0
- package/lib/mail/compose/giphyApi.ts +31 -0
- package/lib/mail/conversationsApi.ts +123 -0
- package/lib/mail/dataExportApi.ts +73 -0
- package/lib/mail/directoryApi.ts +161 -0
- package/lib/mail/erasureRequestApi.ts +71 -0
- package/lib/mail/flaggedMessages.ts +80 -0
- package/lib/mail/focusedInboxOverridesApi.ts +64 -0
- package/lib/mail/labelsApi.ts +71 -0
- package/lib/mail/mailAddress.ts +76 -0
- package/lib/mail/mailApi.ts +1286 -0
- package/lib/mail/mailDetailHooks.ts +57 -0
- package/lib/mail/mailFilterRulesApi.ts +116 -0
- package/lib/mail/mailSignaturesApi.ts +84 -0
- package/lib/mail/mailboxAccessApi.ts +106 -0
- package/lib/mail/mailboxImportApi.ts +87 -0
- package/lib/mail/messageBodySanitizer.ts +129 -0
- package/lib/mail/pushClient.ts +375 -0
- package/lib/mail/sendEvents.ts +72 -0
- package/lib/mail/sendFailure.ts +98 -0
- package/lib/mail/senderListsApi.ts +161 -0
- package/lib/search/queryGrammar.ts +179 -0
- package/lib/search/searchApi.ts +199 -0
- package/lib/search/searchScoring.ts +46 -0
- package/lib/search/searchTier3.ts +406 -0
- package/lib/tasks/tasksApi.ts +128 -0
- package/lib/util/api.ts +318 -0
- package/lib/util/apiClientContext.ts +35 -0
- package/lib/util/apiQuery.ts +61 -0
- package/lib/util/clipboard.ts +55 -0
- package/lib/util/dateInput.ts +15 -0
- package/lib/util/timeZone.ts +33 -0
- package/lib/util/useCopyToClipboard.ts +48 -0
- package/lib/util/useIsMobile.ts +34 -0
- package/lib/videoconf/videoMeetingsApi.ts +144 -0
- package/package.json +10 -4
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
/**
|
|
6
|
+
* The CMS (S/MIME) engine behind `specs/end-to-end_encryption.md`'s "Message Format" requirement
|
|
7
|
+
* ("RapidMX MUST use S/MIME (CMS) as the on-the-wire message format for both signatures and
|
|
8
|
+
* encryption"). This module operates on raw CMS structures (`SignedData`/`EnvelopedData`) via
|
|
9
|
+
* `pkijs` — the actual MIME assembly (`multipart/signed`, RFC 9788 header protection, the
|
|
10
|
+
* `application/pkcs7-mime` wrapping) is a distinct, mechanical layer built on top of these
|
|
11
|
+
* primitives, not implemented here.
|
|
12
|
+
*
|
|
13
|
+
* Certificates are always the base64-decoded DER bytes — the same wire format
|
|
14
|
+
* `keyvaultApi.ts`'s `PublicKey.publicKey` already uses — never PEM, so this module composes
|
|
15
|
+
* directly with values read from a `Mailbox`/`Contact`'s `keys` array with no reformatting.
|
|
16
|
+
*/
|
|
17
|
+
import "reflect-metadata";
|
|
18
|
+
import * as asn1js from "asn1js";
|
|
19
|
+
import * as pkijs from "pkijs";
|
|
20
|
+
|
|
21
|
+
// Mirrors keys.ts's own WebCrypto engine setup - both @peculiar/x509 and pkijs need to be told which
|
|
22
|
+
// Crypto implementation to use; the browser/Electron renderer's own global `crypto` is exactly what
|
|
23
|
+
// both expect (unlike Node's global `crypto`, which @rapidmx/restapi's server-side code has to set up
|
|
24
|
+
// differently - see that repo's LocalX509CertificateAuthority.ts). The raw (`crypto`, `crypto.subtle`)
|
|
25
|
+
// three-argument form, not `new pkijs.CryptoEngine({...})` - pkijs's own `CryptoEngine` class doesn't
|
|
26
|
+
// actually satisfy its own `ICryptoEngine` interface (a real type-definition inconsistency in pkijs
|
|
27
|
+
// itself, confirmed via `tsc --noEmit`: `generateKey`'s Ed25519/X25519 overloads don't line up between
|
|
28
|
+
// the two), so passing an instance of it here fails to compile even though it works at runtime.
|
|
29
|
+
pkijs.setEngine("rapidmx", crypto, crypto.subtle);
|
|
30
|
+
|
|
31
|
+
/** SHA-256 detached signatures throughout, matching this system's hash-algorithm default everywhere
|
|
32
|
+
* else (fingerprints, HKDF). */
|
|
33
|
+
const DIGEST_ALGORITHM = "SHA-256";
|
|
34
|
+
|
|
35
|
+
/** AES-256-GCM for CMS content encryption, matching `masterKey.ts`'s own AEAD choice - one AEAD
|
|
36
|
+
* construction used consistently across this entire E2E scheme. */
|
|
37
|
+
const CONTENT_ENCRYPTION_ALGORITHM: AesKeyGenParams = { name: "AES-GCM", length: 256 };
|
|
38
|
+
|
|
39
|
+
/** `id-data` (RFC 5652 §4) - the only encapsulated content type S/MIME message signatures use. */
|
|
40
|
+
const ID_DATA = pkijs.ContentInfo.DATA;
|
|
41
|
+
|
|
42
|
+
/** AES-GCM content-encryption OIDs (id-aes128-GCM, id-aes192-GCM, id-aes256-GCM - RFC 5084). The only
|
|
43
|
+
* content encryption `decryptEnvelopedData()` accepts: see `UnsupportedContentEncryptionError`. */
|
|
44
|
+
const AEAD_CONTENT_ENCRYPTION_OIDS = new Set(["2.16.840.1.101.3.4.1.6", "2.16.840.1.101.3.4.1.26", "2.16.840.1.101.3.4.1.46"]);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Thrown by `decryptEnvelopedData()` for content encrypted with a non-AEAD algorithm (e.g. AES-CBC, 3DES).
|
|
48
|
+
* Unauthenticated CBC content is malleable - an attacker who can't read the message can still flip
|
|
49
|
+
* plaintext bits or mount EFAIL-style exfiltration gadgets against the decrypted HTML - so it is rejected
|
|
50
|
+
* outright rather than rendered with a weaker indicator.
|
|
51
|
+
*
|
|
52
|
+
* Interop note: many legacy S/MIME clients still send AES-CBC `EnvelopedData`; those messages are
|
|
53
|
+
* undecryptable in RapidMX clients by design. Everything RapidMX itself sends uses AES-256-GCM.
|
|
54
|
+
*/
|
|
55
|
+
export class UnsupportedContentEncryptionError extends Error {
|
|
56
|
+
public readonly algorithmOid: string;
|
|
57
|
+
|
|
58
|
+
constructor(algorithmOid: string) {
|
|
59
|
+
super(`This message uses unauthenticated content encryption (${algorithmOid}), which is not accepted.`);
|
|
60
|
+
this.name = "UnsupportedContentEncryptionError";
|
|
61
|
+
this.algorithmOid = algorithmOid;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function toArrayBuffer(bytes: Uint8Array): ArrayBuffer {
|
|
66
|
+
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as ArrayBuffer;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function parseCertificate(certDer: Uint8Array): pkijs.Certificate {
|
|
70
|
+
const asn1 = asn1js.fromBER(toArrayBuffer(certDer));
|
|
71
|
+
if (asn1.offset === -1) {
|
|
72
|
+
throw new Error("Could not parse the certificate as valid DER/BER.");
|
|
73
|
+
}
|
|
74
|
+
return new pkijs.Certificate({ schema: asn1.result });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Builds a detached CMS `SignedData` structure over `content`, per the spec's "Digital Signatures"
|
|
79
|
+
* section — detached, never opaque, so clients that don't understand S/MIME still render the
|
|
80
|
+
* message body. The signer's own certificate is embedded in the `certificates` field (never sent
|
|
81
|
+
* separately — unlike the encryption key, which travels in the `RapidMX-Key` header).
|
|
82
|
+
*/
|
|
83
|
+
export async function signDetached(content: Uint8Array, signingCertDer: Uint8Array, signingPrivateKey: CryptoKey): Promise<Uint8Array> {
|
|
84
|
+
const cert = parseCertificate(signingCertDer);
|
|
85
|
+
const signedData = new pkijs.SignedData({
|
|
86
|
+
// No `eContent` - an omitted eContent is exactly what makes this a *detached* signature per
|
|
87
|
+
// RFC 5652; the actual content is passed to sign()/verify() separately, never embedded here.
|
|
88
|
+
encapContentInfo: new pkijs.EncapsulatedContentInfo({ eContentType: pkijs.ContentInfo.DATA }),
|
|
89
|
+
signerInfos: [
|
|
90
|
+
new pkijs.SignerInfo({
|
|
91
|
+
sid: new pkijs.IssuerAndSerialNumber({ issuer: cert.issuer, serialNumber: cert.serialNumber }),
|
|
92
|
+
}),
|
|
93
|
+
],
|
|
94
|
+
certificates: [cert],
|
|
95
|
+
});
|
|
96
|
+
await signedData.sign(signingPrivateKey, 0, DIGEST_ALGORITHM, toArrayBuffer(content));
|
|
97
|
+
|
|
98
|
+
const contentInfo = new pkijs.ContentInfo({ contentType: pkijs.ContentInfo.SIGNED_DATA, content: signedData.toSchema(true) });
|
|
99
|
+
return new Uint8Array(contentInfo.toSchema().toBER());
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface VerifyResult {
|
|
103
|
+
valid: boolean;
|
|
104
|
+
/** The certificate pkijs matched to the verified SignerInfo's `sid` (never merely the first embedded
|
|
105
|
+
* certificate) - present whenever `valid` is true. Callers
|
|
106
|
+
* compare its fingerprint against the pinned `Contact` key per the spec's Trust Model (TOFU);
|
|
107
|
+
* this function only proves the signature is mathematically valid over `content`, not that the
|
|
108
|
+
* certificate belongs to who the message claims. */
|
|
109
|
+
signerCertificateDer?: Uint8Array;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Verifies a detached CMS signature (as produced by `signDetached()`) against `content`. A parse
|
|
113
|
+
* failure or content-type mismatch is treated as an invalid signature (`valid: false`), not a thrown
|
|
114
|
+
* error - a malformed/foreign CMS blob is exactly the "signature failed" case the spec's Message
|
|
115
|
+
* Security Indicators table requires being able to render. */
|
|
116
|
+
export async function verifyDetached(content: Uint8Array, signatureDer: Uint8Array): Promise<VerifyResult> {
|
|
117
|
+
const signedData = parseSignedData(signatureDer);
|
|
118
|
+
// A detached signature MUST NOT carry encapsulated content: pkijs's verify() silently prefers an
|
|
119
|
+
// embedded eContent over the caller-supplied `data`, so accepting one here would let an attacker take
|
|
120
|
+
// ANY opaque signature the victim ever produced and staple it onto arbitrary content, which would
|
|
121
|
+
// then verify as "signed" (the round-3 review's PoC 1 - see smimeRegressions.test.ts).
|
|
122
|
+
if (!signedData || signedData.encapContentInfo.eContent) {
|
|
123
|
+
return { valid: false };
|
|
124
|
+
}
|
|
125
|
+
return verifySignerZero(signedData, toArrayBuffer(content));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Parses untrusted DER as a `ContentInfo` wrapping `SignedData` whose `eContentType` is `id-data`.
|
|
129
|
+
* Constructing SignedData from an untrusted schema can throw on a structurally-valid-BER-but-not-
|
|
130
|
+
* actually-SignedData blob - that degrades to `undefined` ("signature failed"), never a thrown error, per
|
|
131
|
+
* the spec's Message Security Indicators (a malformed CMS blob is exactly that state, not a crash). */
|
|
132
|
+
function parseSignedData(der: Uint8Array): pkijs.SignedData | undefined {
|
|
133
|
+
try {
|
|
134
|
+
const contentInfo = pkijs.ContentInfo.fromBER(toArrayBuffer(der));
|
|
135
|
+
if (contentInfo.contentType !== pkijs.ContentInfo.SIGNED_DATA) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const signedData = new pkijs.SignedData({ schema: contentInfo.content });
|
|
139
|
+
return signedData.encapContentInfo.eContentType === ID_DATA ? signedData : undefined;
|
|
140
|
+
} catch {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Verifies `signerInfos[0]` and returns the certificate pkijs actually matched to that SignerInfo's `sid`
|
|
147
|
+
* (`extendedMode`) - never simply `certificates[0]`, which an attacker controls independently of who
|
|
148
|
+
* signed: embedding the victim's certificate first and signing with their own key (whose certificate is
|
|
149
|
+
* second) previously reported the victim's certificate as the signer (the round-3 review's PoC 2).
|
|
150
|
+
* pkijs throws a `SignedDataVerifyError` for most failures in extended mode; all degrade to invalid.
|
|
151
|
+
*/
|
|
152
|
+
async function verifySignerZero(signedData: pkijs.SignedData, data?: ArrayBuffer): Promise<VerifyResult> {
|
|
153
|
+
try {
|
|
154
|
+
const result = await signedData.verify({ signer: 0, data, extendedMode: true });
|
|
155
|
+
if (result.signatureVerified !== true || !result.signerCertificate) {
|
|
156
|
+
return { valid: false };
|
|
157
|
+
}
|
|
158
|
+
return { valid: true, signerCertificateDer: new Uint8Array(result.signerCertificate.toSchema().toBER()) };
|
|
159
|
+
} catch {
|
|
160
|
+
return { valid: false };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Extracts every email address a certificate asserts, lowercased: SAN `rfc822Name` entries when the
|
|
166
|
+
* certificate has any (RFC 5280 §4.2.1.6 - SAN is authoritative when present), otherwise the subject's
|
|
167
|
+
* legacy `emailAddress` attributes plus a `CN` that is itself an email address (how this deployment's
|
|
168
|
+
* own self-signed/test certificates and many older CAs name a mailbox). Used by `messageSecurity.ts` to
|
|
169
|
+
* bind a signer certificate to the message's claimed sender. Returns `[]` for unparseable input -
|
|
170
|
+
* including a certificate whose SubjectAlternativeName extension pkijs couldn't parse (no `parsedValue`),
|
|
171
|
+
* which then fails the identity check (`signature_failed`) rather than throwing out of message evaluation.
|
|
172
|
+
*/
|
|
173
|
+
export function extractCertificateEmails(certDer: Uint8Array): string[] {
|
|
174
|
+
let cert: pkijs.Certificate;
|
|
175
|
+
try {
|
|
176
|
+
cert = parseCertificate(certDer);
|
|
177
|
+
} catch {
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
const sanEmails: string[] = [];
|
|
181
|
+
for (const extension of cert.extensions ?? []) {
|
|
182
|
+
if (extension.extnID !== "2.5.29.17") {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
// pkijs parses a well-formed SubjectAlternativeName into an AltName automatically, and leaves
|
|
186
|
+
// `parsedValue` unset for a malformed one - a certificate asserting an unreadable SAN names nobody.
|
|
187
|
+
const altNames = (extension.parsedValue as pkijs.AltName | undefined)?.altNames;
|
|
188
|
+
if (!Array.isArray(altNames)) {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
for (const name of altNames) {
|
|
192
|
+
// GeneralName type 1 = rfc822Name (an IA5String value).
|
|
193
|
+
if (name.type === 1) {
|
|
194
|
+
sanEmails.push(String(name.value).toLowerCase());
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (sanEmails.length > 0) {
|
|
199
|
+
return sanEmails;
|
|
200
|
+
}
|
|
201
|
+
const subjectEmails: string[] = [];
|
|
202
|
+
for (const attribute of cert.subject.typesAndValues) {
|
|
203
|
+
const isEmailAttribute = attribute.type === "1.2.840.113549.1.9.1";
|
|
204
|
+
const isCommonName = attribute.type === "2.5.4.3";
|
|
205
|
+
const value = String(attribute.value.valueBlock.value).trim().toLowerCase();
|
|
206
|
+
if (isEmailAttribute || (isCommonName && /^[^\s@]+@[^\s@]+$/.test(value))) {
|
|
207
|
+
subjectEmails.push(value);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return subjectEmails;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Builds an *opaque* (content embedded, not detached) CMS `SignedData` structure over `content`.
|
|
215
|
+
* Used only when the signed message is going to be encrypted immediately afterward (`buildMessage()`
|
|
216
|
+
* in `smimeMessage.ts` composes this with `encryptForRecipients()` for the combined sign-then-encrypt
|
|
217
|
+
* case) — the spec's "Digital Signatures" section requires *detached* signing only "for
|
|
218
|
+
* signature-only messages"; once the whole thing is being encrypted regardless, there is no legacy
|
|
219
|
+
* client ever exposed to this intermediate opaque layer, so embedding the content here (simpler than
|
|
220
|
+
* building a second detached `multipart/signed` entity solely to immediately encrypt it) is
|
|
221
|
+
* conformant, not a shortcut around that requirement.
|
|
222
|
+
*/
|
|
223
|
+
export async function signOpaque(content: Uint8Array, signingCertDer: Uint8Array, signingPrivateKey: CryptoKey): Promise<Uint8Array> {
|
|
224
|
+
const cert = parseCertificate(signingCertDer);
|
|
225
|
+
const signedData = new pkijs.SignedData({
|
|
226
|
+
encapContentInfo: new pkijs.EncapsulatedContentInfo({
|
|
227
|
+
eContentType: pkijs.ContentInfo.DATA,
|
|
228
|
+
eContent: new asn1js.OctetString({ valueHex: toArrayBuffer(content) }),
|
|
229
|
+
}),
|
|
230
|
+
signerInfos: [
|
|
231
|
+
new pkijs.SignerInfo({
|
|
232
|
+
sid: new pkijs.IssuerAndSerialNumber({ issuer: cert.issuer, serialNumber: cert.serialNumber }),
|
|
233
|
+
}),
|
|
234
|
+
],
|
|
235
|
+
certificates: [cert],
|
|
236
|
+
});
|
|
237
|
+
await signedData.sign(signingPrivateKey, 0, DIGEST_ALGORITHM);
|
|
238
|
+
|
|
239
|
+
const contentInfo = new pkijs.ContentInfo({ contentType: pkijs.ContentInfo.SIGNED_DATA, content: signedData.toSchema(true) });
|
|
240
|
+
return new Uint8Array(contentInfo.toSchema().toBER());
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface VerifyOpaqueResult extends VerifyResult {
|
|
244
|
+
/** The embedded content, recovered from the SignedData structure - only present when `valid`. */
|
|
245
|
+
content?: Uint8Array;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Verifies an opaque CMS signature (as produced by `signOpaque()`) and recovers its embedded
|
|
249
|
+
* content — unlike `verifyDetached()`, the content isn't supplied separately by the caller, since the
|
|
250
|
+
* whole point of an opaque signature is that it carries its own content. */
|
|
251
|
+
export async function verifyOpaque(signedDer: Uint8Array): Promise<VerifyOpaqueResult> {
|
|
252
|
+
const signedData = parseSignedData(signedDer);
|
|
253
|
+
const eContent = signedData?.encapContentInfo.eContent;
|
|
254
|
+
if (!signedData || !eContent) {
|
|
255
|
+
return { valid: false };
|
|
256
|
+
}
|
|
257
|
+
const result = await verifySignerZero(signedData);
|
|
258
|
+
if (!result.valid) {
|
|
259
|
+
return { valid: false };
|
|
260
|
+
}
|
|
261
|
+
// `.getValue()`, not `.valueBlock.valueHexView` directly - eContent commonly round-trips as a
|
|
262
|
+
// *constructed* OctetString (an outer OctetString wrapping one or more inner primitive OctetString
|
|
263
|
+
// chunks, standard per RFC 5652), and only `.getValue()` transparently concatenates those chunks;
|
|
264
|
+
// reading `.valueBlock.valueHexView` directly is only correct for a primitive OctetString and
|
|
265
|
+
// silently returns empty bytes otherwise (confirmed by direct reproduction).
|
|
266
|
+
return { ...result, content: new Uint8Array(eContent.getValue()) };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Builds a CMS `EnvelopedData` structure encrypting `content` to every certificate in
|
|
271
|
+
* `recipientCertDers` — per the spec's "Encrypt to Self" requirement, callers MUST include the
|
|
272
|
+
* sender's own encryption certificate in this list alongside the actual recipients' certificates, or
|
|
273
|
+
* the sender's own Sent-folder copy becomes unreadable to them.
|
|
274
|
+
*/
|
|
275
|
+
export async function encryptForRecipients(content: Uint8Array, recipientCertDers: Uint8Array[]): Promise<Uint8Array> {
|
|
276
|
+
const envelopedData = new pkijs.EnvelopedData();
|
|
277
|
+
for (const certDer of recipientCertDers) {
|
|
278
|
+
envelopedData.addRecipientByCertificate(parseCertificate(certDer));
|
|
279
|
+
}
|
|
280
|
+
await envelopedData.encrypt(CONTENT_ENCRYPTION_ALGORITHM, toArrayBuffer(content));
|
|
281
|
+
|
|
282
|
+
const contentInfo = new pkijs.ContentInfo({ contentType: pkijs.ContentInfo.ENVELOPED_DATA, content: envelopedData.toSchema() });
|
|
283
|
+
return new Uint8Array(contentInfo.toSchema().toBER());
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Decrypts a CMS `EnvelopedData` structure using one recipient's own certificate/private key.
|
|
288
|
+
* `EnvelopedData` doesn't label which `RecipientInfo` belongs to which recipient in a way this
|
|
289
|
+
* function's own caller already knows in advance, so it tries every recipient slot in turn with the
|
|
290
|
+
* one keypair it has, succeeding on whichever slot was actually built for it and discarding the rest
|
|
291
|
+
* — the same shape as trying every wrapped-key entry in `KeyVault.masterKeyWraps` until one unwraps.
|
|
292
|
+
* A slot whose recipient identifier names this certificate is tried first. See
|
|
293
|
+
* `decryptEnvelopedDataWithKeys()` for several candidate keys.
|
|
294
|
+
*/
|
|
295
|
+
export async function decryptEnvelopedData(
|
|
296
|
+
envelopedDer: Uint8Array,
|
|
297
|
+
recipientCertDer: Uint8Array,
|
|
298
|
+
recipientPrivateKey: CryptoKey,
|
|
299
|
+
): Promise<Uint8Array> {
|
|
300
|
+
return decryptEnvelopedDataWithKeys(envelopedDer, [{ certDer: recipientCertDer, privateKey: recipientPrivateKey }]);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** One candidate decryption keypair for `decryptEnvelopedDataWithKeys()`. */
|
|
304
|
+
export interface DecryptionKey {
|
|
305
|
+
/** Base64-decoded DER certificate of the key. */
|
|
306
|
+
certDer: Uint8Array;
|
|
307
|
+
privateKey: CryptoKey;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** At most this many candidate keys are considered by `decryptEnvelopedDataWithKeys()` (further ones are ignored) - the
|
|
311
|
+
* active encryption key plus `keySession.ts`'s `MAX_RETAINED_ENCRYPTION_KEYS` retained ones. */
|
|
312
|
+
export const MAX_DECRYPTION_KEYS = 21;
|
|
313
|
+
|
|
314
|
+
/** Trial decryptions (a key tried against a slot whose recipient identifier doesn't name it) allowed for every key
|
|
315
|
+
* after the first, together. The first key keeps the unbounded every-slot trial `decryptEnvelopedData()` always did;
|
|
316
|
+
* this budget stops a message with many recipient slots from costing `slots x keys` ECDH operations. */
|
|
317
|
+
export const MAX_TRIAL_DECRYPTIONS = 64;
|
|
318
|
+
|
|
319
|
+
function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {
|
|
320
|
+
return a.length === b.length && a.every((value, index) => value === b[index]);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** The recipient identifier of one `RecipientInfo`: an issuer and serial number, or a subject key identifier. Only
|
|
324
|
+
* key transport (`variant` 1) and key agreement (`variant` 2) recipients carry one naming a certificate; key agreement
|
|
325
|
+
* uses the first encrypted key's identifier, which is the only one pkijs's `decrypt()` reads. */
|
|
326
|
+
function recipientIdentifier(recipientInfo: pkijs.RecipientInfo): pkijs.IssuerAndSerialNumber | asn1js.OctetString | undefined {
|
|
327
|
+
if (recipientInfo.variant === 1) {
|
|
328
|
+
return (recipientInfo.value as pkijs.KeyTransRecipientInfo).rid;
|
|
329
|
+
}
|
|
330
|
+
if (recipientInfo.variant === 2) {
|
|
331
|
+
// pkijs refuses to parse a key agreement recipient without an encrypted key, so `[0]` always exists; a parsed
|
|
332
|
+
// identifier is variant 1 (issuer and serial number) or 2 (a `RecipientKeyIdentifier`).
|
|
333
|
+
const rid = (recipientInfo.value as pkijs.KeyAgreeRecipientInfo).recipientEncryptedKeys.encryptedKeys[0].rid;
|
|
334
|
+
return rid.variant === 1 ? (rid.value as pkijs.IssuerAndSerialNumber) : (rid.value as pkijs.RecipientKeyIdentifier).subjectKeyIdentifier;
|
|
335
|
+
}
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** The subject key identifier extension's value, when the certificate has a readable one. */
|
|
340
|
+
function subjectKeyIdentifier(certificate: pkijs.Certificate): Uint8Array | undefined {
|
|
341
|
+
const extension = certificate.extensions?.find((candidate) => candidate.extnID === "2.5.29.14");
|
|
342
|
+
const parsed = extension?.parsedValue as asn1js.OctetString | undefined;
|
|
343
|
+
return parsed instanceof asn1js.OctetString ? new Uint8Array(parsed.valueBlock.valueHexView) : undefined;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** Whether a recipient slot's identifier names `certificate` (same serial number and issuer DER, or same subject key
|
|
347
|
+
* identifier). A slot with no certificate identifier (KEK, password) names nobody. */
|
|
348
|
+
function recipientMatchesCertificate(recipientInfo: pkijs.RecipientInfo, certificate: pkijs.Certificate): boolean {
|
|
349
|
+
const identifier = recipientIdentifier(recipientInfo);
|
|
350
|
+
if (identifier instanceof pkijs.IssuerAndSerialNumber) {
|
|
351
|
+
return (
|
|
352
|
+
bytesEqual(new Uint8Array(identifier.serialNumber.valueBlock.valueHexView), new Uint8Array(certificate.serialNumber.valueBlock.valueHexView)) &&
|
|
353
|
+
bytesEqual(new Uint8Array(identifier.issuer.toSchema().toBER()), new Uint8Array(certificate.issuer.toSchema().toBER()))
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
if (identifier instanceof asn1js.OctetString) {
|
|
357
|
+
const ski = subjectKeyIdentifier(certificate);
|
|
358
|
+
return ski !== undefined && bytesEqual(new Uint8Array(identifier.valueBlock.valueHexView), ski);
|
|
359
|
+
}
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Decrypts a CMS `EnvelopedData` structure with whichever of several candidate keys it was encrypted to - the mailbox's
|
|
365
|
+
* active encryption key followed by the retained older ones (`keySession.ts`'s `retainedEncryptionKeys`), so mail
|
|
366
|
+
* encrypted to a key since replaced stays readable.
|
|
367
|
+
*
|
|
368
|
+
* **Matching first:** every recipient slot whose identifier (issuer and serial number, or subject key identifier) names
|
|
369
|
+
* a candidate's certificate is tried with that key, in candidate order - normally one decryption, no guessing.
|
|
370
|
+
* **Trial otherwise** (e.g. the sender encrypted to a reissued certificate for the same key): the first candidate is
|
|
371
|
+
* tried against every remaining slot, then the others in order, sharing `MAX_TRIAL_DECRYPTIONS`.
|
|
372
|
+
*
|
|
373
|
+
* Only the first `MAX_DECRYPTION_KEYS` candidates are considered. A candidate whose certificate can't be parsed is
|
|
374
|
+
* skipped (the parse error is thrown only when no candidate is usable). Throws `UnsupportedContentEncryptionError` for
|
|
375
|
+
* non-AEAD content, and the last decryption error when no key opens any slot.
|
|
376
|
+
*/
|
|
377
|
+
export async function decryptEnvelopedDataWithKeys(envelopedDer: Uint8Array, keys: DecryptionKey[]): Promise<Uint8Array> {
|
|
378
|
+
const contentInfo = pkijs.ContentInfo.fromBER(toArrayBuffer(envelopedDer));
|
|
379
|
+
if (contentInfo.contentType !== pkijs.ContentInfo.ENVELOPED_DATA) {
|
|
380
|
+
throw new Error("This CMS content is not EnvelopedData.");
|
|
381
|
+
}
|
|
382
|
+
const envelopedData = new pkijs.EnvelopedData({ schema: contentInfo.content });
|
|
383
|
+
const contentEncryptionOid = envelopedData.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId;
|
|
384
|
+
if (!AEAD_CONTENT_ENCRYPTION_OIDS.has(contentEncryptionOid)) {
|
|
385
|
+
throw new UnsupportedContentEncryptionError(contentEncryptionOid);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const candidates: { certificate: pkijs.Certificate; privateKey: CryptoKey }[] = [];
|
|
389
|
+
let parseError: unknown;
|
|
390
|
+
for (const key of keys.slice(0, MAX_DECRYPTION_KEYS)) {
|
|
391
|
+
try {
|
|
392
|
+
candidates.push({ certificate: parseCertificate(key.certDer), privateKey: key.privateKey });
|
|
393
|
+
} catch (err) {
|
|
394
|
+
parseError = err;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (candidates.length === 0) {
|
|
398
|
+
throw parseError instanceof Error ? parseError : new Error("No decryption key was supplied.");
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const slotCount = envelopedData.recipientInfos.length;
|
|
402
|
+
const tried = new Set<string>();
|
|
403
|
+
let lastError: unknown;
|
|
404
|
+
const attempt = async (index: number, candidate: number): Promise<Uint8Array | undefined> => {
|
|
405
|
+
tried.add(`${index}:${candidate}`);
|
|
406
|
+
const { certificate, privateKey } = candidates[candidate];
|
|
407
|
+
try {
|
|
408
|
+
return new Uint8Array(await envelopedData.decrypt(index, { recipientCertificate: certificate, recipientPrivateKey: privateKey }));
|
|
409
|
+
} catch (err) {
|
|
410
|
+
lastError = err;
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
for (let candidate = 0; candidate < candidates.length; candidate++) {
|
|
416
|
+
for (let index = 0; index < slotCount; index++) {
|
|
417
|
+
if (recipientMatchesCertificate(envelopedData.recipientInfos[index], candidates[candidate].certificate)) {
|
|
418
|
+
const decrypted = await attempt(index, candidate);
|
|
419
|
+
if (decrypted) {
|
|
420
|
+
return decrypted;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
let trialBudget = MAX_TRIAL_DECRYPTIONS;
|
|
427
|
+
for (let candidate = 0; candidate < candidates.length; candidate++) {
|
|
428
|
+
for (let index = 0; index < slotCount; index++) {
|
|
429
|
+
if (tried.has(`${index}:${candidate}`)) {
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
if (candidate > 0 && trialBudget-- <= 0) {
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
const decrypted = await attempt(index, candidate);
|
|
436
|
+
if (decrypted) {
|
|
437
|
+
return decrypted;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// The `new Error(...)` fallback covers an EnvelopedData with zero recipientInfos (no attempt ever runs, so
|
|
442
|
+
// `lastError` stays its initial `undefined`) - not reachable through this module's own encryptForRecipients(),
|
|
443
|
+
// which always adds at least one recipient in practice, but kept as a defensive fallback since `lastError` could
|
|
444
|
+
// otherwise surface as a non-Error thrown value.
|
|
445
|
+
throw lastError instanceof Error ? lastError : new Error("No recipient slot in this EnvelopedData could be decrypted with these keys.");
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/** SHA-256 fingerprint of a DER certificate, hex encoded — matches `keyvaultApi.ts`'s own `PublicKey.
|
|
449
|
+
* fingerprint` format exactly, so a value computed here is directly comparable against one already on
|
|
450
|
+
* a `Mailbox`/`Contact` record. Used by `messageSecurity.ts` to compare a received message's embedded
|
|
451
|
+
* signer certificate against a pinned `Contact` key per the spec's Trust Model (TOFU) — `verifyDetached()`/
|
|
452
|
+
* `verifyOpaque()` only prove a signature is mathematically valid, never that the certificate belongs to
|
|
453
|
+
* who the message claims (see `VerifyResult`'s own doc comment). */
|
|
454
|
+
export async function computeCertFingerprint(certDer: Uint8Array): Promise<string> {
|
|
455
|
+
const digest = await crypto.subtle.digest(DIGEST_ALGORITHM, toArrayBuffer(certDer));
|
|
456
|
+
return Array.from(new Uint8Array(digest))
|
|
457
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
458
|
+
.join("");
|
|
459
|
+
}
|