@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,402 @@
|
|
|
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
|
+
// Mirrors keys.ts's own WebCrypto engine setup - both @peculiar/x509 and pkijs need to be told which
|
|
21
|
+
// Crypto implementation to use; the browser/Electron renderer's own global `crypto` is exactly what
|
|
22
|
+
// both expect (unlike Node's global `crypto`, which @rapidmx/restapi's server-side code has to set up
|
|
23
|
+
// differently - see that repo's LocalX509CertificateAuthority.ts). The raw (`crypto`, `crypto.subtle`)
|
|
24
|
+
// three-argument form, not `new pkijs.CryptoEngine({...})` - pkijs's own `CryptoEngine` class doesn't
|
|
25
|
+
// actually satisfy its own `ICryptoEngine` interface (a real type-definition inconsistency in pkijs
|
|
26
|
+
// itself, confirmed via `tsc --noEmit`: `generateKey`'s Ed25519/X25519 overloads don't line up between
|
|
27
|
+
// the two), so passing an instance of it here fails to compile even though it works at runtime.
|
|
28
|
+
pkijs.setEngine("rapidmx", crypto, crypto.subtle);
|
|
29
|
+
/** SHA-256 detached signatures throughout, matching this system's hash-algorithm default everywhere
|
|
30
|
+
* else (fingerprints, HKDF). */
|
|
31
|
+
const DIGEST_ALGORITHM = "SHA-256";
|
|
32
|
+
/** AES-256-GCM for CMS content encryption, matching `masterKey.ts`'s own AEAD choice - one AEAD
|
|
33
|
+
* construction used consistently across this entire E2E scheme. */
|
|
34
|
+
const CONTENT_ENCRYPTION_ALGORITHM = { name: "AES-GCM", length: 256 };
|
|
35
|
+
/** `id-data` (RFC 5652 §4) - the only encapsulated content type S/MIME message signatures use. */
|
|
36
|
+
const ID_DATA = pkijs.ContentInfo.DATA;
|
|
37
|
+
/** AES-GCM content-encryption OIDs (id-aes128-GCM, id-aes192-GCM, id-aes256-GCM - RFC 5084). The only
|
|
38
|
+
* content encryption `decryptEnvelopedData()` accepts: see `UnsupportedContentEncryptionError`. */
|
|
39
|
+
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"]);
|
|
40
|
+
/**
|
|
41
|
+
* Thrown by `decryptEnvelopedData()` for content encrypted with a non-AEAD algorithm (e.g. AES-CBC, 3DES).
|
|
42
|
+
* Unauthenticated CBC content is malleable - an attacker who can't read the message can still flip
|
|
43
|
+
* plaintext bits or mount EFAIL-style exfiltration gadgets against the decrypted HTML - so it is rejected
|
|
44
|
+
* outright rather than rendered with a weaker indicator.
|
|
45
|
+
*
|
|
46
|
+
* Interop note: many legacy S/MIME clients still send AES-CBC `EnvelopedData`; those messages are
|
|
47
|
+
* undecryptable in RapidMX clients by design. Everything RapidMX itself sends uses AES-256-GCM.
|
|
48
|
+
*/
|
|
49
|
+
export class UnsupportedContentEncryptionError extends Error {
|
|
50
|
+
constructor(algorithmOid) {
|
|
51
|
+
super(`This message uses unauthenticated content encryption (${algorithmOid}), which is not accepted.`);
|
|
52
|
+
this.name = "UnsupportedContentEncryptionError";
|
|
53
|
+
this.algorithmOid = algorithmOid;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function toArrayBuffer(bytes) {
|
|
57
|
+
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
58
|
+
}
|
|
59
|
+
function parseCertificate(certDer) {
|
|
60
|
+
const asn1 = asn1js.fromBER(toArrayBuffer(certDer));
|
|
61
|
+
if (asn1.offset === -1) {
|
|
62
|
+
throw new Error("Could not parse the certificate as valid DER/BER.");
|
|
63
|
+
}
|
|
64
|
+
return new pkijs.Certificate({ schema: asn1.result });
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Builds a detached CMS `SignedData` structure over `content`, per the spec's "Digital Signatures"
|
|
68
|
+
* section — detached, never opaque, so clients that don't understand S/MIME still render the
|
|
69
|
+
* message body. The signer's own certificate is embedded in the `certificates` field (never sent
|
|
70
|
+
* separately — unlike the encryption key, which travels in the `RapidMX-Key` header).
|
|
71
|
+
*/
|
|
72
|
+
export async function signDetached(content, signingCertDer, signingPrivateKey) {
|
|
73
|
+
const cert = parseCertificate(signingCertDer);
|
|
74
|
+
const signedData = new pkijs.SignedData({
|
|
75
|
+
// No `eContent` - an omitted eContent is exactly what makes this a *detached* signature per
|
|
76
|
+
// RFC 5652; the actual content is passed to sign()/verify() separately, never embedded here.
|
|
77
|
+
encapContentInfo: new pkijs.EncapsulatedContentInfo({ eContentType: pkijs.ContentInfo.DATA }),
|
|
78
|
+
signerInfos: [
|
|
79
|
+
new pkijs.SignerInfo({
|
|
80
|
+
sid: new pkijs.IssuerAndSerialNumber({ issuer: cert.issuer, serialNumber: cert.serialNumber }),
|
|
81
|
+
}),
|
|
82
|
+
],
|
|
83
|
+
certificates: [cert],
|
|
84
|
+
});
|
|
85
|
+
await signedData.sign(signingPrivateKey, 0, DIGEST_ALGORITHM, toArrayBuffer(content));
|
|
86
|
+
const contentInfo = new pkijs.ContentInfo({ contentType: pkijs.ContentInfo.SIGNED_DATA, content: signedData.toSchema(true) });
|
|
87
|
+
return new Uint8Array(contentInfo.toSchema().toBER());
|
|
88
|
+
}
|
|
89
|
+
/** Verifies a detached CMS signature (as produced by `signDetached()`) against `content`. A parse
|
|
90
|
+
* failure or content-type mismatch is treated as an invalid signature (`valid: false`), not a thrown
|
|
91
|
+
* error - a malformed/foreign CMS blob is exactly the "signature failed" case the spec's Message
|
|
92
|
+
* Security Indicators table requires being able to render. */
|
|
93
|
+
export async function verifyDetached(content, signatureDer) {
|
|
94
|
+
const signedData = parseSignedData(signatureDer);
|
|
95
|
+
// A detached signature MUST NOT carry encapsulated content: pkijs's verify() silently prefers an
|
|
96
|
+
// embedded eContent over the caller-supplied `data`, so accepting one here would let an attacker take
|
|
97
|
+
// ANY opaque signature the victim ever produced and staple it onto arbitrary content, which would
|
|
98
|
+
// then verify as "signed" (the round-3 review's PoC 1 - see smimeRegressions.test.ts).
|
|
99
|
+
if (!signedData || signedData.encapContentInfo.eContent) {
|
|
100
|
+
return { valid: false };
|
|
101
|
+
}
|
|
102
|
+
return verifySignerZero(signedData, toArrayBuffer(content));
|
|
103
|
+
}
|
|
104
|
+
/** Parses untrusted DER as a `ContentInfo` wrapping `SignedData` whose `eContentType` is `id-data`.
|
|
105
|
+
* Constructing SignedData from an untrusted schema can throw on a structurally-valid-BER-but-not-
|
|
106
|
+
* actually-SignedData blob - that degrades to `undefined` ("signature failed"), never a thrown error, per
|
|
107
|
+
* the spec's Message Security Indicators (a malformed CMS blob is exactly that state, not a crash). */
|
|
108
|
+
function parseSignedData(der) {
|
|
109
|
+
try {
|
|
110
|
+
const contentInfo = pkijs.ContentInfo.fromBER(toArrayBuffer(der));
|
|
111
|
+
if (contentInfo.contentType !== pkijs.ContentInfo.SIGNED_DATA) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
const signedData = new pkijs.SignedData({ schema: contentInfo.content });
|
|
115
|
+
return signedData.encapContentInfo.eContentType === ID_DATA ? signedData : undefined;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Verifies `signerInfos[0]` and returns the certificate pkijs actually matched to that SignerInfo's `sid`
|
|
123
|
+
* (`extendedMode`) - never simply `certificates[0]`, which an attacker controls independently of who
|
|
124
|
+
* signed: embedding the victim's certificate first and signing with their own key (whose certificate is
|
|
125
|
+
* second) previously reported the victim's certificate as the signer (the round-3 review's PoC 2).
|
|
126
|
+
* pkijs throws a `SignedDataVerifyError` for most failures in extended mode; all degrade to invalid.
|
|
127
|
+
*/
|
|
128
|
+
async function verifySignerZero(signedData, data) {
|
|
129
|
+
try {
|
|
130
|
+
const result = await signedData.verify({ signer: 0, data, extendedMode: true });
|
|
131
|
+
if (result.signatureVerified !== true || !result.signerCertificate) {
|
|
132
|
+
return { valid: false };
|
|
133
|
+
}
|
|
134
|
+
return { valid: true, signerCertificateDer: new Uint8Array(result.signerCertificate.toSchema().toBER()) };
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return { valid: false };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Extracts every email address a certificate asserts, lowercased: SAN `rfc822Name` entries when the
|
|
142
|
+
* certificate has any (RFC 5280 §4.2.1.6 - SAN is authoritative when present), otherwise the subject's
|
|
143
|
+
* legacy `emailAddress` attributes plus a `CN` that is itself an email address (how this deployment's
|
|
144
|
+
* own self-signed/test certificates and many older CAs name a mailbox). Used by `messageSecurity.ts` to
|
|
145
|
+
* bind a signer certificate to the message's claimed sender. Returns `[]` for unparseable input -
|
|
146
|
+
* including a certificate whose SubjectAlternativeName extension pkijs couldn't parse (no `parsedValue`),
|
|
147
|
+
* which then fails the identity check (`signature_failed`) rather than throwing out of message evaluation.
|
|
148
|
+
*/
|
|
149
|
+
export function extractCertificateEmails(certDer) {
|
|
150
|
+
let cert;
|
|
151
|
+
try {
|
|
152
|
+
cert = parseCertificate(certDer);
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
const sanEmails = [];
|
|
158
|
+
for (const extension of cert.extensions ?? []) {
|
|
159
|
+
if (extension.extnID !== "2.5.29.17") {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
// pkijs parses a well-formed SubjectAlternativeName into an AltName automatically, and leaves
|
|
163
|
+
// `parsedValue` unset for a malformed one - a certificate asserting an unreadable SAN names nobody.
|
|
164
|
+
const altNames = extension.parsedValue?.altNames;
|
|
165
|
+
if (!Array.isArray(altNames)) {
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
for (const name of altNames) {
|
|
169
|
+
// GeneralName type 1 = rfc822Name (an IA5String value).
|
|
170
|
+
if (name.type === 1) {
|
|
171
|
+
sanEmails.push(String(name.value).toLowerCase());
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (sanEmails.length > 0) {
|
|
176
|
+
return sanEmails;
|
|
177
|
+
}
|
|
178
|
+
const subjectEmails = [];
|
|
179
|
+
for (const attribute of cert.subject.typesAndValues) {
|
|
180
|
+
const isEmailAttribute = attribute.type === "1.2.840.113549.1.9.1";
|
|
181
|
+
const isCommonName = attribute.type === "2.5.4.3";
|
|
182
|
+
const value = String(attribute.value.valueBlock.value).trim().toLowerCase();
|
|
183
|
+
if (isEmailAttribute || (isCommonName && /^[^\s@]+@[^\s@]+$/.test(value))) {
|
|
184
|
+
subjectEmails.push(value);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return subjectEmails;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Builds an *opaque* (content embedded, not detached) CMS `SignedData` structure over `content`.
|
|
191
|
+
* Used only when the signed message is going to be encrypted immediately afterward (`buildMessage()`
|
|
192
|
+
* in `smimeMessage.ts` composes this with `encryptForRecipients()` for the combined sign-then-encrypt
|
|
193
|
+
* case) — the spec's "Digital Signatures" section requires *detached* signing only "for
|
|
194
|
+
* signature-only messages"; once the whole thing is being encrypted regardless, there is no legacy
|
|
195
|
+
* client ever exposed to this intermediate opaque layer, so embedding the content here (simpler than
|
|
196
|
+
* building a second detached `multipart/signed` entity solely to immediately encrypt it) is
|
|
197
|
+
* conformant, not a shortcut around that requirement.
|
|
198
|
+
*/
|
|
199
|
+
export async function signOpaque(content, signingCertDer, signingPrivateKey) {
|
|
200
|
+
const cert = parseCertificate(signingCertDer);
|
|
201
|
+
const signedData = new pkijs.SignedData({
|
|
202
|
+
encapContentInfo: new pkijs.EncapsulatedContentInfo({
|
|
203
|
+
eContentType: pkijs.ContentInfo.DATA,
|
|
204
|
+
eContent: new asn1js.OctetString({ valueHex: toArrayBuffer(content) }),
|
|
205
|
+
}),
|
|
206
|
+
signerInfos: [
|
|
207
|
+
new pkijs.SignerInfo({
|
|
208
|
+
sid: new pkijs.IssuerAndSerialNumber({ issuer: cert.issuer, serialNumber: cert.serialNumber }),
|
|
209
|
+
}),
|
|
210
|
+
],
|
|
211
|
+
certificates: [cert],
|
|
212
|
+
});
|
|
213
|
+
await signedData.sign(signingPrivateKey, 0, DIGEST_ALGORITHM);
|
|
214
|
+
const contentInfo = new pkijs.ContentInfo({ contentType: pkijs.ContentInfo.SIGNED_DATA, content: signedData.toSchema(true) });
|
|
215
|
+
return new Uint8Array(contentInfo.toSchema().toBER());
|
|
216
|
+
}
|
|
217
|
+
/** Verifies an opaque CMS signature (as produced by `signOpaque()`) and recovers its embedded
|
|
218
|
+
* content — unlike `verifyDetached()`, the content isn't supplied separately by the caller, since the
|
|
219
|
+
* whole point of an opaque signature is that it carries its own content. */
|
|
220
|
+
export async function verifyOpaque(signedDer) {
|
|
221
|
+
const signedData = parseSignedData(signedDer);
|
|
222
|
+
const eContent = signedData?.encapContentInfo.eContent;
|
|
223
|
+
if (!signedData || !eContent) {
|
|
224
|
+
return { valid: false };
|
|
225
|
+
}
|
|
226
|
+
const result = await verifySignerZero(signedData);
|
|
227
|
+
if (!result.valid) {
|
|
228
|
+
return { valid: false };
|
|
229
|
+
}
|
|
230
|
+
// `.getValue()`, not `.valueBlock.valueHexView` directly - eContent commonly round-trips as a
|
|
231
|
+
// *constructed* OctetString (an outer OctetString wrapping one or more inner primitive OctetString
|
|
232
|
+
// chunks, standard per RFC 5652), and only `.getValue()` transparently concatenates those chunks;
|
|
233
|
+
// reading `.valueBlock.valueHexView` directly is only correct for a primitive OctetString and
|
|
234
|
+
// silently returns empty bytes otherwise (confirmed by direct reproduction).
|
|
235
|
+
return { ...result, content: new Uint8Array(eContent.getValue()) };
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Builds a CMS `EnvelopedData` structure encrypting `content` to every certificate in
|
|
239
|
+
* `recipientCertDers` — per the spec's "Encrypt to Self" requirement, callers MUST include the
|
|
240
|
+
* sender's own encryption certificate in this list alongside the actual recipients' certificates, or
|
|
241
|
+
* the sender's own Sent-folder copy becomes unreadable to them.
|
|
242
|
+
*/
|
|
243
|
+
export async function encryptForRecipients(content, recipientCertDers) {
|
|
244
|
+
const envelopedData = new pkijs.EnvelopedData();
|
|
245
|
+
for (const certDer of recipientCertDers) {
|
|
246
|
+
envelopedData.addRecipientByCertificate(parseCertificate(certDer));
|
|
247
|
+
}
|
|
248
|
+
await envelopedData.encrypt(CONTENT_ENCRYPTION_ALGORITHM, toArrayBuffer(content));
|
|
249
|
+
const contentInfo = new pkijs.ContentInfo({ contentType: pkijs.ContentInfo.ENVELOPED_DATA, content: envelopedData.toSchema() });
|
|
250
|
+
return new Uint8Array(contentInfo.toSchema().toBER());
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Decrypts a CMS `EnvelopedData` structure using one recipient's own certificate/private key.
|
|
254
|
+
* `EnvelopedData` doesn't label which `RecipientInfo` belongs to which recipient in a way this
|
|
255
|
+
* function's own caller already knows in advance, so it tries every recipient slot in turn with the
|
|
256
|
+
* one keypair it has, succeeding on whichever slot was actually built for it and discarding the rest
|
|
257
|
+
* — the same shape as trying every wrapped-key entry in `KeyVault.masterKeyWraps` until one unwraps.
|
|
258
|
+
* A slot whose recipient identifier names this certificate is tried first. See
|
|
259
|
+
* `decryptEnvelopedDataWithKeys()` for several candidate keys.
|
|
260
|
+
*/
|
|
261
|
+
export async function decryptEnvelopedData(envelopedDer, recipientCertDer, recipientPrivateKey) {
|
|
262
|
+
return decryptEnvelopedDataWithKeys(envelopedDer, [{ certDer: recipientCertDer, privateKey: recipientPrivateKey }]);
|
|
263
|
+
}
|
|
264
|
+
/** At most this many candidate keys are considered by `decryptEnvelopedDataWithKeys()` (further ones are ignored) - the
|
|
265
|
+
* active encryption key plus `keySession.ts`'s `MAX_RETAINED_ENCRYPTION_KEYS` retained ones. */
|
|
266
|
+
export const MAX_DECRYPTION_KEYS = 21;
|
|
267
|
+
/** Trial decryptions (a key tried against a slot whose recipient identifier doesn't name it) allowed for every key
|
|
268
|
+
* after the first, together. The first key keeps the unbounded every-slot trial `decryptEnvelopedData()` always did;
|
|
269
|
+
* this budget stops a message with many recipient slots from costing `slots x keys` ECDH operations. */
|
|
270
|
+
export const MAX_TRIAL_DECRYPTIONS = 64;
|
|
271
|
+
function bytesEqual(a, b) {
|
|
272
|
+
return a.length === b.length && a.every((value, index) => value === b[index]);
|
|
273
|
+
}
|
|
274
|
+
/** The recipient identifier of one `RecipientInfo`: an issuer and serial number, or a subject key identifier. Only
|
|
275
|
+
* key transport (`variant` 1) and key agreement (`variant` 2) recipients carry one naming a certificate; key agreement
|
|
276
|
+
* uses the first encrypted key's identifier, which is the only one pkijs's `decrypt()` reads. */
|
|
277
|
+
function recipientIdentifier(recipientInfo) {
|
|
278
|
+
if (recipientInfo.variant === 1) {
|
|
279
|
+
return recipientInfo.value.rid;
|
|
280
|
+
}
|
|
281
|
+
if (recipientInfo.variant === 2) {
|
|
282
|
+
// pkijs refuses to parse a key agreement recipient without an encrypted key, so `[0]` always exists; a parsed
|
|
283
|
+
// identifier is variant 1 (issuer and serial number) or 2 (a `RecipientKeyIdentifier`).
|
|
284
|
+
const rid = recipientInfo.value.recipientEncryptedKeys.encryptedKeys[0].rid;
|
|
285
|
+
return rid.variant === 1 ? rid.value : rid.value.subjectKeyIdentifier;
|
|
286
|
+
}
|
|
287
|
+
return undefined;
|
|
288
|
+
}
|
|
289
|
+
/** The subject key identifier extension's value, when the certificate has a readable one. */
|
|
290
|
+
function subjectKeyIdentifier(certificate) {
|
|
291
|
+
const extension = certificate.extensions?.find((candidate) => candidate.extnID === "2.5.29.14");
|
|
292
|
+
const parsed = extension?.parsedValue;
|
|
293
|
+
return parsed instanceof asn1js.OctetString ? new Uint8Array(parsed.valueBlock.valueHexView) : undefined;
|
|
294
|
+
}
|
|
295
|
+
/** Whether a recipient slot's identifier names `certificate` (same serial number and issuer DER, or same subject key
|
|
296
|
+
* identifier). A slot with no certificate identifier (KEK, password) names nobody. */
|
|
297
|
+
function recipientMatchesCertificate(recipientInfo, certificate) {
|
|
298
|
+
const identifier = recipientIdentifier(recipientInfo);
|
|
299
|
+
if (identifier instanceof pkijs.IssuerAndSerialNumber) {
|
|
300
|
+
return (bytesEqual(new Uint8Array(identifier.serialNumber.valueBlock.valueHexView), new Uint8Array(certificate.serialNumber.valueBlock.valueHexView)) &&
|
|
301
|
+
bytesEqual(new Uint8Array(identifier.issuer.toSchema().toBER()), new Uint8Array(certificate.issuer.toSchema().toBER())));
|
|
302
|
+
}
|
|
303
|
+
if (identifier instanceof asn1js.OctetString) {
|
|
304
|
+
const ski = subjectKeyIdentifier(certificate);
|
|
305
|
+
return ski !== undefined && bytesEqual(new Uint8Array(identifier.valueBlock.valueHexView), ski);
|
|
306
|
+
}
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Decrypts a CMS `EnvelopedData` structure with whichever of several candidate keys it was encrypted to - the mailbox's
|
|
311
|
+
* active encryption key followed by the retained older ones (`keySession.ts`'s `retainedEncryptionKeys`), so mail
|
|
312
|
+
* encrypted to a key since replaced stays readable.
|
|
313
|
+
*
|
|
314
|
+
* **Matching first:** every recipient slot whose identifier (issuer and serial number, or subject key identifier) names
|
|
315
|
+
* a candidate's certificate is tried with that key, in candidate order - normally one decryption, no guessing.
|
|
316
|
+
* **Trial otherwise** (e.g. the sender encrypted to a reissued certificate for the same key): the first candidate is
|
|
317
|
+
* tried against every remaining slot, then the others in order, sharing `MAX_TRIAL_DECRYPTIONS`.
|
|
318
|
+
*
|
|
319
|
+
* Only the first `MAX_DECRYPTION_KEYS` candidates are considered. A candidate whose certificate can't be parsed is
|
|
320
|
+
* skipped (the parse error is thrown only when no candidate is usable). Throws `UnsupportedContentEncryptionError` for
|
|
321
|
+
* non-AEAD content, and the last decryption error when no key opens any slot.
|
|
322
|
+
*/
|
|
323
|
+
export async function decryptEnvelopedDataWithKeys(envelopedDer, keys) {
|
|
324
|
+
const contentInfo = pkijs.ContentInfo.fromBER(toArrayBuffer(envelopedDer));
|
|
325
|
+
if (contentInfo.contentType !== pkijs.ContentInfo.ENVELOPED_DATA) {
|
|
326
|
+
throw new Error("This CMS content is not EnvelopedData.");
|
|
327
|
+
}
|
|
328
|
+
const envelopedData = new pkijs.EnvelopedData({ schema: contentInfo.content });
|
|
329
|
+
const contentEncryptionOid = envelopedData.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId;
|
|
330
|
+
if (!AEAD_CONTENT_ENCRYPTION_OIDS.has(contentEncryptionOid)) {
|
|
331
|
+
throw new UnsupportedContentEncryptionError(contentEncryptionOid);
|
|
332
|
+
}
|
|
333
|
+
const candidates = [];
|
|
334
|
+
let parseError;
|
|
335
|
+
for (const key of keys.slice(0, MAX_DECRYPTION_KEYS)) {
|
|
336
|
+
try {
|
|
337
|
+
candidates.push({ certificate: parseCertificate(key.certDer), privateKey: key.privateKey });
|
|
338
|
+
}
|
|
339
|
+
catch (err) {
|
|
340
|
+
parseError = err;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (candidates.length === 0) {
|
|
344
|
+
throw parseError instanceof Error ? parseError : new Error("No decryption key was supplied.");
|
|
345
|
+
}
|
|
346
|
+
const slotCount = envelopedData.recipientInfos.length;
|
|
347
|
+
const tried = new Set();
|
|
348
|
+
let lastError;
|
|
349
|
+
const attempt = async (index, candidate) => {
|
|
350
|
+
tried.add(`${index}:${candidate}`);
|
|
351
|
+
const { certificate, privateKey } = candidates[candidate];
|
|
352
|
+
try {
|
|
353
|
+
return new Uint8Array(await envelopedData.decrypt(index, { recipientCertificate: certificate, recipientPrivateKey: privateKey }));
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
lastError = err;
|
|
357
|
+
return undefined;
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
for (let candidate = 0; candidate < candidates.length; candidate++) {
|
|
361
|
+
for (let index = 0; index < slotCount; index++) {
|
|
362
|
+
if (recipientMatchesCertificate(envelopedData.recipientInfos[index], candidates[candidate].certificate)) {
|
|
363
|
+
const decrypted = await attempt(index, candidate);
|
|
364
|
+
if (decrypted) {
|
|
365
|
+
return decrypted;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
let trialBudget = MAX_TRIAL_DECRYPTIONS;
|
|
371
|
+
for (let candidate = 0; candidate < candidates.length; candidate++) {
|
|
372
|
+
for (let index = 0; index < slotCount; index++) {
|
|
373
|
+
if (tried.has(`${index}:${candidate}`)) {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
if (candidate > 0 && trialBudget-- <= 0) {
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
const decrypted = await attempt(index, candidate);
|
|
380
|
+
if (decrypted) {
|
|
381
|
+
return decrypted;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// The `new Error(...)` fallback covers an EnvelopedData with zero recipientInfos (no attempt ever runs, so
|
|
386
|
+
// `lastError` stays its initial `undefined`) - not reachable through this module's own encryptForRecipients(),
|
|
387
|
+
// which always adds at least one recipient in practice, but kept as a defensive fallback since `lastError` could
|
|
388
|
+
// otherwise surface as a non-Error thrown value.
|
|
389
|
+
throw lastError instanceof Error ? lastError : new Error("No recipient slot in this EnvelopedData could be decrypted with these keys.");
|
|
390
|
+
}
|
|
391
|
+
/** SHA-256 fingerprint of a DER certificate, hex encoded — matches `keyvaultApi.ts`'s own `PublicKey.
|
|
392
|
+
* fingerprint` format exactly, so a value computed here is directly comparable against one already on
|
|
393
|
+
* a `Mailbox`/`Contact` record. Used by `messageSecurity.ts` to compare a received message's embedded
|
|
394
|
+
* signer certificate against a pinned `Contact` key per the spec's Trust Model (TOFU) — `verifyDetached()`/
|
|
395
|
+
* `verifyOpaque()` only prove a signature is mathematically valid, never that the certificate belongs to
|
|
396
|
+
* who the message claims (see `VerifyResult`'s own doc comment). */
|
|
397
|
+
export async function computeCertFingerprint(certDer) {
|
|
398
|
+
const digest = await crypto.subtle.digest(DIGEST_ALGORITHM, toArrayBuffer(certDer));
|
|
399
|
+
return Array.from(new Uint8Array(digest))
|
|
400
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
401
|
+
.join("");
|
|
402
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { DisplayBody, MimeAttachment, MimeHeaderField } from "./mime.js";
|
|
2
|
+
import { type DecryptionKey } from "./smime.js";
|
|
3
|
+
export interface ProtectedHeaders {
|
|
4
|
+
from: string;
|
|
5
|
+
to: string;
|
|
6
|
+
cc?: string;
|
|
7
|
+
/** An RFC 5322 date string (e.g. `new Date().toUTCString()`-shaped, `Date:`-header ready). */
|
|
8
|
+
date: string;
|
|
9
|
+
subject: string;
|
|
10
|
+
messageId: string;
|
|
11
|
+
}
|
|
12
|
+
/** RFC 9788's `hcp_baseline` Header Confidentiality Policy — the RFC's own required minimum default
|
|
13
|
+
* (Section 3.3). Applied to produce the OUTER, unprotected envelope's headers from the real
|
|
14
|
+
* (protected) ones; `From`/`To`/`Cc`/`Date` pass through unchanged, `Subject` is obscured. */
|
|
15
|
+
export declare function applyBaselineOuterHeaders(headers: ProtectedHeaders): ProtectedHeaders;
|
|
16
|
+
/** One MIME entity's worth of headers-beyond-Content-Type plus body, ready for a caller (the actual
|
|
17
|
+
* outbound-message compose step, built on top of this module) to combine with the outer envelope's
|
|
18
|
+
* own `From`/`To`/`Subject`/`Date`/`Message-ID`. */
|
|
19
|
+
export interface MimePart {
|
|
20
|
+
/** The full `Content-Type` header value, including any parameters. */
|
|
21
|
+
contentType: string;
|
|
22
|
+
/** Any other headers this entity needs (`Content-Transfer-Encoding`, `Content-Disposition`, ...). */
|
|
23
|
+
additionalHeaders?: Record<string, string>;
|
|
24
|
+
body: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Builds a detached `multipart/signed` message with RFC 9788 header protection (`hp="clear"`) — per
|
|
28
|
+
* the spec, the only form signature-only messages may use (opaque signing is reserved for the
|
|
29
|
+
* sign-then-encrypt case in `buildEncryptedMessage()`, where no legacy client is ever exposed to it).
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildSignedOnlyMessage(bodyContentType: string, bodyText: string, protectedHeaders: ProtectedHeaders, signingCertDer: Uint8Array, signingPrivateKey: CryptoKey): Promise<MimePart>;
|
|
32
|
+
export interface ParsedSignedOnlyMessage {
|
|
33
|
+
verified: boolean;
|
|
34
|
+
/** The certificate pkijs matched to the verified SignerInfo (not merely the first embedded one). */
|
|
35
|
+
signerCertificateDer?: Uint8Array;
|
|
36
|
+
protectedHeaders?: ProtectedHeaders;
|
|
37
|
+
/** Every header field of the signed entity, in order, repeats included - lets a caller reject a
|
|
38
|
+
* message carrying more than one protected `From`/`To`/`Cc`/`Sender` (see `messageSecurity.ts`). */
|
|
39
|
+
protectedHeaderFields?: MimeHeaderField[];
|
|
40
|
+
bodyContentType?: string;
|
|
41
|
+
/** The inner entity's body with its Content-Transfer-Encoding/charset decoded (for a multipart inner
|
|
42
|
+
* entity this is the raw multipart text - use `displayBody` for what to render). */
|
|
43
|
+
bodyText?: string;
|
|
44
|
+
/** The displayable body: `html` only for a real text/html part, `text` for text/plain. */
|
|
45
|
+
displayBody?: DisplayBody;
|
|
46
|
+
/** The attachments inside the *signed* entity - the only ones the signature covers. */
|
|
47
|
+
attachments?: MimeAttachment[];
|
|
48
|
+
}
|
|
49
|
+
/** Parses and verifies a `multipart/signed` message (RFC 1847/8551). Returns `{ verified: false }` (never
|
|
50
|
+
* throws) for anything malformed — same "degrade to a failed-signature state, don't crash" contract as
|
|
51
|
+
* `smime.ts`'s own verify functions. Accepts foreign-MUA framing: unquoted/case-varied parameters,
|
|
52
|
+
* preamble/epilogue, transport padding, and a signed part stored with bare-LF line endings (retried in
|
|
53
|
+
* canonical CRLF form, which is what RFC 8551 §3.1.1 says was actually signed). The body must hold exactly two
|
|
54
|
+
* parts (RFC 1847 §2.1): a third part isn't covered by the signature, so a message carrying one is rejected
|
|
55
|
+
* rather than shown - partly unsigned - under a verified badge. */
|
|
56
|
+
export declare function parseSignedOnlyMessage(contentType: string, body: string): Promise<ParsedSignedOnlyMessage>;
|
|
57
|
+
/**
|
|
58
|
+
* Builds an `application/pkcs7-mime; smime-type="enveloped-data"` message with RFC 9788 header
|
|
59
|
+
* protection (`hp="cipher"`), optionally sign-then-encrypt when `signing` is supplied (opaque
|
|
60
|
+
* signing — see this module's own doc comment for why). Per the spec's "Encrypt to Self"
|
|
61
|
+
* requirement, `recipientCertDers` MUST include the sender's own encryption certificate.
|
|
62
|
+
*/
|
|
63
|
+
export declare function buildEncryptedMessage(bodyContentType: string, bodyText: string, protectedHeaders: ProtectedHeaders, outerHeaders: ProtectedHeaders, recipientCertDers: Uint8Array[], signing?: {
|
|
64
|
+
certDer: Uint8Array;
|
|
65
|
+
privateKey: CryptoKey;
|
|
66
|
+
}): Promise<MimePart>;
|
|
67
|
+
/**
|
|
68
|
+
* Combines a `MimePart` (from `buildSignedOnlyMessage()`/`buildEncryptedMessage()`) with the outer
|
|
69
|
+
* envelope's own headers into one complete RFC 5322 message source, ready for `mailApi.ts`'s
|
|
70
|
+
* `assembleDraftRaw()`. `outerHeaders` MUST be the already-obscured headers for an encrypted message
|
|
71
|
+
* (`applyBaselineOuterHeaders()`'s output) - this function does no obscuring itself, it only serializes
|
|
72
|
+
* whatever headers it's given. Deliberately excludes `Bcc`: that recipient list is submission-only and
|
|
73
|
+
* must never appear as a message header (see `AssembleDraftRawInput`'s own doc comment - `bcc` is passed
|
|
74
|
+
* to that call separately, never baked into `rawMime`). Header values are sanitized and RFC 2047-encoded
|
|
75
|
+
* the same way as the protected headers (see `headerLines()`).
|
|
76
|
+
*/
|
|
77
|
+
export declare function assembleOutboundMime(outerHeaders: ProtectedHeaders, part: MimePart): string;
|
|
78
|
+
export interface ParsedEncryptedMessage {
|
|
79
|
+
decrypted: boolean;
|
|
80
|
+
/** Whether an inner (opaque) signature was present and verified - `undefined` when the message
|
|
81
|
+
* was encrypted without also being signed. */
|
|
82
|
+
signatureVerified?: boolean;
|
|
83
|
+
signerCertificateDer?: Uint8Array;
|
|
84
|
+
protectedHeaders?: ProtectedHeaders;
|
|
85
|
+
/** Every header field of the decrypted (and unwrapped) protected entity, in order, repeats included. */
|
|
86
|
+
protectedHeaderFields?: MimeHeaderField[];
|
|
87
|
+
bodyContentType?: string;
|
|
88
|
+
bodyText?: string;
|
|
89
|
+
/** `true` when `actualOuterHeaders` was supplied and disagrees with the `HP-Outer:` field copies
|
|
90
|
+
* found in the decrypted protected content - RFC 9788's own requirement to "visually distinguish a
|
|
91
|
+
* message whose outer and protected headers disagree" (a MITM or malicious intermediary rewrote the
|
|
92
|
+
* unprotected envelope after signing/encryption). `false` when both were supplied and agree.
|
|
93
|
+
* `undefined` when there's nothing to compare - no `actualOuterHeaders` given, or the message
|
|
94
|
+
* carries no `HP-Outer:` lines at all (a foreign sender's S/MIME implementation that doesn't write
|
|
95
|
+
* them, or a message from before this field existed). */
|
|
96
|
+
headerTamperDetected?: boolean;
|
|
97
|
+
/** The displayable body: `html` only for a real text/html part, `text` for text/plain. */
|
|
98
|
+
displayBody?: DisplayBody;
|
|
99
|
+
/** `true` when decryption was refused because the content encryption isn't AEAD (see `smime.ts`'s
|
|
100
|
+
* `UnsupportedContentEncryptionError`) - lets the caller explain that instead of "wrong key". */
|
|
101
|
+
unsupportedContentEncryption?: boolean;
|
|
102
|
+
/** The attachments inside the decrypted (and, when signed, verified) entity. */
|
|
103
|
+
attachments?: MimeAttachment[];
|
|
104
|
+
}
|
|
105
|
+
/** RFC 9788's `HP-Outer:` field-copy fields to actually compare - a subset of `ProtectedHeaders`
|
|
106
|
+
* (`messageId` has no `HP-Outer` counterpart; only the fields the outer envelope itself carries do).
|
|
107
|
+
* Exported so `messageSecurity.ts` can build one from a received message's real outer envelope. */
|
|
108
|
+
export type ComparableOuterHeaders = Partial<Pick<ProtectedHeaders, "from" | "to" | "cc" | "date" | "subject">>;
|
|
109
|
+
/** Decrypts (and, if present, verifies the inner signature of) a message built by
|
|
110
|
+
* `buildEncryptedMessage()`. Returns `{ decrypted: false }` (never throws) for anything malformed or
|
|
111
|
+
* undecryptable with the given key — the caller's own concern is distinguishing "wrong key" from
|
|
112
|
+
* "corrupt message," neither of which this function treats as exceptional.
|
|
113
|
+
*
|
|
114
|
+
* `actualOuterHeaders` — the received message's real, unprotected outer envelope headers (as the
|
|
115
|
+
* caller itself read them, before ever calling this function) — enables the RFC 9788 `HP-Outer`
|
|
116
|
+
* comparison (see `ParsedEncryptedMessage.headerTamperDetected`); omit it to skip that check entirely.
|
|
117
|
+
*/
|
|
118
|
+
export declare function parseEncryptedMessage(base64Body: string, recipientCertDer: Uint8Array, recipientPrivateKey: CryptoKey, actualOuterHeaders?: ComparableOuterHeaders): Promise<ParsedEncryptedMessage>;
|
|
119
|
+
/** `parseEncryptedMessage()` with several candidate keys - the active encryption key first, then retained older ones -
|
|
120
|
+
* decrypted by `smime.ts`'s `decryptEnvelopedDataWithKeys()` (recipient-identifier matching first, then a bounded
|
|
121
|
+
* trial). Same never-throws contract. */
|
|
122
|
+
export declare function parseEncryptedMessageWithKeys(base64Body: string, keys: DecryptionKey[], actualOuterHeaders?: ComparableOuterHeaders): Promise<ParsedEncryptedMessage>;
|
|
123
|
+
/** Splits a MIME entity's raw text into its header lines (lowercased-key map, first occurrence of each
|
|
124
|
+
* name, unfolded) and raw body, plus the entity's own Content-Type value for convenience. Kept for
|
|
125
|
+
* backward compatibility - new code should use `mime.ts`'s `parseMimeEntity()`, which also exposes every
|
|
126
|
+
* repeated field in order. Tolerates bare-LF line endings. */
|
|
127
|
+
export declare function splitHeadersAndBody(entity: string): {
|
|
128
|
+
headers: Record<string, string>;
|
|
129
|
+
contentType?: string;
|
|
130
|
+
body: string;
|
|
131
|
+
rawHeaderBlock: string;
|
|
132
|
+
};
|