@rapidmx/web-client 0.30.0 → 0.32.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/apps/admin/audit-log/index.tsx +3 -3
- package/apps/admin/branding/index.tsx +3 -3
- package/apps/admin/data-requests/index.tsx +18 -7
- package/apps/admin/distribution-lists/[uid].tsx +3 -3
- package/apps/admin/distribution-lists/index.tsx +3 -3
- package/apps/admin/distribution-lists/new/index.tsx +3 -3
- package/apps/admin/domains/[uid].tsx +6 -5
- package/apps/admin/domains/index.tsx +3 -3
- package/apps/admin/domains/new/index.tsx +3 -3
- package/apps/admin/escrow-scopes/[uid].tsx +11 -5
- package/apps/admin/escrow-scopes/index.tsx +3 -3
- package/apps/admin/escrow-scopes/new/index.tsx +9 -3
- package/apps/admin/index.tsx +4 -4
- package/apps/admin/ingest-queue/index.tsx +3 -3
- package/apps/admin/mailboxes/[uid].tsx +15 -7
- package/apps/admin/quarantine/index.tsx +4 -4
- package/apps/admin/retention-policy/index.tsx +3 -3
- package/apps/admin/signing-certificates/index.tsx +3 -3
- package/apps/admin/transport-rules/[uid].tsx +4 -4
- package/apps/admin/transport-rules/index.tsx +3 -3
- package/apps/admin/transport-rules/new/index.tsx +3 -3
- package/apps/escrow/matters/[uid].tsx +26 -2
- package/apps/escrow/matters/new/index.tsx +4 -0
- package/apps/shared/calendar/calendarLiveUpdates.ts +11 -10
- package/apps/shared/calendar/useCalendarReminders.ts +2 -0
- package/apps/shared/components/admin/ActionAlert.tsx +32 -0
- package/apps/shared/components/admin/diagnostics/InformationPanel.tsx +3 -3
- package/apps/shared/components/admin/diagnostics/InstalledPlugins.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/LogsPanel.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/RuntimePanel.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/SystemPanel.tsx +1 -1
- package/apps/shared/components/admin/diagnostics/diagnosticsApi.ts +2 -2
- package/apps/shared/components/admin/distributionLists/MemberListCard.tsx +4 -4
- package/apps/shared/components/admin/elevation.ts +19 -0
- package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +58 -3
- package/apps/shared/components/admin/layout/AdminShell.tsx +6 -1
- package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +3 -3
- package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +4 -4
- package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +4 -4
- package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +3 -3
- package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +6 -6
- package/apps/shared/components/admin/settings/BrandingForm.tsx +22 -9
- package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +4 -4
- package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +33 -4
- package/apps/shared/components/admin/settings/LoadedSettingsForm.tsx +3 -3
- package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +8 -3
- package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +3 -3
- package/apps/shared/components/admin/settings/PluginsManager.tsx +195 -46
- package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +25 -12
- package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +40 -7
- package/apps/shared/components/admin/setup/SetupWizard.tsx +8 -6
- package/apps/shared/components/admin/signOut.ts +3 -0
- package/apps/shared/components/admin/usePagedList.tsx +2 -2
- package/apps/shared/components/calendar/DescriptionEditor.tsx +2 -1
- package/apps/shared/components/calendar/EventDetails.tsx +34 -8
- package/apps/shared/components/calendar/EventEditor.tsx +90 -40
- package/apps/shared/components/calendar/EventFormParts.tsx +5 -2
- package/apps/shared/components/calendar/EventMatchNav.tsx +14 -2
- package/apps/shared/components/calendar/EventModal.tsx +25 -1
- package/apps/shared/components/calendar/FindATime.tsx +10 -2
- package/apps/shared/components/calendar/ListView.tsx +99 -25
- package/apps/shared/components/calendar/RecurrenceEditor.tsx +19 -8
- package/apps/shared/components/calendar/SplitDayView.tsx +14 -18
- package/apps/shared/components/calendar/TaskQuickForm.tsx +3 -2
- package/apps/shared/components/calendar/TimeGridView.tsx +35 -19
- package/apps/shared/components/calendar/gridLayout.ts +94 -0
- package/apps/shared/components/calendar/layout/CalendarShell.tsx +1 -1
- package/apps/shared/components/calendar/timePicker.ts +5 -2
- package/apps/shared/components/contacts/ContactCard.tsx +15 -4
- package/apps/shared/components/contacts/ContactDetailPane.tsx +54 -15
- package/apps/shared/components/contacts/ContactForm.tsx +61 -17
- package/apps/shared/components/contacts/ContactPhotoEditor.tsx +88 -0
- package/apps/shared/components/contacts/ContactPhotoField.tsx +36 -39
- package/apps/shared/components/contacts/layout/ContactsShell.tsx +1 -1
- package/apps/shared/components/contacts/participantDetails.ts +18 -1
- package/apps/shared/components/layout/AppShell.tsx +9 -0
- package/apps/shared/components/layout/KeyEnrollmentGate.tsx +9 -4
- package/apps/shared/components/layout/MailboxProvisioning.tsx +31 -3
- package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +4 -2
- package/apps/shared/components/mail/ConversationList.tsx +49 -6
- package/apps/shared/components/mail/ConversationThreadPane.tsx +1 -1
- package/apps/shared/components/mail/MenuButton.tsx +3 -400
- package/apps/shared/components/mail/MessageDetailPane.tsx +16 -13
- package/apps/shared/components/mail/compose/ComposeToolbar.tsx +11 -1
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +57 -11
- package/apps/shared/components/mail/compose/GifPicker.tsx +10 -4
- package/apps/shared/components/mail/compose/RecipientInput.tsx +9 -7
- package/apps/shared/components/mail/compose/composeFlushRegistry.ts +14 -1
- package/apps/shared/components/mail/compose/encryptionRequirement.ts +5 -0
- package/apps/shared/components/mail/compose/quotedBody.ts +31 -6
- package/apps/shared/components/mail/layout/MailShell.tsx +1 -1
- package/apps/shared/components/mail/reading/MessageBody.tsx +13 -7
- package/apps/shared/components/mail/reading/bodyContent.ts +2 -0
- package/apps/shared/components/mail/reading/bodyHtml.ts +25 -2
- package/apps/shared/components/mail/writableMailboxes.ts +2 -0
- package/apps/shared/components/rules/RuleBuilder.tsx +11 -2
- package/apps/shared/components/settings/GravatarSetting.tsx +27 -0
- package/apps/shared/components/settings/layout/SettingsShell.tsx +1 -1
- package/apps/shared/components/tasks/dueDate.ts +29 -0
- package/apps/shared/components/tasks/layout/TasksShell.tsx +1 -1
- package/apps/shared/mail/decryptedMessages.ts +51 -2
- package/apps/shared/mail/listSnapshots.ts +2 -0
- package/apps/shared/mail/outbox/sendDecision.ts +14 -3
- package/apps/shared/mail/outbox/sendJob.ts +5 -0
- package/apps/shared/mail/useMailLiveUpdates.ts +7 -1
- package/apps/shared/mail/usePermanentDelete.tsx +3 -1
- package/apps/shared/notifications/apiErrors.ts +2 -0
- package/apps/shared/notifications/preferences.ts +1 -1
- package/apps/shared/notifications/store.ts +3 -1
- package/apps/shared/plugins/pluginNav.ts +4 -2
- package/apps/www/calendar/index.tsx +24 -12
- package/apps/www/contacts/[uid].tsx +6 -1
- package/apps/www/contacts/index.tsx +66 -12
- package/apps/www/index.tsx +91 -28
- package/apps/www/messages/[uid].tsx +8 -3
- package/apps/www/settings/auto-reply/index.tsx +13 -0
- package/apps/www/settings/blocked-senders/index.tsx +4 -0
- package/apps/www/settings/encryption/index.tsx +66 -4
- package/apps/www/settings/privacy/index.tsx +4 -1
- package/apps/www/settings/profile/index.tsx +12 -1
- package/apps/www/settings/sharing/index.tsx +11 -1
- package/apps/www/settings/signatures/[uid].tsx +6 -4
- package/apps/www/tasks/index.tsx +97 -29
- package/dist/apps/admin/audit-log/index.js +3 -3
- package/dist/apps/admin/branding/index.js +3 -3
- package/dist/apps/admin/data-requests/index.js +17 -7
- package/dist/apps/admin/distribution-lists/[uid].js +3 -3
- package/dist/apps/admin/distribution-lists/index.js +3 -3
- package/dist/apps/admin/distribution-lists/new/index.js +3 -3
- package/dist/apps/admin/domains/[uid].js +6 -5
- package/dist/apps/admin/domains/index.js +3 -3
- package/dist/apps/admin/domains/new/index.js +3 -3
- package/dist/apps/admin/escrow-scopes/[uid].js +11 -6
- package/dist/apps/admin/escrow-scopes/index.js +3 -3
- package/dist/apps/admin/escrow-scopes/new/index.js +9 -4
- package/dist/apps/admin/index.js +4 -4
- package/dist/apps/admin/ingest-queue/index.js +3 -3
- package/dist/apps/admin/mailboxes/[uid].js +15 -7
- package/dist/apps/admin/quarantine/index.js +4 -4
- package/dist/apps/admin/retention-policy/index.js +3 -3
- package/dist/apps/admin/signing-certificates/index.js +3 -3
- package/dist/apps/admin/transport-rules/[uid].js +4 -4
- package/dist/apps/admin/transport-rules/index.js +3 -3
- package/dist/apps/admin/transport-rules/new/index.js +3 -3
- package/dist/apps/escrow/matters/[uid].js +8 -3
- package/dist/apps/escrow/matters/new/index.js +4 -0
- package/dist/apps/shared/calendar/calendarLiveUpdates.d.ts +11 -7
- package/dist/apps/shared/calendar/calendarLiveUpdates.js +10 -9
- package/dist/apps/shared/calendar/useCalendarReminders.js +2 -0
- package/dist/apps/shared/components/admin/ActionAlert.d.ts +13 -0
- package/dist/apps/shared/components/admin/ActionAlert.js +24 -0
- package/dist/apps/shared/components/admin/diagnostics/InformationPanel.js +2 -2
- package/dist/apps/shared/components/admin/diagnostics/InstalledPlugins.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/LogsPanel.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/RuntimePanel.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/SystemPanel.js +1 -1
- package/dist/apps/shared/components/admin/diagnostics/diagnosticsApi.d.ts +2 -2
- package/dist/apps/shared/components/admin/distributionLists/MemberListCard.js +4 -4
- package/dist/apps/shared/components/admin/elevation.d.ts +9 -0
- package/dist/apps/shared/components/admin/elevation.js +16 -0
- package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.d.ts +2 -0
- package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +41 -1
- package/dist/apps/shared/components/admin/layout/AdminShell.js +2 -1
- package/dist/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.js +3 -3
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +4 -4
- package/dist/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.js +4 -4
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +3 -3
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +6 -6
- package/dist/apps/shared/components/admin/settings/BrandingForm.js +17 -7
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +4 -4
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +17 -5
- package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.js +3 -3
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +8 -3
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +3 -3
- package/dist/apps/shared/components/admin/settings/PluginsManager.js +103 -18
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +17 -10
- package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +18 -8
- package/dist/apps/shared/components/admin/setup/SetupWizard.js +8 -6
- package/dist/apps/shared/components/admin/signOut.js +3 -0
- package/dist/apps/shared/components/admin/usePagedList.js +2 -2
- package/dist/apps/shared/components/calendar/DescriptionEditor.js +2 -1
- package/dist/apps/shared/components/calendar/EventDetails.d.ts +3 -1
- package/dist/apps/shared/components/calendar/EventDetails.js +7 -4
- package/dist/apps/shared/components/calendar/EventEditor.js +81 -33
- package/dist/apps/shared/components/calendar/EventFormParts.d.ts +3 -1
- package/dist/apps/shared/components/calendar/EventFormParts.js +3 -3
- package/dist/apps/shared/components/calendar/EventMatchNav.d.ts +1 -1
- package/dist/apps/shared/components/calendar/EventMatchNav.js +12 -2
- package/dist/apps/shared/components/calendar/EventModal.js +10 -2
- package/dist/apps/shared/components/calendar/FindATime.js +4 -3
- package/dist/apps/shared/components/calendar/ListView.d.ts +10 -4
- package/dist/apps/shared/components/calendar/ListView.js +92 -27
- package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +4 -1
- package/dist/apps/shared/components/calendar/RecurrenceEditor.js +15 -10
- package/dist/apps/shared/components/calendar/SplitDayView.js +11 -17
- package/dist/apps/shared/components/calendar/TaskQuickForm.js +3 -2
- package/dist/apps/shared/components/calendar/TimeGridView.js +23 -21
- package/dist/apps/shared/components/calendar/gridLayout.d.ts +41 -0
- package/dist/apps/shared/components/calendar/gridLayout.js +83 -0
- package/dist/apps/shared/components/calendar/layout/CalendarShell.js +1 -1
- package/dist/apps/shared/components/calendar/timePicker.js +5 -2
- package/dist/apps/shared/components/contacts/ContactCard.js +9 -3
- package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +5 -3
- package/dist/apps/shared/components/contacts/ContactDetailPane.js +11 -5
- package/dist/apps/shared/components/contacts/ContactForm.js +54 -16
- package/dist/apps/shared/components/contacts/ContactPhotoEditor.d.ts +21 -0
- package/dist/apps/shared/components/contacts/ContactPhotoEditor.js +56 -0
- package/dist/apps/shared/components/contacts/ContactPhotoField.d.ts +7 -4
- package/dist/apps/shared/components/contacts/ContactPhotoField.js +19 -21
- package/dist/apps/shared/components/contacts/layout/ContactsShell.js +1 -1
- package/dist/apps/shared/components/contacts/participantDetails.d.ts +4 -1
- package/dist/apps/shared/components/contacts/participantDetails.js +17 -1
- package/dist/apps/shared/components/layout/AppShell.js +9 -0
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +2 -3
- package/dist/apps/shared/components/layout/MailboxProvisioning.d.ts +4 -1
- package/dist/apps/shared/components/layout/MailboxProvisioning.js +24 -2
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +4 -2
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +4 -2
- package/dist/apps/shared/components/mail/ConversationList.js +49 -6
- package/dist/apps/shared/components/mail/ConversationThreadPane.js +1 -1
- package/dist/apps/shared/components/mail/MenuButton.d.ts +2 -78
- package/dist/apps/shared/components/mail/MenuButton.js +2 -211
- package/dist/apps/shared/components/mail/MessageDetailPane.js +10 -6
- package/dist/apps/shared/components/mail/compose/ComposeToolbar.d.ts +3 -0
- package/dist/apps/shared/components/mail/compose/ComposeToolbar.js +10 -1
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +55 -10
- package/dist/apps/shared/components/mail/compose/GifPicker.js +10 -4
- package/dist/apps/shared/components/mail/compose/RecipientInput.js +9 -7
- package/dist/apps/shared/components/mail/compose/composeFlushRegistry.d.ts +7 -1
- package/dist/apps/shared/components/mail/compose/composeFlushRegistry.js +13 -1
- package/dist/apps/shared/components/mail/compose/encryptionRequirement.d.ts +5 -0
- package/dist/apps/shared/components/mail/compose/quotedBody.js +28 -5
- package/dist/apps/shared/components/mail/layout/MailShell.js +1 -1
- package/dist/apps/shared/components/mail/reading/MessageBody.js +11 -6
- package/dist/apps/shared/components/mail/reading/bodyContent.js +2 -0
- package/dist/apps/shared/components/mail/reading/bodyHtml.d.ts +5 -1
- package/dist/apps/shared/components/mail/reading/bodyHtml.js +23 -2
- package/dist/apps/shared/components/mail/writableMailboxes.js +2 -0
- package/dist/apps/shared/components/rules/RuleBuilder.js +9 -1
- package/dist/apps/shared/components/settings/GravatarSetting.d.ts +6 -0
- package/dist/apps/shared/components/settings/GravatarSetting.js +15 -0
- package/dist/apps/shared/components/settings/layout/SettingsShell.js +1 -1
- package/dist/apps/shared/components/tasks/dueDate.d.ts +12 -0
- package/dist/apps/shared/components/tasks/dueDate.js +26 -0
- package/dist/apps/shared/components/tasks/layout/TasksShell.js +1 -1
- package/dist/apps/shared/mail/decryptedMessages.d.ts +8 -0
- package/dist/apps/shared/mail/decryptedMessages.js +46 -2
- package/dist/apps/shared/mail/listSnapshots.js +2 -0
- package/dist/apps/shared/mail/outbox/sendDecision.d.ts +6 -3
- package/dist/apps/shared/mail/outbox/sendDecision.js +13 -3
- package/dist/apps/shared/mail/outbox/sendJob.d.ts +1 -0
- package/dist/apps/shared/mail/outbox/sendJob.js +5 -1
- package/dist/apps/shared/mail/useMailLiveUpdates.d.ts +3 -0
- package/dist/apps/shared/mail/useMailLiveUpdates.js +6 -1
- package/dist/apps/shared/mail/usePermanentDelete.d.ts +2 -0
- package/dist/apps/shared/mail/usePermanentDelete.js +1 -1
- package/dist/apps/shared/notifications/apiErrors.js +2 -0
- package/dist/apps/shared/notifications/preferences.d.ts +1 -1
- package/dist/apps/shared/notifications/preferences.js +1 -1
- package/dist/apps/shared/notifications/store.js +3 -1
- package/dist/apps/shared/plugins/pluginNav.d.ts +2 -1
- package/dist/apps/shared/plugins/pluginNav.js +4 -2
- package/dist/apps/www/calendar/index.js +24 -12
- package/dist/apps/www/contacts/[uid].js +6 -2
- package/dist/apps/www/contacts/index.js +62 -11
- package/dist/apps/www/index.js +85 -30
- package/dist/apps/www/messages/[uid].js +8 -3
- package/dist/apps/www/settings/auto-reply/index.js +13 -1
- package/dist/apps/www/settings/blocked-senders/index.js +4 -0
- package/dist/apps/www/settings/encryption/index.js +29 -5
- package/dist/apps/www/settings/privacy/index.js +3 -2
- package/dist/apps/www/settings/profile/index.js +4 -1
- package/dist/apps/www/settings/sharing/index.js +10 -1
- package/dist/apps/www/settings/signatures/[uid].js +6 -4
- package/dist/apps/www/tasks/index.js +94 -32
- package/dist/lib/admin/auditLogApi.js +2 -2
- package/dist/lib/admin/distributionListsApi.js +2 -2
- package/dist/lib/admin/domainsApi.js +2 -2
- package/dist/lib/admin/escrowAuditLogApi.js +2 -2
- package/dist/lib/admin/escrowScopesApi.js +2 -2
- package/dist/lib/admin/pluginsApi.d.ts +31 -2
- package/dist/lib/admin/pluginsApi.js +23 -1
- package/dist/lib/admin/retentionPolicyApi.d.ts +3 -0
- package/dist/lib/admin/retentionPolicyApi.js +3 -0
- package/dist/lib/admin/transportRulesApi.js +2 -2
- package/dist/lib/appearance/preferencesApi.d.ts +1 -1
- package/dist/lib/appearance/preferencesApi.js +3 -14
- package/dist/lib/auth/session.d.ts +51 -12
- package/dist/lib/auth/session.js +214 -38
- package/dist/lib/branding/brandingApi.d.ts +3 -3
- package/dist/lib/branding/brandingApi.js +9 -21
- package/dist/lib/calendar/calendarApi.js +3 -1
- package/dist/lib/calendar/eventSearch.js +43 -6
- package/dist/lib/calendar/freeBusyApi.d.ts +2 -1
- package/dist/lib/calendar/freeBusyApi.js +13 -5
- package/dist/lib/calendar/recurrence.js +51 -3
- package/dist/lib/calendar/useDayKey.d.ts +7 -0
- package/dist/lib/calendar/useDayKey.js +43 -0
- package/dist/lib/components/avatar/ContactAvatar.d.ts +6 -2
- package/dist/lib/components/avatar/ContactAvatar.js +37 -8
- package/dist/lib/components/avatar/ContactPhotoAvatar.d.ts +11 -0
- package/dist/lib/components/avatar/ContactPhotoAvatar.js +18 -0
- package/dist/lib/components/forms/CameraCaptureModal.d.ts +17 -0
- package/dist/lib/components/forms/CameraCaptureModal.js +88 -0
- package/dist/lib/components/forms/ImageEditBadge.d.ts +28 -0
- package/dist/lib/components/forms/ImageEditBadge.js +62 -0
- package/dist/lib/components/menus/MenuButton.d.ts +78 -0
- package/dist/lib/components/menus/MenuButton.js +219 -0
- package/dist/lib/components/navigation/BottomTabBar.d.ts +3 -1
- package/dist/lib/components/navigation/BottomTabBar.js +22 -3
- package/dist/lib/components/overlays/PopoverPortal.d.ts +2 -1
- package/dist/lib/components/overlays/PopoverPortal.js +3 -2
- package/dist/lib/components/pickers/TimeZonePicker.js +13 -1
- package/dist/lib/contacts/contactsApi.d.ts +5 -2
- package/dist/lib/contacts/contactsApi.js +16 -19
- package/dist/lib/contacts/gravatar.d.ts +14 -3
- package/dist/lib/contacts/gravatar.js +42 -5
- package/dist/lib/contacts/preparePhoto.d.ts +24 -0
- package/dist/lib/contacts/preparePhoto.js +250 -0
- package/dist/lib/contacts/useContactPhotoSrc.d.ts +19 -0
- package/dist/lib/contacts/useContactPhotoSrc.js +153 -0
- package/dist/lib/contacts/vcard.d.ts +3 -0
- package/dist/lib/contacts/vcard.js +59 -7
- package/dist/lib/crypto/escrowKeys.d.ts +8 -0
- package/dist/lib/crypto/escrowKeys.js +20 -1
- package/dist/lib/crypto/messageSecurity.d.ts +7 -4
- package/dist/lib/crypto/messageSecurity.js +23 -5
- package/dist/lib/crypto/passwordUnlock.d.ts +6 -1
- package/dist/lib/crypto/passwordUnlock.js +13 -2
- package/dist/lib/crypto/smime.js +12 -2
- package/dist/lib/mail/compose/composeQuoting.js +3 -2
- package/dist/lib/mail/compose/quotedImages.d.ts +6 -3
- package/dist/lib/mail/compose/quotedImages.js +35 -9
- package/dist/lib/mail/labelsApi.js +2 -2
- package/dist/lib/mail/mailApi.d.ts +8 -5
- package/dist/lib/mail/mailApi.js +73 -39
- package/dist/lib/mail/mailDetailHooks.js +11 -3
- package/dist/lib/mail/mailFilterRulesApi.js +2 -2
- package/dist/lib/mail/mailSignaturesApi.js +2 -2
- package/dist/lib/mail/mailboxImportApi.d.ts +1 -1
- package/dist/lib/mail/mailboxImportApi.js +3 -15
- package/dist/lib/mail/messageBodySanitizer.d.ts +6 -0
- package/dist/lib/mail/messageBodySanitizer.js +44 -1
- package/dist/lib/search/queryGrammar.js +12 -4
- package/dist/lib/search/searchTier3.d.ts +6 -1
- package/dist/lib/search/searchTier3.js +54 -25
- package/dist/lib/tasks/tasksApi.js +3 -3
- package/dist/lib/util/api.d.ts +26 -4
- package/dist/lib/util/api.js +73 -16
- package/dist/lib/util/apiQuery.d.ts +11 -0
- package/dist/lib/util/apiQuery.js +11 -0
- package/dist/lib/util/settleWithLimit.d.ts +5 -0
- package/dist/lib/util/settleWithLimit.js +25 -0
- package/lib/admin/auditLogApi.ts +2 -2
- package/lib/admin/distributionListsApi.ts +2 -2
- package/lib/admin/domainsApi.ts +2 -2
- package/lib/admin/escrowAuditLogApi.ts +2 -2
- package/lib/admin/escrowScopesApi.ts +2 -2
- package/lib/admin/pluginsApi.ts +45 -3
- package/lib/admin/retentionPolicyApi.ts +4 -0
- package/lib/admin/transportRulesApi.ts +2 -2
- package/lib/appearance/preferencesApi.ts +3 -14
- package/lib/auth/session.ts +239 -39
- package/lib/branding/brandingApi.ts +9 -21
- package/lib/calendar/calendarApi.ts +3 -1
- package/lib/calendar/eventSearch.ts +46 -6
- package/lib/calendar/freeBusyApi.ts +14 -6
- package/lib/calendar/recurrence.ts +59 -8
- package/lib/calendar/useDayKey.ts +45 -0
- package/lib/components/avatar/ContactAvatar.tsx +46 -8
- package/lib/components/avatar/ContactPhotoAvatar.tsx +26 -0
- package/lib/components/forms/CameraCaptureModal.tsx +133 -0
- package/lib/components/forms/ImageEditBadge.tsx +121 -0
- package/lib/components/menus/MenuButton.tsx +408 -0
- package/lib/components/navigation/BottomTabBar.tsx +30 -8
- package/lib/components/overlays/PopoverPortal.tsx +3 -2
- package/lib/components/pickers/TimeZonePicker.tsx +17 -1
- package/lib/contacts/contactsApi.ts +18 -19
- package/lib/contacts/gravatar.ts +47 -5
- package/lib/contacts/preparePhoto.ts +273 -0
- package/lib/contacts/useContactPhotoSrc.ts +177 -0
- package/lib/contacts/vcard.ts +60 -7
- package/lib/crypto/escrowKeys.ts +21 -1
- package/lib/crypto/messageSecurity.ts +33 -9
- package/lib/crypto/passwordUnlock.ts +14 -2
- package/lib/crypto/smime.ts +13 -2
- package/lib/mail/compose/composeQuoting.ts +3 -2
- package/lib/mail/compose/quotedImages.ts +39 -9
- package/lib/mail/labelsApi.ts +2 -2
- package/lib/mail/mailApi.ts +96 -39
- package/lib/mail/mailDetailHooks.ts +11 -3
- package/lib/mail/mailFilterRulesApi.ts +2 -2
- package/lib/mail/mailSignaturesApi.ts +2 -2
- package/lib/mail/mailboxImportApi.ts +9 -15
- package/lib/mail/messageBodySanitizer.ts +47 -1
- package/lib/search/queryGrammar.ts +13 -4
- package/lib/search/searchTier3.ts +65 -32
- package/lib/tasks/tasksApi.ts +3 -3
- package/lib/util/api.ts +99 -16
- package/lib/util/apiQuery.ts +13 -0
- package/lib/util/settleWithLimit.ts +25 -0
- package/package.json +1 -1
package/lib/util/api.ts
CHANGED
|
@@ -157,12 +157,18 @@ export async function apiFetch<T = unknown>(path: string, init: RequestInit = {}
|
|
|
157
157
|
applyCsrfHeader(headers, init.method);
|
|
158
158
|
const credentials = apiBaseUrl ? "include" : init.credentials;
|
|
159
159
|
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
const res = await fetchWithRecovery(path, { ...init, headers, credentials });
|
|
161
|
+
return decodeApiResponse<T>(res, (error) => unauthorizedObserver?.(error));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** `fetch()` of `path` against the global origin. When the access token has run out (a sleeping tab or laptop stops the timer that renews it in
|
|
165
|
+
* time) it renews the session, and asks again once. */
|
|
166
|
+
async function fetchWithRecovery(path: string, init: RequestInit): Promise<Response> {
|
|
167
|
+
let res = await fetch(apiUrl(path), init);
|
|
162
168
|
if (res.status === 401 && sessionRecovery && (await recoverSession())) {
|
|
163
|
-
res = await fetch(apiUrl(path),
|
|
169
|
+
res = await fetch(apiUrl(path), init);
|
|
164
170
|
}
|
|
165
|
-
return
|
|
171
|
+
return res;
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
let sessionRecovery: (() => Promise<boolean>) | undefined;
|
|
@@ -196,15 +202,16 @@ async function recoverSession(): Promise<boolean> {
|
|
|
196
202
|
* a deployment-level requirement owned by auth-server/the Helm chart, not configured here — and auth-server's
|
|
197
203
|
* CORS config must explicitly allow this app's origin with credentials.
|
|
198
204
|
*
|
|
199
|
-
* `
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
205
|
+
* No `x-csrf-token` header is sent, deliberately. A double-submit token is only meaningful to the server that issued it, and the `csrf`
|
|
206
|
+
* cookie this app's JavaScript can read is *this* host's own (`mail.example.com`), never auth-server's - so echoing it
|
|
207
|
+
* would be a wrong token for the wrong server. Worse, auth-server's CORS rules do not allow that header, so the browser
|
|
208
|
+
* blocked the preflight of every such call (the silent session refresh, sign-out) before it ever reached the server: "Request header
|
|
209
|
+
* field x-csrf-token is not allowed by Access-Control-Allow-Headers". Auth-server's CSRF protection for this cross-origin call shape is
|
|
210
|
+
* its Origin allow-list check, which needs no header.
|
|
203
211
|
*/
|
|
204
212
|
export async function authApiFetch<T = unknown>(authServerUrl: string, path: string, init: RequestInit = {}): Promise<T> {
|
|
205
213
|
const headers = new Headers(init.headers);
|
|
206
214
|
headers.set("Content-Type", "application/json");
|
|
207
|
-
applyCsrfHeader(headers, init.method);
|
|
208
215
|
|
|
209
216
|
const res = await fetch(`${authServerUrl}/api${path}`, { ...init, headers, credentials: "include" });
|
|
210
217
|
return decodeApiResponse<T>(res);
|
|
@@ -228,13 +235,19 @@ export function setApiUnauthorizedObserver(observer: ((error: ApiRequestError) =
|
|
|
228
235
|
* `createApiClient()`-made client's `fetch()` (which forwards to that instance's own
|
|
229
236
|
* `setUnauthorizedObserver()`) pass their own. A throwing `onUnauthorized` never changes what the caller sees.
|
|
230
237
|
*/
|
|
231
|
-
async function decodeApiResponse<T>(
|
|
238
|
+
async function decodeApiResponse<T>(
|
|
239
|
+
res: Response,
|
|
240
|
+
onUnauthorized?: (error: ApiRequestError) => void,
|
|
241
|
+
failureMessage: string = "Request failed.",
|
|
242
|
+
): Promise<T> {
|
|
232
243
|
const contentType = res.headers.get("content-type") ?? "";
|
|
233
244
|
const body = contentType.includes("application/json") ? await res.json().catch(() => undefined) : undefined;
|
|
234
245
|
|
|
235
246
|
if (!res.ok) {
|
|
236
|
-
|
|
237
|
-
const
|
|
247
|
+
// A body is untrusted: only a non-empty string is a message (anything else would read "[object Object]"), only a string a code.
|
|
248
|
+
const reported = body && (body.message || body.error);
|
|
249
|
+
const message = (typeof reported === "string" && reported) || res.statusText || failureMessage;
|
|
250
|
+
const error = new ApiRequestError(message, res.status, typeof body?.code === "string" ? body.code : undefined, body);
|
|
238
251
|
if (res.status === 401 && onUnauthorized) {
|
|
239
252
|
try {
|
|
240
253
|
onUnauthorized(error);
|
|
@@ -259,6 +272,12 @@ export interface ApiClient {
|
|
|
259
272
|
/** Same contract as `apiFetch()`: prefixes `path` with `/api`, parses a JSON response, and rejects with
|
|
260
273
|
* `ApiRequestError` on a non-ok response. */
|
|
261
274
|
fetch<T = unknown>(path: string, init?: RequestInit): Promise<T>;
|
|
275
|
+
/**
|
|
276
|
+
* Like `fetch()` - same origin, authentication and error decoding - but resolves the response's own bytes instead of parsing JSON, for a picture or other
|
|
277
|
+
* file. An `<img src>` cannot send an `Authorization` header, so a token-authenticated client shows such a file by fetching it here and displaying a
|
|
278
|
+
* `blob:` URL. No `Content-Type` is added.
|
|
279
|
+
*/
|
|
280
|
+
fetchBlob(path: string, init?: RequestInit): Promise<Blob>;
|
|
262
281
|
/**
|
|
263
282
|
* This client instance's own `setApiUnauthorizedObserver()` equivalent - see `createApiClient()`'s doc
|
|
264
283
|
* comment for why it is per-instance rather than shared with the module-level `setApiUnauthorizedObserver()`
|
|
@@ -308,18 +327,34 @@ export function createApiClient(options: CreateApiClientOptions): ApiClient {
|
|
|
308
327
|
const { getAccessToken } = options;
|
|
309
328
|
let unauthorizedObserver: ((error: ApiRequestError) => void) | undefined;
|
|
310
329
|
|
|
311
|
-
async function
|
|
330
|
+
async function send(path: string, init: RequestInit, json: boolean): Promise<Response> {
|
|
312
331
|
const headers = new Headers(init.headers);
|
|
313
|
-
|
|
332
|
+
// JSON unless the caller sent a body of its own kind (an upload names the file's type).
|
|
333
|
+
if (json && !headers.has("Content-Type")) {
|
|
334
|
+
headers.set("Content-Type", "application/json");
|
|
335
|
+
}
|
|
314
336
|
const token = await getAccessToken();
|
|
315
337
|
headers.set("Authorization", `jwt ${token}`);
|
|
316
338
|
|
|
317
|
-
|
|
318
|
-
|
|
339
|
+
return fetch(`${baseUrl}/api${path}`, { ...init, headers });
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async function clientFetch<T = unknown>(path: string, init: RequestInit = {}): Promise<T> {
|
|
343
|
+
return decodeApiResponse<T>(await send(path, init, true), (error) => unauthorizedObserver?.(error));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async function clientFetchBlob(path: string, init: RequestInit = {}): Promise<Blob> {
|
|
347
|
+
const res = await send(path, init, false);
|
|
348
|
+
if (!res.ok) {
|
|
349
|
+
// Throws the same `ApiRequestError` (and tells the observer of a 401) as every other request.
|
|
350
|
+
await decodeApiResponse<never>(res, (error) => unauthorizedObserver?.(error));
|
|
351
|
+
}
|
|
352
|
+
return res.blob();
|
|
319
353
|
}
|
|
320
354
|
|
|
321
355
|
return {
|
|
322
356
|
fetch: clientFetch,
|
|
357
|
+
fetchBlob: clientFetchBlob,
|
|
323
358
|
setUnauthorizedObserver(observer) {
|
|
324
359
|
unauthorizedObserver = observer;
|
|
325
360
|
},
|
|
@@ -339,3 +374,51 @@ export function createApiClient(options: CreateApiClientOptions): ApiClient {
|
|
|
339
374
|
export function withClient<T = unknown>(client: ApiClient | undefined, path: string, init?: RequestInit): Promise<T> {
|
|
340
375
|
return client ? client.fetch<T>(path, init) : apiFetch<T>(path, init);
|
|
341
376
|
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Sends a file's own bytes (not JSON) to `path` - the upload counterpart of `withClient()`. With an explicit `client` the request goes through it, so it
|
|
380
|
+
* reaches that account's origin with its token (the client keeps the `Content-Type` given here). Without one it is a plain `fetch()` to the global
|
|
381
|
+
* origin that carries the `jwt` cookie and the CSRF header, exactly as a same-origin upload always was. Resolves the decoded JSON response and rejects with
|
|
382
|
+
* an `ApiRequestError` (`failureMessage` when the server gave no message) on a non-ok one.
|
|
383
|
+
*/
|
|
384
|
+
export async function withClientRaw<T = unknown>(
|
|
385
|
+
client: ApiClient | undefined,
|
|
386
|
+
path: string,
|
|
387
|
+
method: string,
|
|
388
|
+
file: Blob,
|
|
389
|
+
contentType: string = file.type,
|
|
390
|
+
failureMessage: string = "Upload failed.",
|
|
391
|
+
): Promise<T> {
|
|
392
|
+
if (client) {
|
|
393
|
+
return client.fetch<T>(path, { method, headers: { "Content-Type": contentType }, body: file });
|
|
394
|
+
}
|
|
395
|
+
const res = await fetchWithRecovery(path, {
|
|
396
|
+
method,
|
|
397
|
+
credentials: "include",
|
|
398
|
+
headers: withCsrfHeader({ "Content-Type": contentType }, method),
|
|
399
|
+
body: file,
|
|
400
|
+
});
|
|
401
|
+
return decodeApiResponse<T>(res, (error) => unauthorizedObserver?.(error), failureMessage);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Fetches `path`'s own bytes (a message's raw source, say) rather than JSON - the download counterpart of `withClient()`. With an explicit `client` the
|
|
406
|
+
* request goes through its `fetchBlob()`, so it reaches that account's origin with its token. Without one it is a plain `fetch()` to the global origin
|
|
407
|
+
* with the `jwt` cookie, renewing the session and asking again once on a `401`, as `apiFetch()` does. Rejects with an `ApiRequestError`
|
|
408
|
+
* (`failureMessage` when the server gave no message) on a non-ok response.
|
|
409
|
+
*/
|
|
410
|
+
export async function withClientBlob(
|
|
411
|
+
client: ApiClient | undefined,
|
|
412
|
+
path: string,
|
|
413
|
+
failureMessage: string = "Download failed.",
|
|
414
|
+
): Promise<Blob> {
|
|
415
|
+
if (client) {
|
|
416
|
+
return client.fetchBlob(path);
|
|
417
|
+
}
|
|
418
|
+
const res = await fetchWithRecovery(path, { credentials: "include" });
|
|
419
|
+
if (!res.ok) {
|
|
420
|
+
// Throws the same `ApiRequestError` (and tells the observer of a 401) as every other request.
|
|
421
|
+
await decodeApiResponse<never>(res, (error) => unauthorizedObserver?.(error), failureMessage);
|
|
422
|
+
}
|
|
423
|
+
return res.blob();
|
|
424
|
+
}
|
package/lib/util/apiQuery.ts
CHANGED
|
@@ -16,6 +16,10 @@ export interface ListParams {
|
|
|
16
16
|
|
|
17
17
|
const DEFAULT_PAGE_SIZE = 25;
|
|
18
18
|
|
|
19
|
+
/** The page size of a list that a settings screen shows whole (labels, signatures, filter rules, task lists, contact lists): a few dozen rows at most in practice, so one
|
|
20
|
+
* large page rather than the default 25 that would hide everything after the 25th with no way to reach it. */
|
|
21
|
+
export const SETTINGS_LIST_LIMIT = 200;
|
|
22
|
+
|
|
19
23
|
/**
|
|
20
24
|
* Builds a `limit`/`page` query string, plus any extra scope/filter params (e.g. `folderUid`,
|
|
21
25
|
* or one of `@rapidmx/restapi`'s generic query-operator values like `startDate=lte(...)`).
|
|
@@ -28,6 +32,15 @@ export function buildQuery(params: ListParams, extra: Record<string, string> = {
|
|
|
28
32
|
return parts.join("&");
|
|
29
33
|
}
|
|
30
34
|
|
|
35
|
+
/**
|
|
36
|
+
* The `sort` query value for `buildQuery()`'s extra params, in the order the keys are given. Paging with no sort leaves the order to the
|
|
37
|
+
* database, which on SQL can repeat or skip a row between two pages and on MongoDB is the oldest first: end the sort with a unique key (`uid`)
|
|
38
|
+
* so every row lands on exactly one page.
|
|
39
|
+
*/
|
|
40
|
+
export function sortQuery(sort: Record<string, "ASC" | "DESC">): { sort: string } {
|
|
41
|
+
return { sort: JSON.stringify(sort) };
|
|
42
|
+
}
|
|
43
|
+
|
|
31
44
|
/**
|
|
32
45
|
* Optional paging/scope params for the async-request list endpoints (`listExportRequests()`,
|
|
33
46
|
* `listImportRequests()`, `listErasureRequests()`, `listMatterExportRequests()`,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Runs `task` for each of `items`, never more than `limit` of them at once, and resolves to what became of every one in the order of `items`, as
|
|
8
|
+
* `Promise.allSettled()` does - a task that fails does not stop the others. For a batch of requests too big to send all at once (a thousand rows ticked).
|
|
9
|
+
*/
|
|
10
|
+
export async function settleWithLimit<T, R>(items: readonly T[], limit: number, task: (item: T) => Promise<R>): Promise<PromiseSettledResult<R>[]> {
|
|
11
|
+
const outcomes = new Array<PromiseSettledResult<R>>(items.length);
|
|
12
|
+
let next = 0;
|
|
13
|
+
async function worker() {
|
|
14
|
+
while (next < items.length) {
|
|
15
|
+
const index = next++;
|
|
16
|
+
try {
|
|
17
|
+
outcomes[index] = { status: "fulfilled", value: await task(items[index]) };
|
|
18
|
+
} catch (reason) {
|
|
19
|
+
outcomes[index] = { status: "rejected", reason };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
|
|
24
|
+
return outcomes;
|
|
25
|
+
}
|
package/package.json
CHANGED