@rapidmx/web-client 0.4.0 → 0.6.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 +88 -0
- package/apps/admin/audit-log/index.tsx +35 -8
- package/apps/admin/data-requests/index.tsx +480 -485
- package/apps/admin/distribution-lists/[uid].tsx +19 -1
- package/apps/admin/escrow-scopes/[uid].tsx +348 -237
- package/apps/admin/escrow-scopes/new/index.tsx +8 -2
- package/apps/admin/index.tsx +19 -1
- package/apps/admin/ingest-queue/index.tsx +44 -5
- package/apps/admin/mailboxes/[uid].tsx +211 -184
- package/apps/admin/quarantine/index.tsx +46 -14
- package/apps/admin/transport-rules/[uid].tsx +30 -1
- package/apps/admin/transport-rules/_transportRuleConfig.tsx +38 -2
- package/apps/admin/transport-rules/index.tsx +24 -6
- package/apps/admin/transport-rules/new/index.tsx +30 -1
- package/apps/escrow/_layout.tsx +2 -3
- package/apps/escrow/audit-log/index.tsx +196 -168
- package/apps/escrow/matters/[uid].tsx +621 -521
- package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +22 -1
- package/apps/shared/components/admin/layout/AdminShell.tsx +28 -9
- package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +152 -0
- package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +3 -3
- package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +55 -11
- package/apps/shared/components/admin/settings/BrandingForm.tsx +15 -4
- package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +18 -7
- package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +10 -2
- package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +6 -0
- package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +45 -12
- package/apps/shared/components/admin/settings/PluginsManager.tsx +1235 -595
- package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +174 -98
- package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +49 -13
- package/apps/shared/components/admin/setup/SetupWizard.tsx +150 -34
- package/apps/shared/components/admin/signOut.ts +79 -0
- package/apps/shared/components/admin/usePagedList.tsx +129 -0
- package/apps/shared/components/calendar/EventModal.tsx +717 -549
- package/apps/shared/components/calendar/MonthView.tsx +173 -139
- package/apps/shared/components/calendar/RecurrenceEditor.tsx +222 -180
- package/apps/shared/components/calendar/SplitDayView.tsx +143 -137
- package/apps/shared/components/calendar/TimeGridView.tsx +244 -198
- package/apps/shared/components/calendar/allDay.ts +124 -0
- package/apps/shared/components/calendar/layout/CalendarShell.tsx +194 -192
- package/apps/shared/components/contacts/ContactDetailPane.tsx +100 -21
- package/apps/shared/components/contacts/ContactForm.tsx +377 -348
- package/apps/shared/components/contacts/ContactsSidebar.tsx +6 -2
- package/apps/shared/components/contacts/KeyChangeReview.tsx +192 -0
- package/apps/shared/components/contacts/contactKeys.ts +78 -0
- package/apps/shared/components/contacts/layout/ContactsShell.tsx +199 -197
- package/apps/shared/components/escrow/layout/EscrowShell.tsx +148 -134
- package/apps/shared/components/layout/AppShell.tsx +123 -33
- package/apps/shared/components/layout/BrandingChrome.tsx +48 -10
- package/apps/shared/components/layout/KeyEnrollmentGate.tsx +389 -298
- package/apps/shared/components/layout/MailboxProvisioning.tsx +19 -3
- package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +350 -0
- package/apps/shared/components/layout/UnlockPromptProvider.tsx +257 -128
- package/apps/shared/components/mail/ConversationThreadPane.tsx +216 -181
- package/apps/shared/components/mail/MessageDetailPane.tsx +1318 -630
- package/apps/shared/components/mail/compose/ComposeContext.tsx +20 -15
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +854 -132
- package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -0
- package/apps/shared/components/mail/layout/MailShell.tsx +420 -408
- package/apps/shared/components/mail/pinnedSigners.ts +124 -0
- package/apps/shared/components/mail/verificationSeals.ts +125 -0
- package/apps/shared/components/mail/writableMailboxes.ts +101 -0
- package/apps/shared/components/rules/RuleBuilder.tsx +311 -276
- package/apps/shared/components/settings/layout/SettingsShell.tsx +23 -9
- package/apps/shared/components/tasks/layout/TasksShell.tsx +201 -199
- package/apps/shared/mail/listAllPages.ts +39 -0
- package/apps/shared/plugins/pluginNav.ts +73 -0
- package/apps/shared/search/LocalIndexLifecycle.tsx +64 -55
- package/apps/shared/search/localIndexBuilder.ts +481 -179
- package/apps/shared/search/localIndexRpcClient.ts +231 -29
- package/apps/shared/search/localIndexSchema.ts +15 -6
- package/apps/shared/search/localIndexStorage.ts +98 -0
- package/apps/shared/search/localIndexVFS.ts +32 -1
- package/apps/shared/search/localIndexWorker.ts +648 -186
- package/apps/www/calendar/index.tsx +438 -417
- package/apps/www/contacts/[uid].tsx +21 -2
- package/apps/www/contacts/index.tsx +116 -12
- package/apps/www/index.tsx +1314 -1041
- package/apps/www/messages/[uid].tsx +18 -6
- package/apps/www/settings/auto-reply/index.tsx +134 -129
- package/apps/www/settings/encryption/index.tsx +739 -216
- package/apps/www/settings/filters/[uid].tsx +171 -155
- package/apps/www/settings/filters/new/index.tsx +8 -1
- package/apps/www/settings/focused-inbox/index.tsx +150 -148
- package/apps/www/settings/privacy/index.tsx +494 -436
- package/apps/www/settings/read-receipts/index.tsx +148 -125
- package/apps/www/settings/sharing/index.tsx +17 -14
- package/apps/www/tasks/index.tsx +638 -579
- package/dist/apps/admin/_404.d.ts +2 -0
- package/dist/apps/admin/_500.d.ts +2 -0
- package/dist/apps/admin/_layout.d.ts +8 -0
- package/dist/apps/admin/audit-log/index.d.ts +11 -0
- package/dist/apps/admin/audit-log/index.js +38 -8
- package/dist/apps/admin/branding/index.d.ts +3 -0
- package/dist/apps/admin/data-requests/index.d.ts +3 -0
- package/dist/apps/admin/data-requests/index.js +52 -72
- package/dist/apps/admin/distribution-lists/[uid].d.ts +7 -0
- package/dist/apps/admin/distribution-lists/[uid].js +1 -1
- package/dist/apps/admin/distribution-lists/index.d.ts +3 -0
- package/dist/apps/admin/distribution-lists/new/index.d.ts +3 -0
- package/dist/apps/admin/domains/[uid].d.ts +7 -0
- package/dist/apps/admin/domains/index.d.ts +3 -0
- package/dist/apps/admin/domains/new/index.d.ts +3 -0
- package/dist/apps/admin/encryption-policy/index.d.ts +3 -0
- package/dist/apps/admin/escrow-scopes/[uid].d.ts +21 -0
- package/dist/apps/admin/escrow-scopes/[uid].js +91 -12
- package/dist/apps/admin/escrow-scopes/index.d.ts +3 -0
- package/dist/apps/admin/escrow-scopes/new/index.d.ts +3 -0
- package/dist/apps/admin/escrow-scopes/new/index.js +8 -3
- package/dist/apps/admin/index.d.ts +3 -0
- package/dist/apps/admin/index.js +4 -1
- package/dist/apps/admin/ingest-queue/index.d.ts +4 -0
- package/dist/apps/admin/ingest-queue/index.js +24 -6
- package/dist/apps/admin/mailbox-policy/index.d.ts +3 -0
- package/dist/apps/admin/mailboxes/[uid].d.ts +7 -0
- package/dist/apps/admin/mailboxes/[uid].js +20 -4
- package/dist/apps/admin/mailboxes/new/index.d.ts +3 -0
- package/dist/apps/admin/plugins/index.d.ts +3 -0
- package/dist/apps/admin/quarantine/index.d.ts +6 -0
- package/dist/apps/admin/quarantine/index.js +20 -11
- package/dist/apps/admin/retention-policy/index.d.ts +3 -0
- package/dist/apps/admin/setup/index.d.ts +3 -0
- package/dist/apps/admin/transport-rules/[uid].d.ts +7 -0
- package/dist/apps/admin/transport-rules/[uid].js +18 -2
- package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +21 -0
- package/dist/apps/admin/transport-rules/_transportRuleConfig.js +19 -0
- package/dist/apps/admin/transport-rules/index.d.ts +3 -0
- package/dist/apps/admin/transport-rules/index.js +22 -6
- package/dist/apps/admin/transport-rules/new/index.d.ts +3 -0
- package/dist/apps/admin/transport-rules/new/index.js +18 -2
- package/dist/apps/escrow/_layout.d.ts +10 -0
- package/dist/apps/escrow/_layout.js +3 -3
- package/dist/apps/escrow/audit-log/index.d.ts +9 -0
- package/dist/apps/escrow/audit-log/index.js +26 -1
- package/dist/apps/escrow/index.d.ts +3 -0
- package/dist/apps/escrow/matters/[uid].d.ts +7 -0
- package/dist/apps/escrow/matters/[uid].js +77 -42
- package/dist/apps/escrow/matters/new/index.d.ts +3 -0
- package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +17 -0
- package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.d.ts +32 -0
- package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +11 -2
- package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +32 -0
- package/dist/apps/shared/components/admin/layout/AdminShell.js +15 -6
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +12 -0
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +72 -0
- package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +6 -0
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +19 -0
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +3 -3
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.d.ts +12 -0
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +22 -4
- package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +9 -0
- package/dist/apps/shared/components/admin/settings/BrandingForm.js +15 -4
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +12 -0
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +13 -7
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +12 -0
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +7 -2
- package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.d.ts +9 -0
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +19 -0
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +6 -0
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +10 -0
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +34 -12
- package/dist/apps/shared/components/admin/settings/PluginsManager.d.ts +4 -0
- package/dist/apps/shared/components/admin/settings/PluginsManager.js +390 -78
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +9 -0
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +40 -11
- package/dist/apps/shared/components/admin/setup/EscrowSetupStep.d.ts +14 -0
- package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +29 -13
- package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +36 -0
- package/dist/apps/shared/components/admin/setup/SetupWizard.js +87 -21
- package/dist/apps/shared/components/admin/signOut.d.ts +23 -0
- package/dist/apps/shared/components/admin/signOut.js +75 -0
- package/dist/apps/shared/components/admin/usePagedList.d.ts +39 -0
- package/dist/apps/shared/components/admin/usePagedList.js +99 -0
- package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +26 -0
- package/dist/apps/shared/components/calendar/EventModal.d.ts +46 -0
- package/dist/apps/shared/components/calendar/EventModal.js +142 -21
- package/dist/apps/shared/components/calendar/MonthView.d.ts +15 -0
- package/dist/apps/shared/components/calendar/MonthView.js +12 -5
- package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +20 -0
- package/dist/apps/shared/components/calendar/RecurrenceEditor.js +40 -5
- package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +19 -0
- package/dist/apps/shared/components/calendar/SplitDayView.d.ts +28 -0
- package/dist/apps/shared/components/calendar/SplitDayView.js +10 -4
- package/dist/apps/shared/components/calendar/TimeGridView.d.ts +17 -0
- package/dist/apps/shared/components/calendar/TimeGridView.js +23 -7
- package/dist/apps/shared/components/calendar/allDay.d.ts +51 -0
- package/dist/apps/shared/components/calendar/allDay.js +111 -0
- package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +40 -0
- package/dist/apps/shared/components/calendar/layout/CalendarShell.js +3 -3
- package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +23 -0
- package/dist/apps/shared/components/contacts/ContactDetailPane.js +43 -5
- package/dist/apps/shared/components/contacts/ContactForm.d.ts +20 -0
- package/dist/apps/shared/components/contacts/ContactForm.js +32 -10
- package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +40 -0
- package/dist/apps/shared/components/contacts/ContactsSidebar.js +2 -2
- package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +25 -0
- package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +40 -0
- package/dist/apps/shared/components/contacts/KeyChangeReview.js +63 -0
- package/dist/apps/shared/components/contacts/contactKeys.d.ts +29 -0
- package/dist/apps/shared/components/contacts/contactKeys.js +64 -0
- package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +21 -0
- package/dist/apps/shared/components/contacts/layout/ContactsShell.js +2 -2
- package/dist/apps/shared/components/escrow/layout/EscrowShell.d.ts +25 -0
- package/dist/apps/shared/components/escrow/layout/EscrowShell.js +24 -5
- package/dist/apps/shared/components/forms/StringListField.d.ts +22 -0
- package/dist/apps/shared/components/layout/AppShell.d.ts +49 -0
- package/dist/apps/shared/components/layout/AppShell.js +97 -26
- package/dist/apps/shared/components/layout/BrandingChrome.d.ts +18 -0
- package/dist/apps/shared/components/layout/BrandingChrome.js +45 -10
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +51 -0
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +49 -12
- package/dist/apps/shared/components/layout/MailboxProvisioning.d.ts +13 -0
- package/dist/apps/shared/components/layout/MailboxProvisioning.js +10 -2
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +66 -0
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +174 -0
- package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +45 -0
- package/dist/apps/shared/components/layout/UnlockPromptProvider.js +73 -14
- package/dist/apps/shared/components/layout/UserMenu.d.ts +23 -0
- package/dist/apps/shared/components/mail/ConversationList.d.ts +11 -0
- package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +23 -0
- package/dist/apps/shared/components/mail/ConversationThreadPane.js +50 -12
- package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +93 -0
- package/dist/apps/shared/components/mail/MessageDetailPane.js +441 -36
- package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +58 -0
- package/dist/apps/shared/components/mail/compose/ComposeContext.js +9 -6
- package/dist/apps/shared/components/mail/compose/ComposeToolbar.d.ts +15 -0
- package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +37 -0
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +699 -128
- package/dist/apps/shared/components/mail/compose/EmojiPicker.d.ts +14 -0
- package/dist/apps/shared/components/mail/compose/GifPicker.d.ts +13 -0
- package/dist/apps/shared/components/mail/compose/RichTextEditor.d.ts +34 -0
- package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.d.ts +16 -0
- package/dist/apps/shared/components/mail/compose/composeFlushRegistry.d.ts +27 -0
- package/dist/apps/shared/components/mail/compose/composeFlushRegistry.js +50 -0
- package/dist/apps/shared/components/mail/layout/MailShell.d.ts +57 -0
- package/dist/apps/shared/components/mail/layout/MailShell.js +13 -4
- package/dist/apps/shared/components/mail/pinnedSigners.d.ts +33 -0
- package/dist/apps/shared/components/mail/pinnedSigners.js +98 -0
- package/dist/apps/shared/components/mail/verificationSeals.d.ts +22 -0
- package/dist/apps/shared/components/mail/verificationSeals.js +112 -0
- package/dist/apps/shared/components/mail/writableMailboxes.d.ts +15 -0
- package/dist/apps/shared/components/mail/writableMailboxes.js +87 -0
- package/dist/apps/shared/components/rules/RuleBuilder.d.ts +70 -0
- package/dist/apps/shared/components/rules/RuleBuilder.js +34 -6
- package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +41 -0
- package/dist/apps/shared/components/settings/layout/SettingsShell.js +19 -9
- package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +41 -0
- package/dist/apps/shared/components/tasks/TasksToolbar.d.ts +14 -0
- package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +24 -0
- package/dist/apps/shared/components/tasks/layout/TasksShell.js +2 -2
- package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -0
- package/dist/apps/shared/mail/listAllPages.d.ts +17 -0
- package/dist/apps/shared/mail/listAllPages.js +25 -0
- package/dist/apps/shared/plugins/pluginNav.d.ts +39 -0
- package/dist/apps/shared/plugins/pluginNav.js +33 -0
- package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +13 -0
- package/dist/apps/shared/search/LocalIndexLifecycle.js +58 -54
- package/dist/apps/shared/search/localIndexBlockCipher.d.ts +36 -0
- package/dist/apps/shared/search/localIndexBuilder.d.ts +85 -0
- package/dist/apps/shared/search/localIndexBuilder.js +292 -37
- package/dist/apps/shared/search/localIndexKey.d.ts +4 -0
- package/dist/apps/shared/search/localIndexRpcClient.d.ts +71 -0
- package/dist/apps/shared/search/localIndexRpcClient.js +191 -26
- package/dist/apps/shared/search/localIndexSchema.d.ts +111 -0
- package/dist/apps/shared/search/localIndexSchema.js +12 -6
- package/dist/apps/shared/search/localIndexSizePreference.d.ts +27 -0
- package/dist/apps/shared/search/localIndexStorage.d.ts +28 -0
- package/dist/apps/shared/search/localIndexStorage.js +86 -0
- package/dist/apps/shared/search/localIndexVFS.d.ts +101 -0
- package/dist/apps/shared/search/localIndexVFS.js +68 -40
- package/dist/apps/shared/search/localIndexWorker.d.ts +145 -0
- package/dist/apps/shared/search/localIndexWorker.js +519 -173
- package/dist/apps/shared/search/searchTier2.d.ts +30 -0
- package/dist/apps/www/_404.d.ts +2 -0
- package/dist/apps/www/_500.d.ts +2 -0
- package/dist/apps/www/_layout.d.ts +14 -0
- package/dist/apps/www/calendar/index.d.ts +3 -0
- package/dist/apps/www/calendar/index.js +28 -10
- package/dist/apps/www/contacts/[uid].d.ts +13 -0
- package/dist/apps/www/contacts/[uid].js +13 -2
- package/dist/apps/www/contacts/index.d.ts +3 -0
- package/dist/apps/www/contacts/index.js +80 -10
- package/dist/apps/www/index.d.ts +3 -0
- package/dist/apps/www/index.js +339 -108
- package/dist/apps/www/messages/[uid].d.ts +11 -0
- package/dist/apps/www/messages/[uid].js +18 -6
- package/dist/apps/www/settings/auto-reply/index.d.ts +4 -0
- package/dist/apps/www/settings/auto-reply/index.js +9 -4
- package/dist/apps/www/settings/encryption/index.d.ts +7 -0
- package/dist/apps/www/settings/encryption/index.js +514 -97
- package/dist/apps/www/settings/filters/[uid].d.ts +8 -0
- package/dist/apps/www/settings/filters/[uid].js +22 -7
- package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +11 -0
- package/dist/apps/www/settings/filters/index.d.ts +4 -0
- package/dist/apps/www/settings/filters/new/index.d.ts +4 -0
- package/dist/apps/www/settings/filters/new/index.js +8 -2
- package/dist/apps/www/settings/focused-inbox/index.d.ts +4 -0
- package/dist/apps/www/settings/focused-inbox/index.js +3 -1
- package/dist/apps/www/settings/labels/index.d.ts +4 -0
- package/dist/apps/www/settings/privacy/index.d.ts +4 -0
- package/dist/apps/www/settings/privacy/index.js +57 -22
- package/dist/apps/www/settings/read-receipts/index.d.ts +4 -0
- package/dist/apps/www/settings/read-receipts/index.js +10 -3
- package/dist/apps/www/settings/sharing/index.d.ts +4 -0
- package/dist/apps/www/settings/sharing/index.js +7 -11
- package/dist/apps/www/settings/signatures/[uid].d.ts +8 -0
- package/dist/apps/www/settings/signatures/index.d.ts +4 -0
- package/dist/apps/www/settings/signatures/new/index.d.ts +4 -0
- package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +10 -0
- package/dist/apps/www/tasks/index.d.ts +3 -0
- package/dist/apps/www/tasks/index.js +50 -10
- package/package.json +3 -3
- package/apps/shared/components/booking/AvailabilityEditor.tsx +0 -118
- package/apps/www/settings/booking-types/[uid].tsx +0 -300
- package/apps/www/settings/booking-types/index.tsx +0 -98
- package/apps/www/settings/booking-types/new/index.tsx +0 -212
- package/dist/apps/shared/components/booking/AvailabilityEditor.js +0 -45
- package/dist/apps/www/settings/booking-types/[uid].js +0 -129
- package/dist/apps/www/settings/booking-types/index.js +0 -29
- package/dist/apps/www/settings/booking-types/new/index.js +0 -86
|
@@ -47,6 +47,10 @@ export interface ContactsSidebarProps {
|
|
|
47
47
|
contacts: Contact[];
|
|
48
48
|
active: ContactsView;
|
|
49
49
|
onSelect: (view: ContactsView) => void;
|
|
50
|
+
/** Whether to offer the "Deleted" view - restapi only honors `deleted=true` for a caller with delete and
|
|
51
|
+
* update rights on the mailbox (anyone else silently gets the live contacts), so the parent hides it
|
|
52
|
+
* otherwise. Defaults to `true`. */
|
|
53
|
+
showDeleted?: boolean;
|
|
50
54
|
/** Bumped by the parent whenever a contact-list membership changes, so a newly-created/renamed list
|
|
51
55
|
* shows up without a full page reload. */
|
|
52
56
|
refreshToken?: number;
|
|
@@ -91,7 +95,7 @@ function NavItem({
|
|
|
91
95
|
* server-side). Owns its own contact-list data-fetching, per this app's convention of keeping
|
|
92
96
|
* `ContactsShellContext` itself minimal (mailbox/folder resolution only).
|
|
93
97
|
*/
|
|
94
|
-
export default function ContactsSidebar({ mailboxUid, contacts, active, onSelect, refreshToken }: ContactsSidebarProps) {
|
|
98
|
+
export default function ContactsSidebar({ mailboxUid, contacts, active, onSelect, refreshToken, showDeleted = true }: ContactsSidebarProps) {
|
|
95
99
|
const [lists, setLists] = useState<ContactList[]>([]);
|
|
96
100
|
const [listsError, setListsError] = useState<string | null>(null);
|
|
97
101
|
const [addingList, setAddingList] = useState(false);
|
|
@@ -157,7 +161,7 @@ export default function ContactsSidebar({ mailboxUid, contacts, active, onSelect
|
|
|
157
161
|
<div className="flex flex-col gap-0.5">
|
|
158
162
|
<NavItem label="Your contacts" count={contacts.length} active={active.type === "all"} onClick={() => handleSelect({ type: "all" })} />
|
|
159
163
|
<NavItem label="Favorites" count={favoriteCount} active={active.type === "favorites"} onClick={() => handleSelect({ type: "favorites" })} />
|
|
160
|
-
<NavItem label="Deleted" active={active.type === "deleted"} onClick={() => handleSelect({ type: "deleted" })} />
|
|
164
|
+
{showDeleted && <NavItem label="Deleted" active={active.type === "deleted"} onClick={() => handleSelect({ type: "deleted" })} />}
|
|
161
165
|
</div>
|
|
162
166
|
|
|
163
167
|
<div>
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
import React, { useState } from "react";
|
|
6
|
+
import { PinnedKeyChangedError, resolveKeyConflict, type KeyConflict } from "@rapidmx/react-shared/crypto/keyvaultApi.js";
|
|
7
|
+
import Modal from "@rapidmx/react-shared/components/overlays/Modal.js";
|
|
8
|
+
import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
|
|
9
|
+
import Button from "@rapidmx/react-shared/components/buttons/Button.js";
|
|
10
|
+
import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
|
|
11
|
+
import { conflictSourceLabel, formatDate, groupFingerprint, keyChangeErrorMessage } from "./contactKeys.js";
|
|
12
|
+
|
|
13
|
+
export interface KeyChangeReviewProps {
|
|
14
|
+
/** The mailbox whose contact holds the pinned key. */
|
|
15
|
+
mailboxUid: string;
|
|
16
|
+
/** The contact's address `resolveKeyConflict()` looks the contact up by; absent hides the actions. */
|
|
17
|
+
address?: string;
|
|
18
|
+
useType: "sign" | "encrypt";
|
|
19
|
+
/** Who the key belongs to, for the advice ("confirm with <name>"). */
|
|
20
|
+
ownerName: string;
|
|
21
|
+
/** The currently pinned key and when it was first trusted; absent (couldn't be loaded) hides the actions. */
|
|
22
|
+
current?: { fingerprint: string; since: number };
|
|
23
|
+
/** The new key: its fingerprint, the addresses its certificate names, and when and how it was recorded (absent when
|
|
24
|
+
* it's only known from the message being read). */
|
|
25
|
+
proposed: { fingerprint: string; emails?: string[]; observedAt?: number; source?: KeyConflict["source"] };
|
|
26
|
+
/** For accepting a key seen in a message: its certificate. Omitted, accepting pins the recorded conflict's key. */
|
|
27
|
+
certificate?: string;
|
|
28
|
+
/** Whether "Keep current key" applies - only when a conflict for this exact key is recorded. */
|
|
29
|
+
canReject: boolean;
|
|
30
|
+
/** `false` when the reader is known to lack the rights to change the contact's keys. */
|
|
31
|
+
canResolve?: boolean;
|
|
32
|
+
/** After a successful accept or reject - the caller refreshes what it shows. */
|
|
33
|
+
onResolved: (action: "accept" | "reject") => void;
|
|
34
|
+
/** After a 409: the pinned key changed meanwhile. The caller reloads and says so (`KEY_CHANGE_STALE_MESSAGE`). */
|
|
35
|
+
onPinnedKeyChanged: () => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The old-versus-new comparison for a changed contact key, with Accept new key (confirmed in a dialog) and Keep current
|
|
40
|
+
* key, calling `resolveKeyConflict()` against the pinned fingerprint shown. Shared by a message's "signing key changed"
|
|
41
|
+
* notice and a contact's recorded key conflicts.
|
|
42
|
+
*/
|
|
43
|
+
export default function KeyChangeReview({
|
|
44
|
+
mailboxUid,
|
|
45
|
+
address,
|
|
46
|
+
useType,
|
|
47
|
+
ownerName,
|
|
48
|
+
current,
|
|
49
|
+
proposed,
|
|
50
|
+
certificate,
|
|
51
|
+
canReject,
|
|
52
|
+
canResolve,
|
|
53
|
+
onResolved,
|
|
54
|
+
onPinnedKeyChanged,
|
|
55
|
+
}: KeyChangeReviewProps) {
|
|
56
|
+
const [confirmOpen, setConfirmOpen] = useState(false);
|
|
57
|
+
const [busy, setBusy] = useState<"accept" | "reject" | null>(null);
|
|
58
|
+
const [error, setError] = useState<string | null>(null);
|
|
59
|
+
const [forbidden, setForbidden] = useState(false);
|
|
60
|
+
const kind = useType === "sign" ? "signing" : "encryption";
|
|
61
|
+
const actionable = !!address && !!current && canResolve !== false && !forbidden;
|
|
62
|
+
|
|
63
|
+
async function resolve(action: "accept" | "reject") {
|
|
64
|
+
setBusy(action);
|
|
65
|
+
setError(null);
|
|
66
|
+
try {
|
|
67
|
+
await resolveKeyConflict(mailboxUid, {
|
|
68
|
+
address: address!,
|
|
69
|
+
useType,
|
|
70
|
+
action,
|
|
71
|
+
expectedPinnedFingerprint: current!.fingerprint,
|
|
72
|
+
...(action === "accept" && certificate !== undefined ? { certificate } : {}),
|
|
73
|
+
});
|
|
74
|
+
setConfirmOpen(false);
|
|
75
|
+
onResolved(action);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
setConfirmOpen(false);
|
|
78
|
+
if (err instanceof PinnedKeyChangedError) {
|
|
79
|
+
onPinnedKeyChanged();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (err instanceof ApiRequestError && err.status === 403) {
|
|
83
|
+
setForbidden(true);
|
|
84
|
+
}
|
|
85
|
+
setError(keyChangeErrorMessage(err));
|
|
86
|
+
} finally {
|
|
87
|
+
setBusy(null);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const proposedSeen =
|
|
92
|
+
proposed.observedAt !== undefined
|
|
93
|
+
? `First seen ${formatDate(proposed.observedAt)}${proposed.source ? `, ${conflictSourceLabel(proposed.source)}` : ""}`
|
|
94
|
+
: "Only seen in this message";
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<div className="flex flex-col gap-2">
|
|
98
|
+
<dl className="grid grid-cols-1 sm:grid-cols-2 gap-2">
|
|
99
|
+
<div className="rounded-sm bg-surface p-2">
|
|
100
|
+
<dt className="text-xs text-text-muted">Current key</dt>
|
|
101
|
+
{current ? (
|
|
102
|
+
<dd>
|
|
103
|
+
<span className="font-mono text-xs break-all">{groupFingerprint(current.fingerprint)}</span>
|
|
104
|
+
<span className="block text-xs text-text-muted">First seen {formatDate(current.since)}</span>
|
|
105
|
+
</dd>
|
|
106
|
+
) : (
|
|
107
|
+
<dd className="text-xs text-text-muted">The key you trust couldn’t be loaded.</dd>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
<div className="rounded-sm bg-surface p-2">
|
|
111
|
+
<dt className="text-xs text-text-muted">New key</dt>
|
|
112
|
+
<dd>
|
|
113
|
+
<span className="font-mono text-xs break-all">{groupFingerprint(proposed.fingerprint)}</span>
|
|
114
|
+
{proposed.emails && (
|
|
115
|
+
<span className="block text-xs text-text-muted">
|
|
116
|
+
Certificate for {proposed.emails.length > 0 ? proposed.emails.join(", ") : "no email address"}
|
|
117
|
+
</span>
|
|
118
|
+
)}
|
|
119
|
+
<span className="block text-xs text-text-muted">{proposedSeen}</span>
|
|
120
|
+
</dd>
|
|
121
|
+
</div>
|
|
122
|
+
</dl>
|
|
123
|
+
<p>
|
|
124
|
+
This is routine when {ownerName} renews a certificate, but it can also mean someone is impersonating them.
|
|
125
|
+
Confirm the new fingerprint with {ownerName} another way, such as a phone call, before accepting it.
|
|
126
|
+
</p>
|
|
127
|
+
{error && <Alert>{error}</Alert>}
|
|
128
|
+
{actionable && (
|
|
129
|
+
<div className="flex flex-wrap gap-2">
|
|
130
|
+
<Button
|
|
131
|
+
type="button"
|
|
132
|
+
className="!w-auto"
|
|
133
|
+
disabled={busy !== null}
|
|
134
|
+
onClick={() => {
|
|
135
|
+
setError(null);
|
|
136
|
+
setConfirmOpen(true);
|
|
137
|
+
}}
|
|
138
|
+
>
|
|
139
|
+
Accept new key
|
|
140
|
+
</Button>
|
|
141
|
+
{canReject && (
|
|
142
|
+
<Button
|
|
143
|
+
type="button"
|
|
144
|
+
variant="secondary"
|
|
145
|
+
className="!w-auto"
|
|
146
|
+
loading={busy === "reject"}
|
|
147
|
+
disabled={busy !== null}
|
|
148
|
+
onClick={() => resolve("reject")}
|
|
149
|
+
>
|
|
150
|
+
Keep current key
|
|
151
|
+
</Button>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
)}
|
|
155
|
+
<Modal open={confirmOpen} onClose={() => busy === null && setConfirmOpen(false)} title="Accept the new key?">
|
|
156
|
+
<div className="flex flex-col gap-3 text-sm">
|
|
157
|
+
<p>
|
|
158
|
+
{useType === "sign"
|
|
159
|
+
? `Mail from ${address} signed with this key will show as verified.`
|
|
160
|
+
: `Mail you send to ${address} will be encrypted to this key.`}{" "}
|
|
161
|
+
The current {kind} key moves to this contact’s key history.
|
|
162
|
+
</p>
|
|
163
|
+
<dl className="flex flex-col gap-1">
|
|
164
|
+
<dt className="text-xs text-text-muted">New key fingerprint</dt>
|
|
165
|
+
<dd className="font-mono text-xs break-all">{groupFingerprint(proposed.fingerprint)}</dd>
|
|
166
|
+
</dl>
|
|
167
|
+
<p className="text-text-muted">Only accept it once you’ve confirmed this fingerprint with {ownerName}.</p>
|
|
168
|
+
<div className="flex gap-3">
|
|
169
|
+
<Button
|
|
170
|
+
type="button"
|
|
171
|
+
className="!w-auto"
|
|
172
|
+
loading={busy === "accept"}
|
|
173
|
+
disabled={busy !== null}
|
|
174
|
+
onClick={() => resolve("accept")}
|
|
175
|
+
>
|
|
176
|
+
Accept new key
|
|
177
|
+
</Button>
|
|
178
|
+
<Button
|
|
179
|
+
type="button"
|
|
180
|
+
variant="secondary"
|
|
181
|
+
className="!w-auto"
|
|
182
|
+
disabled={busy !== null}
|
|
183
|
+
onClick={() => setConfirmOpen(false)}
|
|
184
|
+
>
|
|
185
|
+
Cancel
|
|
186
|
+
</Button>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
</Modal>
|
|
190
|
+
</div>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5
|
+
/** Display and error helpers for a contact's pinned keys and key changes (`KeyChangeReview`, `ContactDetailPane`,
|
|
6
|
+
* `MessageDetailPane`). */
|
|
7
|
+
import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
|
|
8
|
+
import type { Contact } from "@rapidmx/react-shared/contacts/contactsApi.js";
|
|
9
|
+
import { PinnedKeyChangedError, type KeyConflict, type PublicKey } from "@rapidmx/react-shared/crypto/keyvaultApi.js";
|
|
10
|
+
|
|
11
|
+
export const KEY_CHANGE_STALE_MESSAGE = "This contact's keys changed while you were looking; reload to see the latest.";
|
|
12
|
+
export const KEY_CHANGE_INVALID_MESSAGE =
|
|
13
|
+
"The new key isn't a valid, current certificate for this address, so it can't be accepted. Nothing was changed.";
|
|
14
|
+
export const KEY_CHANGE_FORBIDDEN_MESSAGE = "You don't have permission to change this contact's keys.";
|
|
15
|
+
export const KEY_CHANGE_NOT_FOUND_MESSAGE =
|
|
16
|
+
"There's no key change to resolve for this address any more. It may already have been resolved, or the contact was removed.";
|
|
17
|
+
export const KEY_CHANGE_GENERIC_MESSAGE = "Couldn't update this contact's keys. Try again.";
|
|
18
|
+
|
|
19
|
+
/** The error text for a failed `resolveKeyConflict()` other than `PinnedKeyChangedError` (which the caller reloads
|
|
20
|
+
* on and reports with `KEY_CHANGE_STALE_MESSAGE`). */
|
|
21
|
+
export function keyChangeErrorMessage(err: unknown): string {
|
|
22
|
+
if (err instanceof PinnedKeyChangedError) {
|
|
23
|
+
return KEY_CHANGE_STALE_MESSAGE;
|
|
24
|
+
}
|
|
25
|
+
if (err instanceof ApiRequestError && err.status === 400) {
|
|
26
|
+
return KEY_CHANGE_INVALID_MESSAGE;
|
|
27
|
+
}
|
|
28
|
+
if (err instanceof ApiRequestError && err.status === 403) {
|
|
29
|
+
return KEY_CHANGE_FORBIDDEN_MESSAGE;
|
|
30
|
+
}
|
|
31
|
+
if (err instanceof ApiRequestError && err.status === 404) {
|
|
32
|
+
return KEY_CHANGE_NOT_FOUND_MESSAGE;
|
|
33
|
+
}
|
|
34
|
+
return KEY_CHANGE_GENERIC_MESSAGE;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Groups a fingerprint into 4-character blocks (`ab12 cd34 ...`), ignoring any separators it came with, so it can be
|
|
38
|
+
* read out and compared over another channel. */
|
|
39
|
+
export function groupFingerprint(fingerprint: string): string {
|
|
40
|
+
const compact = fingerprint.replace(/[\s:]/g, "").toLowerCase();
|
|
41
|
+
return compact.match(/.{1,4}/g)?.join(" ") ?? compact;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Whether two fingerprints name the same key (case and separators ignored). */
|
|
45
|
+
export function sameFingerprint(a: string | undefined, b: string | undefined): boolean {
|
|
46
|
+
return a !== undefined && b !== undefined && a.replace(/[\s:]/g, "").toLowerCase() === b.replace(/[\s:]/g, "").toLowerCase();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** A revoked key's label: `"superseded"` for a routine replacement, `"revoked"` for a compromised key or one revoked
|
|
50
|
+
* with no reason; `undefined` when the key isn't revoked. */
|
|
51
|
+
export function revocationLabel(key: PublicKey): "superseded" | "revoked" | undefined {
|
|
52
|
+
if (!key.revokedAt) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
return key.revocationReason === "superseded" ? "superseded" : "revoked";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Where a key conflict was observed, for display. */
|
|
59
|
+
export function conflictSourceLabel(source: KeyConflict["source"]): string {
|
|
60
|
+
return source === "header" ? "from an incoming message" : "by key discovery";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** restapi records `keysFirstSeen` on a contact but react-shared's `Contact` type doesn't carry it. */
|
|
64
|
+
type ContactWithFirstSeen = Pick<Contact, "previousKeys"> & { keysFirstSeen?: number };
|
|
65
|
+
|
|
66
|
+
/** When `key` (one of `contact`'s pinned keys) started being trusted: when it replaced the newest previous key of its
|
|
67
|
+
* use, else the contact's `keysFirstSeen`, else the key's own `notBefore`. */
|
|
68
|
+
export function keyPinnedSince(contact: ContactWithFirstSeen, key: PublicKey): number {
|
|
69
|
+
const replaced = (contact.previousKeys ?? []).filter((previous) => previous.useType === key.useType).map((previous) => previous.replacedAt);
|
|
70
|
+
if (replaced.length > 0) {
|
|
71
|
+
return Math.max(...replaced);
|
|
72
|
+
}
|
|
73
|
+
return contact.keysFirstSeen ?? key.notBefore;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function formatDate(ms: number): string {
|
|
77
|
+
return new Date(ms).toLocaleDateString();
|
|
78
|
+
}
|