@rapidmx/web-client 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +415 -381
- package/apps/admin/_layout.tsx +2 -2
- package/apps/admin/audit-log/index.tsx +4 -4
- package/apps/admin/branding/index.tsx +39 -39
- package/apps/admin/data-requests/index.tsx +482 -482
- 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 +166 -166
- 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 +350 -350
- package/apps/admin/escrow-scopes/index.tsx +4 -4
- package/apps/admin/escrow-scopes/new/index.tsx +5 -5
- package/apps/admin/index.tsx +129 -129
- package/apps/admin/ingest-queue/index.tsx +4 -4
- package/apps/admin/mailbox-policy/index.tsx +1 -1
- package/apps/admin/mailboxes/[uid].tsx +271 -271
- package/apps/admin/mailboxes/new/index.tsx +30 -30
- package/apps/admin/plugins/index.tsx +15 -15
- package/apps/admin/quarantine/index.tsx +5 -5
- package/apps/admin/retention-policy/index.tsx +39 -39
- package/apps/admin/signing-certificates/index.tsx +343 -343
- 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 +196 -196
- package/apps/escrow/index.tsx +4 -4
- package/apps/escrow/matters/[uid].tsx +621 -621
- 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 +99 -99
- 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 +384 -384
- package/apps/shared/components/admin/mailboxes/EraseLeftoverDataDialog.tsx +238 -238
- package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +154 -152
- package/apps/shared/components/admin/mailboxes/LeftoverMailboxesSection.tsx +194 -194
- 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 +423 -423
- package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +5 -5
- package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +119 -119
- 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 +198 -198
- package/apps/shared/components/admin/settings/PluginsManager.tsx +2093 -2093
- package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +182 -182
- package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +288 -288
- package/apps/shared/components/admin/setup/SetupWizard.tsx +450 -446
- package/apps/shared/components/admin/signOut.ts +1 -1
- package/apps/shared/components/admin/usePagedList.tsx +129 -129
- 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 +206 -206
- 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 +185 -185
- 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 +227 -227
- 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 +144 -144
- package/apps/shared/components/calendar/TaskQuickForm.tsx +23 -18
- package/apps/shared/components/calendar/TimeGridView.tsx +246 -246
- package/apps/shared/components/calendar/allDay.ts +124 -124
- 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 +393 -383
- package/apps/shared/components/contacts/ContactsSidebar.tsx +7 -5
- package/apps/shared/components/contacts/ContactsToolbar.tsx +103 -103
- 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 +155 -155
- package/apps/shared/components/forms/StringListField.tsx +1 -1
- package/apps/shared/components/layout/AppShell.tsx +465 -461
- package/apps/shared/components/layout/BrandingChrome.tsx +1 -1
- package/apps/shared/components/layout/KeyEnrollmentGate.tsx +398 -398
- package/apps/shared/components/layout/MailboxProvisioning.tsx +170 -168
- package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +9 -9
- package/apps/shared/components/layout/ResponsiveToolbar.tsx +315 -315
- package/apps/shared/components/layout/ThemeSwitch.tsx +84 -84
- package/apps/shared/components/layout/UnlockPromptProvider.tsx +6 -6
- package/apps/shared/components/layout/UserMenu.tsx +441 -439
- package/apps/shared/components/mail/ConversationList.tsx +334 -332
- package/apps/shared/components/mail/ConversationThreadPane.tsx +624 -613
- 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 +240 -240
- package/apps/shared/components/mail/MenuButton.tsx +404 -404
- package/apps/shared/components/mail/MessageDetailPane.tsx +1759 -1757
- 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 +323 -312
- package/apps/shared/components/mail/compose/ComposeToolbar.tsx +422 -422
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +1709 -1681
- 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/RichTextEditor.tsx +147 -147
- package/apps/shared/components/mail/compose/ScheduleSendPicker.tsx +1 -1
- package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -60
- package/apps/shared/components/mail/compose/encryptionRequirement.ts +2 -2
- package/apps/shared/components/mail/compose/quotedBody.ts +161 -161
- package/apps/shared/components/mail/compose/recipients.ts +1 -1
- package/apps/shared/components/mail/invite/InviteRowChip.tsx +2 -2
- package/apps/shared/components/mail/invite/InviteRsvpPopover.tsx +9 -7
- 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/MessageMoreMenu.tsx +258 -258
- package/apps/shared/components/mail/reading/MessageSourceDialog.tsx +79 -79
- 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/messageExport.ts +59 -59
- package/apps/shared/components/mail/reading/printMessage.ts +99 -99
- package/apps/shared/components/mail/reading/useMessageActions.ts +450 -443
- package/apps/shared/components/mail/unreadStyle.tsx +1 -1
- package/apps/shared/components/mail/verificationSeals.ts +129 -125
- package/apps/shared/components/mail/writableMailboxes.ts +14 -7
- package/apps/shared/components/rules/RuleBuilder.tsx +311 -311
- package/apps/shared/components/settings/SigningCertificateCard.tsx +344 -344
- 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/GlobalShortcuts.tsx +51 -51
- package/apps/shared/keyboard/ShortcutProvider.tsx +62 -62
- package/apps/shared/keyboard/ShortcutsDialog.tsx +84 -84
- package/apps/shared/keyboard/dispatch.ts +124 -124
- package/apps/shared/keyboard/format.ts +89 -89
- package/apps/shared/keyboard/keymap.ts +114 -114
- package/apps/shared/keyboard/registry.ts +65 -65
- package/apps/shared/keyboard/targets.ts +79 -79
- package/apps/shared/mail/findWellKnownFolderUid.ts +6 -4
- package/apps/shared/mail/folderCounts.ts +8 -4
- package/apps/shared/mail/folderOfType.ts +51 -49
- package/apps/shared/mail/folderTree.ts +143 -143
- package/apps/shared/mail/listAllPages.ts +39 -39
- package/apps/shared/mail/listSnapshots.ts +2 -2
- package/apps/shared/mail/messageReadState.ts +6 -5
- package/apps/shared/mail/newMailNotifications.ts +171 -171
- 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 +450 -445
- package/apps/shared/mail/outbox/sendOutcomes.ts +160 -155
- 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 +66 -66
- package/apps/shared/mail/senderBlocking.ts +157 -141
- package/apps/shared/mail/useMailConnection.ts +207 -205
- package/apps/shared/mail/useMailLiveUpdates.ts +277 -277
- package/apps/shared/mail/useMailboxUpdateAccess.ts +84 -60
- package/apps/shared/mail/useMarkMessageRead.ts +54 -47
- package/apps/shared/mail/useNewMailNotifications.ts +178 -178
- 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/store.ts +560 -560
- package/apps/shared/notifications/systemErrors.ts +1 -1
- package/apps/shared/search/LocalIndexLifecycle.tsx +120 -114
- package/apps/shared/search/crossMailboxSearch.ts +3 -3
- package/apps/shared/search/localIndexBuilder.ts +493 -481
- 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/enrollmentStorage.ts +33 -33
- package/apps/shared/signing/enrollmentTracker.ts +385 -385
- package/apps/shared/signing/enrollmentView.ts +251 -251
- package/apps/shared/signing/signingInfo.ts +1 -1
- package/apps/shared/signing/useNow.ts +19 -19
- package/apps/shared/signing/useSigningEnrollmentWatcher.ts +92 -90
- package/apps/shared/styles/app.css +387 -396
- package/apps/www/_layout.tsx +2 -2
- package/apps/www/calendar/index.tsx +583 -581
- package/apps/www/contacts/[uid].tsx +114 -112
- package/apps/www/contacts/index.tsx +19 -17
- package/apps/www/index.tsx +3021 -3012
- package/apps/www/messages/[uid].tsx +141 -139
- package/apps/www/settings/auto-reply/index.tsx +138 -136
- package/apps/www/settings/blocked-senders/index.tsx +305 -303
- package/apps/www/settings/encryption/index.tsx +1296 -1290
- package/apps/www/settings/filters/[uid].tsx +184 -179
- package/apps/www/settings/filters/_mailFilterRuleConfig.tsx +2 -2
- package/apps/www/settings/filters/index.tsx +105 -105
- package/apps/www/settings/filters/new/index.tsx +167 -165
- package/apps/www/settings/labels/index.tsx +209 -207
- package/apps/www/settings/privacy/index.tsx +499 -495
- package/apps/www/settings/profile/index.tsx +256 -251
- package/apps/www/settings/read-receipts/index.tsx +155 -150
- package/apps/www/settings/sharing/index.tsx +259 -259
- package/apps/www/settings/signatures/[uid].tsx +175 -175
- package/apps/www/settings/signatures/index.tsx +91 -91
- package/apps/www/settings/signatures/new/index.tsx +138 -138
- package/apps/www/settings/signatures/signatureDefaults.ts +1 -1
- package/apps/www/tasks/index.tsx +659 -654
- 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 +8 -8
- 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 +8 -8
- 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.js +26 -22
- 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 +1 -1
- 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 +7 -7
- 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 +14 -10
- 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 +6 -4
- package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +3 -3
- package/dist/apps/shared/components/mail/ConversationThreadPane.js +13 -11
- 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 +30 -28
- 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.d.ts +7 -1
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +54 -31
- 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 +1 -1
- package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.d.ts +1 -1
- package/dist/apps/shared/components/mail/invite/InviteRsvpPopover.js +9 -7
- 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/messageExport.js +1 -1
- package/dist/apps/shared/components/mail/reading/printMessage.d.ts +2 -2
- package/dist/apps/shared/components/mail/reading/printMessage.js +11 -11
- 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/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 +387 -396
- 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 +54 -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,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed wrappers over `@rapidmx/restapi`'s `TransportRule` CRUD route (`BaseTransportRuleRoute`) —
|
|
3
|
+
* trusted-role-only, org-wide (evaluated once per SMTP transaction, before per-mailbox fan-out). No
|
|
4
|
+
* uid-derivation on create (unlike `Domain`/`Mailbox`/`DistributionList`) — a transport rule has no
|
|
5
|
+
* natural address of its own.
|
|
6
|
+
*/
|
|
7
|
+
import { ApiClient } from "../util/api.js";
|
|
8
|
+
import { ListParams } from "../util/apiQuery.js";
|
|
9
|
+
export type { ListParams };
|
|
10
|
+
export type TransportRuleActionType = "reject" | "quarantine" | "add_header" | "add_recipient";
|
|
11
|
+
export interface TransportRuleAction {
|
|
12
|
+
type: TransportRuleActionType;
|
|
13
|
+
/** Required for `add_header`. */
|
|
14
|
+
headerName?: string;
|
|
15
|
+
/** Required for `add_header`. */
|
|
16
|
+
headerValue?: string;
|
|
17
|
+
/** Required for `add_recipient`. */
|
|
18
|
+
recipientAddress?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface TransportRuleConditions {
|
|
21
|
+
fromContains?: string[];
|
|
22
|
+
subjectContains?: string[];
|
|
23
|
+
bodyContains?: string[];
|
|
24
|
+
recipientContains?: string[];
|
|
25
|
+
anyRecipientExternal?: boolean;
|
|
26
|
+
hasAttachment?: boolean;
|
|
27
|
+
attachmentNameContains?: string[];
|
|
28
|
+
}
|
|
29
|
+
export interface TransportRule {
|
|
30
|
+
uid: string;
|
|
31
|
+
version: number;
|
|
32
|
+
dateCreated: string;
|
|
33
|
+
dateModified: string;
|
|
34
|
+
name: string;
|
|
35
|
+
enabled: boolean;
|
|
36
|
+
sequence: number;
|
|
37
|
+
stopProcessingRules: boolean;
|
|
38
|
+
conditions: TransportRuleConditions;
|
|
39
|
+
actions: TransportRuleAction[];
|
|
40
|
+
}
|
|
41
|
+
/** `client`, given by every function below, is an explicit `ApiClient` from `createApiClient()` (e.g. one
|
|
42
|
+
* account of a multi-account app) to call instead of the default global `apiFetch()` - see `withClient()`'s
|
|
43
|
+
* own doc comment in `util/api.ts`. Omitted (the default), every function here behaves exactly as before. */
|
|
44
|
+
export declare function listTransportRules(params?: ListParams, client?: ApiClient): Promise<TransportRule[]>;
|
|
45
|
+
export declare function getTransportRule(uid: string, client?: ApiClient): Promise<TransportRule>;
|
|
46
|
+
export interface CreateTransportRuleInput {
|
|
47
|
+
name: string;
|
|
48
|
+
enabled?: boolean;
|
|
49
|
+
sequence?: number;
|
|
50
|
+
stopProcessingRules?: boolean;
|
|
51
|
+
conditions?: TransportRuleConditions;
|
|
52
|
+
actions?: TransportRuleAction[];
|
|
53
|
+
}
|
|
54
|
+
export declare function createTransportRule(input: CreateTransportRuleInput, client?: ApiClient): Promise<TransportRule>;
|
|
55
|
+
export interface UpdateTransportRuleInput {
|
|
56
|
+
uid: string;
|
|
57
|
+
version: number;
|
|
58
|
+
name?: string;
|
|
59
|
+
enabled?: boolean;
|
|
60
|
+
sequence?: number;
|
|
61
|
+
stopProcessingRules?: boolean;
|
|
62
|
+
conditions?: TransportRuleConditions;
|
|
63
|
+
actions?: TransportRuleAction[];
|
|
64
|
+
}
|
|
65
|
+
export declare function updateTransportRule(input: UpdateTransportRuleInput, client?: ApiClient): Promise<TransportRule>;
|
|
66
|
+
export declare function deleteTransportRule(uid: string, version: number, client?: ApiClient): Promise<void>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
/**
|
|
6
|
+
* Typed wrappers over `@rapidmx/restapi`'s `TransportRule` CRUD route (`BaseTransportRuleRoute`) —
|
|
7
|
+
* trusted-role-only, org-wide (evaluated once per SMTP transaction, before per-mailbox fan-out). No
|
|
8
|
+
* uid-derivation on create (unlike `Domain`/`Mailbox`/`DistributionList`) — a transport rule has no
|
|
9
|
+
* natural address of its own.
|
|
10
|
+
*/
|
|
11
|
+
import { withClient } from "../util/api.js";
|
|
12
|
+
import { buildQuery } from "../util/apiQuery.js";
|
|
13
|
+
/** `client`, given by every function below, is an explicit `ApiClient` from `createApiClient()` (e.g. one
|
|
14
|
+
* account of a multi-account app) to call instead of the default global `apiFetch()` - see `withClient()`'s
|
|
15
|
+
* own doc comment in `util/api.ts`. Omitted (the default), every function here behaves exactly as before. */
|
|
16
|
+
export function listTransportRules(params = {}, client) {
|
|
17
|
+
return withClient(client, `/mail/transport-rules?${buildQuery(params)}`);
|
|
18
|
+
}
|
|
19
|
+
export function getTransportRule(uid, client) {
|
|
20
|
+
return withClient(client, `/mail/transport-rules/${encodeURIComponent(uid)}`);
|
|
21
|
+
}
|
|
22
|
+
export function createTransportRule(input, client) {
|
|
23
|
+
return withClient(client, "/mail/transport-rules", {
|
|
24
|
+
method: "POST",
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
enabled: true,
|
|
27
|
+
sequence: 0,
|
|
28
|
+
stopProcessingRules: false,
|
|
29
|
+
conditions: {},
|
|
30
|
+
actions: [],
|
|
31
|
+
...input,
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function updateTransportRule(input, client) {
|
|
36
|
+
return withClient(client, `/mail/transport-rules/${encodeURIComponent(input.uid)}`, {
|
|
37
|
+
method: "PUT",
|
|
38
|
+
body: JSON.stringify(input),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export function deleteTransportRule(uid, version, client) {
|
|
42
|
+
return withClient(client, `/mail/transport-rules/${encodeURIComponent(uid)}?version=${version}`, { method: "DELETE" });
|
|
43
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed client for the signed-in user's appearance preferences - their colour scheme, theme colours and app background
|
|
3
|
+
* (`@rapidmx/restapi`'s `/mail/preferences/appearance` routes):
|
|
4
|
+
*
|
|
5
|
+
* - `GET /mail/preferences/appearance` reads the `AppearancePreferences` object (never a 404: a user with none gets the defaults). `PUT`
|
|
6
|
+
* the same path **merges** a partial `AppearanceUpdate` into it (each colour and each background field on its own; `null` clears a
|
|
7
|
+
* colour) and answers with the saved object - so a client sends what changed (`diffAppearance()`), never the whole thing.
|
|
8
|
+
* - `POST /mail/preferences/appearance/background` stores the request body (a raw image, `Content-Type` = the file's own) as the
|
|
9
|
+
* background and answers with the updated preferences; `DELETE` the same path removes it.
|
|
10
|
+
* - `GET /mail/preferences/appearance/background/:version` is the image itself - immutable per version, so an `<img>`/CSS `url()`
|
|
11
|
+
* pointing at `appearanceBackgroundUrl()` is cached for good.
|
|
12
|
+
* - A change is also pushed to the user's other tabs and devices as `{ type: /^AppearancePreferences/, action: "update", data }` on
|
|
13
|
+
* the user's own uid channel - `parseAppearanceEvent()` reads it.
|
|
14
|
+
*
|
|
15
|
+
* Everything that comes from outside - the response, a push event, the page's server-rendered props, `localStorage` - goes through
|
|
16
|
+
* `normalizeAppearance()`, which keeps only well-formed values (so a stale or hostile value can never reach a CSS declaration).
|
|
17
|
+
*/
|
|
18
|
+
import { ApiClient } from "../util/api.js";
|
|
19
|
+
export type AppearanceMode = "system" | "light" | "dark";
|
|
20
|
+
export type BackgroundKind = "none" | "color" | "image";
|
|
21
|
+
export type BackgroundFit = "cover" | "contain" | "tile";
|
|
22
|
+
/** Theme colours, each `#rrggbb` and each optional: an unset one keeps the app's (or the deployment's branding's) own. */
|
|
23
|
+
export interface AppearanceColors {
|
|
24
|
+
primary?: string;
|
|
25
|
+
accent?: string;
|
|
26
|
+
surface?: string;
|
|
27
|
+
text?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface AppearanceBackground {
|
|
30
|
+
kind: BackgroundKind;
|
|
31
|
+
/** `kind: "color"`: the colour. `kind: "image"`: the colour shown behind the image (letterboxing, while it loads). `#rrggbb`. */
|
|
32
|
+
color?: string;
|
|
33
|
+
/** Which stored image `kind: "image"` shows - part of its URL (`appearanceBackgroundUrl()`), so a new upload is a new URL. */
|
|
34
|
+
imageVersion?: string | number;
|
|
35
|
+
/** How much of the scheme's surface colour is laid over the image, `0` to `BACKGROUND_DIM_MAX`. */
|
|
36
|
+
dim: number;
|
|
37
|
+
/** Blur radius in CSS pixels, `0` to `BACKGROUND_BLUR_MAX`. */
|
|
38
|
+
blur: number;
|
|
39
|
+
fit: BackgroundFit;
|
|
40
|
+
}
|
|
41
|
+
export interface AppearancePreferences {
|
|
42
|
+
version: 1;
|
|
43
|
+
mode: AppearanceMode;
|
|
44
|
+
colors?: AppearanceColors;
|
|
45
|
+
background?: AppearanceBackground;
|
|
46
|
+
/** When the server last stored these. Opaque to the client (compared for equality, never parsed). */
|
|
47
|
+
updatedAt?: string | number;
|
|
48
|
+
}
|
|
49
|
+
/** Preferences without the server's own timestamp. */
|
|
50
|
+
export type AppearanceInput = Omit<AppearancePreferences, "updatedAt">;
|
|
51
|
+
/**
|
|
52
|
+
* What `PUT` takes, a partial that the server merges into what is stored: `mode`; `colors` (a colour is set by its `#rrggbb` and cleared by
|
|
53
|
+
* `null`, and `colors: null` clears all four); `background` (any of its fields, merged one by one - `color: null` clears the colour). It cannot
|
|
54
|
+
* name an `imageVersion` (uploading is what makes one), and `kind: "image"` needs an image already uploaded.
|
|
55
|
+
*/
|
|
56
|
+
export interface AppearanceUpdate {
|
|
57
|
+
version?: 1;
|
|
58
|
+
mode?: AppearanceMode;
|
|
59
|
+
colors?: Partial<Record<ColorKey, string | null>> | null;
|
|
60
|
+
background?: Partial<Omit<AppearanceBackground, "color" | "imageVersion">> & {
|
|
61
|
+
color?: string | null;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export declare const APPEARANCE_MODES: readonly AppearanceMode[];
|
|
65
|
+
export declare const BACKGROUND_KINDS: readonly BackgroundKind[];
|
|
66
|
+
export declare const BACKGROUND_FITS: readonly BackgroundFit[];
|
|
67
|
+
export declare const COLOR_KEYS: readonly ["primary", "accent", "surface", "text"];
|
|
68
|
+
export type ColorKey = (typeof COLOR_KEYS)[number];
|
|
69
|
+
/** The largest dim the server accepts - beyond it the picture is not worth having. */
|
|
70
|
+
export declare const BACKGROUND_DIM_MAX = 0.8;
|
|
71
|
+
/** The largest blur, in CSS pixels. */
|
|
72
|
+
export declare const BACKGROUND_BLUR_MAX = 20;
|
|
73
|
+
/** The image types a background may be - raster only: an SVG is a document that can carry script. */
|
|
74
|
+
export declare const BACKGROUND_IMAGE_TYPES: readonly string[];
|
|
75
|
+
/** The largest background image, in bytes. */
|
|
76
|
+
export declare const BACKGROUND_MAX_BYTES: number;
|
|
77
|
+
/** The preferences a user who never chose anything has. */
|
|
78
|
+
export declare const DEFAULT_APPEARANCE: AppearanceInput;
|
|
79
|
+
/** The starting background when the user first picks a kind: a light dim and no blur, covering the whole app. */
|
|
80
|
+
export declare const DEFAULT_BACKGROUND: AppearanceBackground;
|
|
81
|
+
/**
|
|
82
|
+
* The well-formed part of `value` as `AppearancePreferences`, or `undefined` when it is not preferences at all (not an object, or not
|
|
83
|
+
* `version: 1`). Unknown keys are dropped, colours must be `#rrggbb` (lower-cased), numbers are clamped into their range, and an enum
|
|
84
|
+
* that isn't one of its values falls back to the default - so what comes out is always safe to turn into CSS.
|
|
85
|
+
*/
|
|
86
|
+
export declare function normalizeAppearance(value: unknown): AppearancePreferences | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* The reason `file` can't be a background, worded for the person choosing it, or `undefined` when it can. Checked before anything is
|
|
89
|
+
* uploaded (the server checks again). Takes anything with a `type` and a `size`, so it is testable without a real `File`.
|
|
90
|
+
*/
|
|
91
|
+
export declare function validateBackgroundFile(file: {
|
|
92
|
+
type: string;
|
|
93
|
+
size: number;
|
|
94
|
+
}): string | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* The `PUT` that takes what the server has (`server`, `undefined` for nothing yet) to `next`: only what differs, in the merge form the
|
|
97
|
+
* server takes - a colour that is gone is `null`, all of them gone is `colors: null`, and a background that is gone is `kind: "none"`
|
|
98
|
+
* (the server refuses `background: null`). `undefined` when there is nothing to send. The image is never named: its `imageVersion` is
|
|
99
|
+
* the server's to choose, and `kind: "image"` is only sent once `next` shows the very image the server holds - an image that is still
|
|
100
|
+
* uploading (a version the server doesn't know) can't be switched to yet.
|
|
101
|
+
*/
|
|
102
|
+
export declare function diffAppearance(server: AppearancePreferences | undefined, next: AppearanceInput): AppearanceUpdate | undefined;
|
|
103
|
+
/** `true` when nothing meaningful is set - a user who has changed nothing, or reset everything. */
|
|
104
|
+
export declare function isDefaultAppearance(prefs: AppearanceInput | undefined): boolean;
|
|
105
|
+
/** `client`, given by every function below that isn't a raw-bytes upload, is an explicit `ApiClient` from
|
|
106
|
+
* `createApiClient()` (e.g. one account of a multi-account app) to call instead of the default global
|
|
107
|
+
* `apiFetch()` - see `withClient()`'s own doc comment in `util/api.ts`. Omitted (the default), every
|
|
108
|
+
* function here behaves exactly as before. */
|
|
109
|
+
/** The user's stored preferences, or `undefined` when there are none to read (a `404`, or a body that isn't preferences). */
|
|
110
|
+
export declare function getAppearance(client?: ApiClient): Promise<AppearancePreferences | undefined>;
|
|
111
|
+
/** Merges `update` into the user's preferences and returns what the server stored. */
|
|
112
|
+
export declare function saveAppearance(update: AppearanceUpdate, client?: ApiClient): Promise<AppearancePreferences>;
|
|
113
|
+
/** Stores `file` (already checked with `validateBackgroundFile()`) as the background: its raw bytes, with its own content type - which
|
|
114
|
+
* bypasses `apiFetch()`, as it always sends JSON. Answers with the updated preferences. */
|
|
115
|
+
export declare function uploadAppearanceBackground(file: Blob): Promise<AppearancePreferences>;
|
|
116
|
+
/** Removes the stored background image. Answers with the updated preferences when the server sends them, else `undefined`. */
|
|
117
|
+
export declare function deleteAppearanceBackground(client?: ApiClient): Promise<AppearancePreferences | undefined>;
|
|
118
|
+
/** The URL of the stored background image `version` - what CSS `url()` and `<img src>` use. Immutable per version. */
|
|
119
|
+
export declare function appearanceBackgroundUrl(version: string | number): string;
|
|
120
|
+
/**
|
|
121
|
+
* What a push event says about the appearance: the new preferences for a `create`/`update` of an `AppearancePreferences...` model
|
|
122
|
+
* (whose `data` normalises), `null` for its `delete` (the user's back to the defaults), and `undefined` for any other event.
|
|
123
|
+
*/
|
|
124
|
+
export declare function parseAppearanceEvent(event: {
|
|
125
|
+
type: string;
|
|
126
|
+
action?: string;
|
|
127
|
+
data?: unknown;
|
|
128
|
+
}): AppearancePreferences | null | undefined;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
/**
|
|
6
|
+
* Typed client for the signed-in user's appearance preferences - their colour scheme, theme colours and app background
|
|
7
|
+
* (`@rapidmx/restapi`'s `/mail/preferences/appearance` routes):
|
|
8
|
+
*
|
|
9
|
+
* - `GET /mail/preferences/appearance` reads the `AppearancePreferences` object (never a 404: a user with none gets the defaults). `PUT`
|
|
10
|
+
* the same path **merges** a partial `AppearanceUpdate` into it (each colour and each background field on its own; `null` clears a
|
|
11
|
+
* colour) and answers with the saved object - so a client sends what changed (`diffAppearance()`), never the whole thing.
|
|
12
|
+
* - `POST /mail/preferences/appearance/background` stores the request body (a raw image, `Content-Type` = the file's own) as the
|
|
13
|
+
* background and answers with the updated preferences; `DELETE` the same path removes it.
|
|
14
|
+
* - `GET /mail/preferences/appearance/background/:version` is the image itself - immutable per version, so an `<img>`/CSS `url()`
|
|
15
|
+
* pointing at `appearanceBackgroundUrl()` is cached for good.
|
|
16
|
+
* - A change is also pushed to the user's other tabs and devices as `{ type: /^AppearancePreferences/, action: "update", data }` on
|
|
17
|
+
* the user's own uid channel - `parseAppearanceEvent()` reads it.
|
|
18
|
+
*
|
|
19
|
+
* Everything that comes from outside - the response, a push event, the page's server-rendered props, `localStorage` - goes through
|
|
20
|
+
* `normalizeAppearance()`, which keeps only well-formed values (so a stale or hostile value can never reach a CSS declaration).
|
|
21
|
+
*/
|
|
22
|
+
import { ApiRequestError, apiUrl, withClient, withCsrfHeader } from "../util/api.js";
|
|
23
|
+
export const APPEARANCE_MODES = ["system", "light", "dark"];
|
|
24
|
+
export const BACKGROUND_KINDS = ["none", "color", "image"];
|
|
25
|
+
export const BACKGROUND_FITS = ["cover", "contain", "tile"];
|
|
26
|
+
export const COLOR_KEYS = ["primary", "accent", "surface", "text"];
|
|
27
|
+
/** The largest dim the server accepts - beyond it the picture is not worth having. */
|
|
28
|
+
export const BACKGROUND_DIM_MAX = 0.8;
|
|
29
|
+
/** The largest blur, in CSS pixels. */
|
|
30
|
+
export const BACKGROUND_BLUR_MAX = 20;
|
|
31
|
+
/** The image types a background may be - raster only: an SVG is a document that can carry script. */
|
|
32
|
+
export const BACKGROUND_IMAGE_TYPES = ["image/png", "image/jpeg", "image/webp", "image/avif"];
|
|
33
|
+
/** The largest background image, in bytes. */
|
|
34
|
+
export const BACKGROUND_MAX_BYTES = 8 * 1024 * 1024;
|
|
35
|
+
/** The preferences a user who never chose anything has. */
|
|
36
|
+
export const DEFAULT_APPEARANCE = { version: 1, mode: "system" };
|
|
37
|
+
/** The starting background when the user first picks a kind: a light dim and no blur, covering the whole app. */
|
|
38
|
+
export const DEFAULT_BACKGROUND = { kind: "none", dim: 0.2, blur: 0, fit: "cover" };
|
|
39
|
+
const HEX_COLOR = /^#[0-9a-f]{6}$/i;
|
|
40
|
+
/** An image version becomes part of a URL path: only characters that need no escaping. */
|
|
41
|
+
const IMAGE_VERSION = /^[A-Za-z0-9._-]{1,64}$/;
|
|
42
|
+
function isRecord(value) {
|
|
43
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44
|
+
}
|
|
45
|
+
function hexOrUndefined(value) {
|
|
46
|
+
return typeof value === "string" && HEX_COLOR.test(value) ? value.toLowerCase() : undefined;
|
|
47
|
+
}
|
|
48
|
+
function clampNumber(value, min, max, fallback) {
|
|
49
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.min(max, Math.max(min, value)) : fallback;
|
|
50
|
+
}
|
|
51
|
+
function normalizeBackground(value) {
|
|
52
|
+
if (!isRecord(value)) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const color = hexOrUndefined(value.color);
|
|
56
|
+
const rawVersion = value.imageVersion;
|
|
57
|
+
const imageVersion = typeof rawVersion === "number" && Number.isFinite(rawVersion) && rawVersion >= 0
|
|
58
|
+
? rawVersion
|
|
59
|
+
: typeof rawVersion === "string" && IMAGE_VERSION.test(rawVersion)
|
|
60
|
+
? rawVersion
|
|
61
|
+
: undefined;
|
|
62
|
+
let kind = BACKGROUND_KINDS.includes(value.kind) ? value.kind : "none";
|
|
63
|
+
// A kind without what it shows is nothing: an "image" that has no stored image, a "color" with no colour.
|
|
64
|
+
if ((kind === "image" && imageVersion === undefined) || (kind === "color" && color === undefined)) {
|
|
65
|
+
kind = "none";
|
|
66
|
+
}
|
|
67
|
+
const background = {
|
|
68
|
+
kind,
|
|
69
|
+
dim: clampNumber(value.dim, 0, BACKGROUND_DIM_MAX, DEFAULT_BACKGROUND.dim),
|
|
70
|
+
blur: clampNumber(value.blur, 0, BACKGROUND_BLUR_MAX, DEFAULT_BACKGROUND.blur),
|
|
71
|
+
fit: BACKGROUND_FITS.includes(value.fit) ? value.fit : DEFAULT_BACKGROUND.fit,
|
|
72
|
+
};
|
|
73
|
+
if (color !== undefined) {
|
|
74
|
+
background.color = color;
|
|
75
|
+
}
|
|
76
|
+
if (imageVersion !== undefined) {
|
|
77
|
+
background.imageVersion = imageVersion;
|
|
78
|
+
}
|
|
79
|
+
return background;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The well-formed part of `value` as `AppearancePreferences`, or `undefined` when it is not preferences at all (not an object, or not
|
|
83
|
+
* `version: 1`). Unknown keys are dropped, colours must be `#rrggbb` (lower-cased), numbers are clamped into their range, and an enum
|
|
84
|
+
* that isn't one of its values falls back to the default - so what comes out is always safe to turn into CSS.
|
|
85
|
+
*/
|
|
86
|
+
export function normalizeAppearance(value) {
|
|
87
|
+
if (!isRecord(value) || value.version !== 1) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const prefs = {
|
|
91
|
+
version: 1,
|
|
92
|
+
mode: APPEARANCE_MODES.includes(value.mode) ? value.mode : "system",
|
|
93
|
+
};
|
|
94
|
+
if (isRecord(value.colors)) {
|
|
95
|
+
const colors = {};
|
|
96
|
+
for (const key of COLOR_KEYS) {
|
|
97
|
+
const hex = hexOrUndefined(value.colors[key]);
|
|
98
|
+
if (hex !== undefined) {
|
|
99
|
+
colors[key] = hex;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (Object.keys(colors).length > 0) {
|
|
103
|
+
prefs.colors = colors;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const background = normalizeBackground(value.background);
|
|
107
|
+
if (background) {
|
|
108
|
+
prefs.background = background;
|
|
109
|
+
}
|
|
110
|
+
if (typeof value.updatedAt === "string" || (typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt))) {
|
|
111
|
+
prefs.updatedAt = value.updatedAt;
|
|
112
|
+
}
|
|
113
|
+
return prefs;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The reason `file` can't be a background, worded for the person choosing it, or `undefined` when it can. Checked before anything is
|
|
117
|
+
* uploaded (the server checks again). Takes anything with a `type` and a `size`, so it is testable without a real `File`.
|
|
118
|
+
*/
|
|
119
|
+
export function validateBackgroundFile(file) {
|
|
120
|
+
if (!BACKGROUND_IMAGE_TYPES.includes(file.type)) {
|
|
121
|
+
return "Choose a PNG, JPEG, WebP or AVIF image.";
|
|
122
|
+
}
|
|
123
|
+
if (file.size > BACKGROUND_MAX_BYTES) {
|
|
124
|
+
return `That image is ${(file.size / (1024 * 1024)).toFixed(1)} MB; the limit is ${BACKGROUND_MAX_BYTES / (1024 * 1024)} MB.`;
|
|
125
|
+
}
|
|
126
|
+
if (file.size === 0) {
|
|
127
|
+
return "That file is empty.";
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
const PATH = "/mail/preferences/appearance";
|
|
132
|
+
/** What a background is until the user sets anything, as the server has it. */
|
|
133
|
+
const SERVER_DEFAULT_BACKGROUND = { kind: "none", dim: 0, blur: 0, fit: "cover" };
|
|
134
|
+
/**
|
|
135
|
+
* The `PUT` that takes what the server has (`server`, `undefined` for nothing yet) to `next`: only what differs, in the merge form the
|
|
136
|
+
* server takes - a colour that is gone is `null`, all of them gone is `colors: null`, and a background that is gone is `kind: "none"`
|
|
137
|
+
* (the server refuses `background: null`). `undefined` when there is nothing to send. The image is never named: its `imageVersion` is
|
|
138
|
+
* the server's to choose, and `kind: "image"` is only sent once `next` shows the very image the server holds - an image that is still
|
|
139
|
+
* uploading (a version the server doesn't know) can't be switched to yet.
|
|
140
|
+
*/
|
|
141
|
+
export function diffAppearance(server, next) {
|
|
142
|
+
const update = {};
|
|
143
|
+
if (next.mode !== (server?.mode ?? "system")) {
|
|
144
|
+
update.mode = next.mode;
|
|
145
|
+
}
|
|
146
|
+
const colors = {};
|
|
147
|
+
for (const key of COLOR_KEYS) {
|
|
148
|
+
if (next.colors?.[key] !== server?.colors?.[key]) {
|
|
149
|
+
colors[key] = next.colors?.[key] ?? null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (Object.keys(colors).length > 0) {
|
|
153
|
+
update.colors = !next.colors ? null : colors;
|
|
154
|
+
}
|
|
155
|
+
const base = server?.background ?? SERVER_DEFAULT_BACKGROUND;
|
|
156
|
+
const wanted = next.background;
|
|
157
|
+
if (!wanted) {
|
|
158
|
+
if (base.kind !== "none") {
|
|
159
|
+
update.background = { kind: "none" };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const changes = {};
|
|
164
|
+
const heldImage = wanted.imageVersion !== undefined && wanted.imageVersion === base.imageVersion;
|
|
165
|
+
if (wanted.kind !== base.kind && (wanted.kind !== "image" || heldImage)) {
|
|
166
|
+
changes.kind = wanted.kind;
|
|
167
|
+
}
|
|
168
|
+
if (wanted.color !== base.color) {
|
|
169
|
+
changes.color = wanted.color ?? null;
|
|
170
|
+
}
|
|
171
|
+
for (const key of ["dim", "blur", "fit"]) {
|
|
172
|
+
if (wanted[key] !== base[key]) {
|
|
173
|
+
changes[key] = wanted[key];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (Object.keys(changes).length > 0) {
|
|
177
|
+
update.background = changes;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return Object.keys(update).length > 0 ? { version: 1, ...update } : undefined;
|
|
181
|
+
}
|
|
182
|
+
/** `true` when nothing meaningful is set - a user who has changed nothing, or reset everything. */
|
|
183
|
+
export function isDefaultAppearance(prefs) {
|
|
184
|
+
return (!prefs ||
|
|
185
|
+
(prefs.mode === "system" &&
|
|
186
|
+
!prefs.colors &&
|
|
187
|
+
(!prefs.background || prefs.background.kind === "none")));
|
|
188
|
+
}
|
|
189
|
+
/** `client`, given by every function below that isn't a raw-bytes upload, is an explicit `ApiClient` from
|
|
190
|
+
* `createApiClient()` (e.g. one account of a multi-account app) to call instead of the default global
|
|
191
|
+
* `apiFetch()` - see `withClient()`'s own doc comment in `util/api.ts`. Omitted (the default), every
|
|
192
|
+
* function here behaves exactly as before. */
|
|
193
|
+
/** The user's stored preferences, or `undefined` when there are none to read (a `404`, or a body that isn't preferences). */
|
|
194
|
+
export async function getAppearance(client) {
|
|
195
|
+
try {
|
|
196
|
+
return normalizeAppearance(await withClient(client, PATH));
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
if (err instanceof ApiRequestError && err.status === 404) {
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
throw err;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** Merges `update` into the user's preferences and returns what the server stored. */
|
|
206
|
+
export async function saveAppearance(update, client) {
|
|
207
|
+
const stored = normalizeAppearance(await withClient(client, PATH, { method: "PUT", body: JSON.stringify(update) }));
|
|
208
|
+
if (!stored) {
|
|
209
|
+
throw new ApiRequestError("The server did not return the saved appearance.", 502);
|
|
210
|
+
}
|
|
211
|
+
return stored;
|
|
212
|
+
}
|
|
213
|
+
/** Stores `file` (already checked with `validateBackgroundFile()`) as the background: its raw bytes, with its own content type - which
|
|
214
|
+
* bypasses `apiFetch()`, as it always sends JSON. Answers with the updated preferences. */
|
|
215
|
+
export async function uploadAppearanceBackground(file) {
|
|
216
|
+
const res = await fetch(apiUrl(`${PATH}/background`), {
|
|
217
|
+
method: "POST",
|
|
218
|
+
credentials: "include",
|
|
219
|
+
headers: withCsrfHeader({ "Content-Type": file.type || "application/octet-stream" }),
|
|
220
|
+
body: file,
|
|
221
|
+
});
|
|
222
|
+
const contentType = res.headers.get("content-type") ?? "";
|
|
223
|
+
const body = contentType.includes("application/json") ? await res.json().catch(() => undefined) : undefined;
|
|
224
|
+
if (!res.ok) {
|
|
225
|
+
const message = (body && (body.message || body.error)) || res.statusText || "Upload failed.";
|
|
226
|
+
throw new ApiRequestError(message, res.status, body?.code);
|
|
227
|
+
}
|
|
228
|
+
const stored = normalizeAppearance(body);
|
|
229
|
+
if (!stored) {
|
|
230
|
+
throw new ApiRequestError("The server did not return the saved appearance.", 502);
|
|
231
|
+
}
|
|
232
|
+
return stored;
|
|
233
|
+
}
|
|
234
|
+
/** Removes the stored background image. Answers with the updated preferences when the server sends them, else `undefined`. */
|
|
235
|
+
export async function deleteAppearanceBackground(client) {
|
|
236
|
+
return normalizeAppearance(await withClient(client, `${PATH}/background`, { method: "DELETE" }));
|
|
237
|
+
}
|
|
238
|
+
/** The URL of the stored background image `version` - what CSS `url()` and `<img src>` use. Immutable per version. */
|
|
239
|
+
export function appearanceBackgroundUrl(version) {
|
|
240
|
+
return apiUrl(`${PATH}/background/${encodeURIComponent(String(version))}`);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* What a push event says about the appearance: the new preferences for a `create`/`update` of an `AppearancePreferences...` model
|
|
244
|
+
* (whose `data` normalises), `null` for its `delete` (the user's back to the defaults), and `undefined` for any other event.
|
|
245
|
+
*/
|
|
246
|
+
export function parseAppearanceEvent(event) {
|
|
247
|
+
if (!/^AppearancePreferences/.test(event.type)) {
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
if (event.action === "delete") {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
if (event.action === "update" || event.action === "create") {
|
|
254
|
+
return normalizeAppearance(event.data);
|
|
255
|
+
}
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface Profile {
|
|
2
|
+
uid: string;
|
|
3
|
+
/** URL to the user's avatar image (e.g. gravatar). Absent for most password-registered accounts. */
|
|
4
|
+
avatar?: string;
|
|
5
|
+
givenName?: string;
|
|
6
|
+
familyName?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Fetches the signed-in caller's own profile — `"me"` resolves to the caller's own uid server-side. */
|
|
9
|
+
export declare function getMyProfile(authServerUrl: string): Promise<Profile>;
|
|
10
|
+
/**
|
|
11
|
+
* One of the caller's own aliases as auth-server's `GET /api/aliases` returns it - only the fields read here.
|
|
12
|
+
* `type: "name"` is a username (the local part of a mailbox address); `verified` is false until it's confirmed.
|
|
13
|
+
*/
|
|
14
|
+
export interface Alias {
|
|
15
|
+
alias: string;
|
|
16
|
+
type: string;
|
|
17
|
+
verified?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The caller's username - their first verified auth-server alias of type `name` (`GET /api/aliases?type=name`,
|
|
21
|
+
* which lists only the caller's own). The display-name fallback for an account with no profile name: some
|
|
22
|
+
* accounts have no profile document at all (`/profiles/me` is a 404 for them), yet every account has a
|
|
23
|
+
* username. Never rejects - a failed call, an unexpected body or no verified name alias all resolve
|
|
24
|
+
* `undefined`, since a missing nicety must not surface as an error.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getMyUsername(authServerUrl: string): Promise<string | undefined>;
|
|
27
|
+
/** `"Jane Doe"`, `"Jane"`, `"Doe"`, or `undefined` if neither name field is set. */
|
|
28
|
+
export declare function formatProfileName(profile: Pick<Profile, "givenName" | "familyName"> | undefined): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* A 1-2 letter initials badge, derived from the profile's name, else the first letter of `username` (see
|
|
31
|
+
* `getMyUsername()`), else the first letter of the given uid.
|
|
32
|
+
*/
|
|
33
|
+
export declare function profileInitials(profile: Pick<Profile, "givenName" | "familyName"> | undefined, uid: string, username?: string): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
/**
|
|
6
|
+
* Typed wrapper over `@rapidrest/auth`'s `BaseProfileRoute`, mounted by auth-server at `/api/profiles`. Used
|
|
7
|
+
* for the signed-in user's own display name/avatar in the top-right user menu (see `UserMenu.tsx`) — this
|
|
8
|
+
* service has no local user directory of its own (see `.claude/NOTES.md`), so name/avatar can only ever come
|
|
9
|
+
* from auth-server.
|
|
10
|
+
*
|
|
11
|
+
* Deliberately NOT given the explicit-`ApiClient` `client?` parameter every other converted module in this
|
|
12
|
+
* package has — see `withClient()`'s doc comment in `util/api.ts`. Both `getMyProfile()` and `getMyUsername()`
|
|
13
|
+
* already take an explicit `authServerUrl` targeting a *different* origin than this app's own API (auth-server,
|
|
14
|
+
* not the RapidMX server `ApiClient`/`apiFetch()` talk to) — the same shape as `mailApi.ts`'s `impersonateUser()`/
|
|
15
|
+
* `stopImpersonating()`, which is why those were left unconverted too. A per-account auth-server session (the
|
|
16
|
+
* multi-account app's own credentials for *that* origin, not this app's) is a separate future change, out of
|
|
17
|
+
* scope here.
|
|
18
|
+
*/
|
|
19
|
+
import { authApiFetch } from "../util/api.js";
|
|
20
|
+
/** Fetches the signed-in caller's own profile — `"me"` resolves to the caller's own uid server-side. */
|
|
21
|
+
export function getMyProfile(authServerUrl) {
|
|
22
|
+
return authApiFetch(authServerUrl, "/profiles/me");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The caller's username - their first verified auth-server alias of type `name` (`GET /api/aliases?type=name`,
|
|
26
|
+
* which lists only the caller's own). The display-name fallback for an account with no profile name: some
|
|
27
|
+
* accounts have no profile document at all (`/profiles/me` is a 404 for them), yet every account has a
|
|
28
|
+
* username. Never rejects - a failed call, an unexpected body or no verified name alias all resolve
|
|
29
|
+
* `undefined`, since a missing nicety must not surface as an error.
|
|
30
|
+
*/
|
|
31
|
+
export async function getMyUsername(authServerUrl) {
|
|
32
|
+
try {
|
|
33
|
+
const aliases = await authApiFetch(authServerUrl, "/aliases?type=name");
|
|
34
|
+
return Array.isArray(aliases) ? aliases.find((a) => a?.type === "name" && a.verified === true && !!a.alias)?.alias : undefined;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** `"Jane Doe"`, `"Jane"`, `"Doe"`, or `undefined` if neither name field is set. */
|
|
41
|
+
export function formatProfileName(profile) {
|
|
42
|
+
const name = [profile?.givenName, profile?.familyName].filter(Boolean).join(" ").trim();
|
|
43
|
+
return name || undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A 1-2 letter initials badge, derived from the profile's name, else the first letter of `username` (see
|
|
47
|
+
* `getMyUsername()`), else the first letter of the given uid.
|
|
48
|
+
*/
|
|
49
|
+
export function profileInitials(profile, uid, username) {
|
|
50
|
+
const initials = [profile?.givenName?.[0], profile?.familyName?.[0]].filter(Boolean).join("");
|
|
51
|
+
return (initials || username?.[0] || uid[0] || "?").toUpperCase();
|
|
52
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** An access token's age at which it is refreshed. The token lives an hour; the margin leaves time to retry a failed refresh. */
|
|
2
|
+
export declare const SESSION_REFRESH_AFTER_MS: number;
|
|
3
|
+
/** How often an open page checks whether its token is due. Also what retries a refresh that failed for a transient reason. */
|
|
4
|
+
export declare const SESSION_REFRESH_CHECK_MS: number;
|
|
5
|
+
/** A reload that follows a successful recovery refresh but still finds no session is not repeated within this window. */
|
|
6
|
+
export declare const SESSION_RELOAD_GUARD_MS: number;
|
|
7
|
+
/**
|
|
8
|
+
* Refreshes the signed-in session through auth-server: exchanges the `refresh` cookie for a new access token and
|
|
9
|
+
* refresh token, both set as cookies on the response. Rejects with the `ApiRequestError` auth-server answered
|
|
10
|
+
* (`401`/`403` when the refresh token has expired or was revoked).
|
|
11
|
+
*
|
|
12
|
+
* A refresh token is single-use and bound to the session, so two tabs refreshing at once would make the second one look
|
|
13
|
+
* like a dead session. Refreshes are therefore serialised across tabs (Web Locks, where the browser has them) and each
|
|
14
|
+
* tab records when the last one happened, so a tab that gets its turn right after another tab refreshed does nothing.
|
|
15
|
+
*
|
|
16
|
+
* @param force Refresh even when the last refresh, by this tab or another, was recent.
|
|
17
|
+
* @returns `true` when a refresh was made, `false` when one was not needed.
|
|
18
|
+
*/
|
|
19
|
+
export declare function refreshSession(authServerUrl: string, force?: boolean): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Redirects the browser to auth-server's sign-in page when `userUid` is absent, carrying the current URL as
|
|
22
|
+
* `return_to` so auth-server can send the browser back here afterward. A no-op once `userUid` is present.
|
|
23
|
+
*
|
|
24
|
+
* This does not try to recover the session first; `useSessionRefresh()` does, and is what an app frame should call.
|
|
25
|
+
*
|
|
26
|
+
* A no-op under an `ApiClientContext.Provider` (see `useSessionRefresh()`'s own doc comment for why) — there is
|
|
27
|
+
* no `jwt` cookie in that context for `userUid` to ever meaningfully reflect, and redirecting to auth-server's
|
|
28
|
+
* cookie-based sign-in page would be wrong for a session whose lifecycle a host app's own `ApiClient` manages.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useRedirectIfUnauthenticated(userUid: string | undefined, authServerUrl: string | undefined): void;
|
|
31
|
+
/** Options for `useSessionRefresh()`. */
|
|
32
|
+
export interface SessionRefreshOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Do not refresh, and send a page with no session straight to sign-in. For a session whose access token was not
|
|
35
|
+
* issued from the refresh token in its cookie: an admin viewing as another user holds that user's token beside their
|
|
36
|
+
* own refresh token, and a refresh would silently swap the admin back in.
|
|
37
|
+
*/
|
|
38
|
+
paused?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Runs before the browser leaves for sign-in because a refresh was refused while the page still had a session - the
|
|
41
|
+
* access token in hand is valid for a while yet, so this is the moment to save work in progress. The caller bounds how
|
|
42
|
+
* long it takes; a rejection is ignored and never stops the redirect.
|
|
43
|
+
*/
|
|
44
|
+
beforeRedirect?: () => Promise<unknown>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Keeps a page's session alive for as long as auth-server's refresh token is valid, so the user is not sent to sign in
|
|
48
|
+
* again every time the access token's hour is up:
|
|
49
|
+
*
|
|
50
|
+
* - `userUid` unset (the page was rendered without a valid `jwt` cookie - the tab was left open past the token's
|
|
51
|
+
* lifetime, or reopened later): attempts one silent refresh and reloads so the server renders the page with the new
|
|
52
|
+
* cookie. If the refresh is refused (the refresh token expired or was revoked, or there was none), or a reload just
|
|
53
|
+
* made still found no session, redirects to sign-in as `useRedirectIfUnauthenticated()` does.
|
|
54
|
+
* - `userUid` set: refreshes once the token is `SESSION_REFRESH_AFTER_MS` old (and right away when this browser has no
|
|
55
|
+
* record of a recent refresh, since the page's token age is unknown), checked every `SESSION_REFRESH_CHECK_MS` and
|
|
56
|
+
* whenever the tab becomes visible or the network returns, because a sleeping laptop stops timers. A failure that is
|
|
57
|
+
* not a rejection is simply retried at the next check. A rejection (`401`/`403`: the refresh token expired or was
|
|
58
|
+
* revoked, so the session cannot be kept) redirects to sign-in with `return_to` after `options.beforeRedirect` has run.
|
|
59
|
+
*
|
|
60
|
+
* **A no-op under an `ApiClientContext.Provider`** (see `util/apiClientContext.ts`): everything above assumes a
|
|
61
|
+
* `jwt`/`refresh` cookie pair this app can renew through auth-server's own `/auth/refresh` - meaningless for a
|
|
62
|
+
* component whose network calls actually go through an explicit `ApiClient` from `createApiClient()` instead
|
|
63
|
+
* (e.g. one account of the native, multi-account `tauri-client`), which has no cookie jar for that origin at all
|
|
64
|
+
* and whose token lifecycle is the host app's own job via a completely different mechanism (its own refresh
|
|
65
|
+
* flow, keyed to `ApiClient.getAccessToken()`). Detected via `useApiClient()`; when it returns anything other
|
|
66
|
+
* than `undefined`, this hook does nothing at all - no timer, no listener, no redirect, regardless of `userUid`/
|
|
67
|
+
* `authServerUrl`/`options`. The default (no `ApiClientContext.Provider` anywhere - every existing browser/SSR/
|
|
68
|
+
* Electron consumer) is completely unchanged: `useApiClient()` there always returns `undefined`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function useSessionRefresh(userUid: string | undefined, authServerUrl: string | undefined, options?: SessionRefreshOptions): void;
|