@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.
Files changed (320) hide show
  1. package/README.md +88 -0
  2. package/apps/admin/audit-log/index.tsx +35 -8
  3. package/apps/admin/data-requests/index.tsx +480 -485
  4. package/apps/admin/distribution-lists/[uid].tsx +19 -1
  5. package/apps/admin/escrow-scopes/[uid].tsx +348 -237
  6. package/apps/admin/escrow-scopes/new/index.tsx +8 -2
  7. package/apps/admin/index.tsx +19 -1
  8. package/apps/admin/ingest-queue/index.tsx +44 -5
  9. package/apps/admin/mailboxes/[uid].tsx +211 -184
  10. package/apps/admin/quarantine/index.tsx +46 -14
  11. package/apps/admin/transport-rules/[uid].tsx +30 -1
  12. package/apps/admin/transport-rules/_transportRuleConfig.tsx +38 -2
  13. package/apps/admin/transport-rules/index.tsx +24 -6
  14. package/apps/admin/transport-rules/new/index.tsx +30 -1
  15. package/apps/escrow/_layout.tsx +2 -3
  16. package/apps/escrow/audit-log/index.tsx +196 -168
  17. package/apps/escrow/matters/[uid].tsx +621 -521
  18. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +22 -1
  19. package/apps/shared/components/admin/layout/AdminShell.tsx +28 -9
  20. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +152 -0
  21. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +3 -3
  22. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +55 -11
  23. package/apps/shared/components/admin/settings/BrandingForm.tsx +15 -4
  24. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +18 -7
  25. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +10 -2
  26. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +6 -0
  27. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +45 -12
  28. package/apps/shared/components/admin/settings/PluginsManager.tsx +1235 -595
  29. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +174 -98
  30. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +49 -13
  31. package/apps/shared/components/admin/setup/SetupWizard.tsx +150 -34
  32. package/apps/shared/components/admin/signOut.ts +79 -0
  33. package/apps/shared/components/admin/usePagedList.tsx +129 -0
  34. package/apps/shared/components/calendar/EventModal.tsx +717 -549
  35. package/apps/shared/components/calendar/MonthView.tsx +173 -139
  36. package/apps/shared/components/calendar/RecurrenceEditor.tsx +222 -180
  37. package/apps/shared/components/calendar/SplitDayView.tsx +143 -137
  38. package/apps/shared/components/calendar/TimeGridView.tsx +244 -198
  39. package/apps/shared/components/calendar/allDay.ts +124 -0
  40. package/apps/shared/components/calendar/layout/CalendarShell.tsx +194 -192
  41. package/apps/shared/components/contacts/ContactDetailPane.tsx +100 -21
  42. package/apps/shared/components/contacts/ContactForm.tsx +377 -348
  43. package/apps/shared/components/contacts/ContactsSidebar.tsx +6 -2
  44. package/apps/shared/components/contacts/KeyChangeReview.tsx +192 -0
  45. package/apps/shared/components/contacts/contactKeys.ts +78 -0
  46. package/apps/shared/components/contacts/layout/ContactsShell.tsx +199 -197
  47. package/apps/shared/components/escrow/layout/EscrowShell.tsx +148 -134
  48. package/apps/shared/components/layout/AppShell.tsx +123 -33
  49. package/apps/shared/components/layout/BrandingChrome.tsx +48 -10
  50. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +389 -298
  51. package/apps/shared/components/layout/MailboxProvisioning.tsx +19 -3
  52. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +350 -0
  53. package/apps/shared/components/layout/UnlockPromptProvider.tsx +257 -128
  54. package/apps/shared/components/mail/ConversationThreadPane.tsx +216 -181
  55. package/apps/shared/components/mail/MessageDetailPane.tsx +1318 -630
  56. package/apps/shared/components/mail/compose/ComposeContext.tsx +20 -15
  57. package/apps/shared/components/mail/compose/ComposeWindow.tsx +854 -132
  58. package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -0
  59. package/apps/shared/components/mail/layout/MailShell.tsx +420 -408
  60. package/apps/shared/components/mail/pinnedSigners.ts +124 -0
  61. package/apps/shared/components/mail/verificationSeals.ts +125 -0
  62. package/apps/shared/components/mail/writableMailboxes.ts +101 -0
  63. package/apps/shared/components/rules/RuleBuilder.tsx +311 -276
  64. package/apps/shared/components/settings/layout/SettingsShell.tsx +23 -9
  65. package/apps/shared/components/tasks/layout/TasksShell.tsx +201 -199
  66. package/apps/shared/mail/listAllPages.ts +39 -0
  67. package/apps/shared/plugins/pluginNav.ts +73 -0
  68. package/apps/shared/search/LocalIndexLifecycle.tsx +64 -55
  69. package/apps/shared/search/localIndexBuilder.ts +481 -179
  70. package/apps/shared/search/localIndexRpcClient.ts +231 -29
  71. package/apps/shared/search/localIndexSchema.ts +15 -6
  72. package/apps/shared/search/localIndexStorage.ts +98 -0
  73. package/apps/shared/search/localIndexVFS.ts +32 -1
  74. package/apps/shared/search/localIndexWorker.ts +648 -186
  75. package/apps/www/calendar/index.tsx +438 -417
  76. package/apps/www/contacts/[uid].tsx +21 -2
  77. package/apps/www/contacts/index.tsx +116 -12
  78. package/apps/www/index.tsx +1314 -1041
  79. package/apps/www/messages/[uid].tsx +18 -6
  80. package/apps/www/settings/auto-reply/index.tsx +134 -129
  81. package/apps/www/settings/encryption/index.tsx +739 -216
  82. package/apps/www/settings/filters/[uid].tsx +171 -155
  83. package/apps/www/settings/filters/new/index.tsx +8 -1
  84. package/apps/www/settings/focused-inbox/index.tsx +150 -148
  85. package/apps/www/settings/privacy/index.tsx +494 -436
  86. package/apps/www/settings/read-receipts/index.tsx +148 -125
  87. package/apps/www/settings/sharing/index.tsx +17 -14
  88. package/apps/www/tasks/index.tsx +638 -579
  89. package/dist/apps/admin/_404.d.ts +2 -0
  90. package/dist/apps/admin/_500.d.ts +2 -0
  91. package/dist/apps/admin/_layout.d.ts +8 -0
  92. package/dist/apps/admin/audit-log/index.d.ts +11 -0
  93. package/dist/apps/admin/audit-log/index.js +38 -8
  94. package/dist/apps/admin/branding/index.d.ts +3 -0
  95. package/dist/apps/admin/data-requests/index.d.ts +3 -0
  96. package/dist/apps/admin/data-requests/index.js +52 -72
  97. package/dist/apps/admin/distribution-lists/[uid].d.ts +7 -0
  98. package/dist/apps/admin/distribution-lists/[uid].js +1 -1
  99. package/dist/apps/admin/distribution-lists/index.d.ts +3 -0
  100. package/dist/apps/admin/distribution-lists/new/index.d.ts +3 -0
  101. package/dist/apps/admin/domains/[uid].d.ts +7 -0
  102. package/dist/apps/admin/domains/index.d.ts +3 -0
  103. package/dist/apps/admin/domains/new/index.d.ts +3 -0
  104. package/dist/apps/admin/encryption-policy/index.d.ts +3 -0
  105. package/dist/apps/admin/escrow-scopes/[uid].d.ts +21 -0
  106. package/dist/apps/admin/escrow-scopes/[uid].js +91 -12
  107. package/dist/apps/admin/escrow-scopes/index.d.ts +3 -0
  108. package/dist/apps/admin/escrow-scopes/new/index.d.ts +3 -0
  109. package/dist/apps/admin/escrow-scopes/new/index.js +8 -3
  110. package/dist/apps/admin/index.d.ts +3 -0
  111. package/dist/apps/admin/index.js +4 -1
  112. package/dist/apps/admin/ingest-queue/index.d.ts +4 -0
  113. package/dist/apps/admin/ingest-queue/index.js +24 -6
  114. package/dist/apps/admin/mailbox-policy/index.d.ts +3 -0
  115. package/dist/apps/admin/mailboxes/[uid].d.ts +7 -0
  116. package/dist/apps/admin/mailboxes/[uid].js +20 -4
  117. package/dist/apps/admin/mailboxes/new/index.d.ts +3 -0
  118. package/dist/apps/admin/plugins/index.d.ts +3 -0
  119. package/dist/apps/admin/quarantine/index.d.ts +6 -0
  120. package/dist/apps/admin/quarantine/index.js +20 -11
  121. package/dist/apps/admin/retention-policy/index.d.ts +3 -0
  122. package/dist/apps/admin/setup/index.d.ts +3 -0
  123. package/dist/apps/admin/transport-rules/[uid].d.ts +7 -0
  124. package/dist/apps/admin/transport-rules/[uid].js +18 -2
  125. package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +21 -0
  126. package/dist/apps/admin/transport-rules/_transportRuleConfig.js +19 -0
  127. package/dist/apps/admin/transport-rules/index.d.ts +3 -0
  128. package/dist/apps/admin/transport-rules/index.js +22 -6
  129. package/dist/apps/admin/transport-rules/new/index.d.ts +3 -0
  130. package/dist/apps/admin/transport-rules/new/index.js +18 -2
  131. package/dist/apps/escrow/_layout.d.ts +10 -0
  132. package/dist/apps/escrow/_layout.js +3 -3
  133. package/dist/apps/escrow/audit-log/index.d.ts +9 -0
  134. package/dist/apps/escrow/audit-log/index.js +26 -1
  135. package/dist/apps/escrow/index.d.ts +3 -0
  136. package/dist/apps/escrow/matters/[uid].d.ts +7 -0
  137. package/dist/apps/escrow/matters/[uid].js +77 -42
  138. package/dist/apps/escrow/matters/new/index.d.ts +3 -0
  139. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +17 -0
  140. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.d.ts +32 -0
  141. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +11 -2
  142. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +32 -0
  143. package/dist/apps/shared/components/admin/layout/AdminShell.js +15 -6
  144. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +12 -0
  145. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +72 -0
  146. package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +6 -0
  147. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +19 -0
  148. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +3 -3
  149. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.d.ts +12 -0
  150. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +22 -4
  151. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +9 -0
  152. package/dist/apps/shared/components/admin/settings/BrandingForm.js +15 -4
  153. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +12 -0
  154. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +13 -7
  155. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +12 -0
  156. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +7 -2
  157. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.d.ts +9 -0
  158. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +19 -0
  159. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +6 -0
  160. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +10 -0
  161. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +34 -12
  162. package/dist/apps/shared/components/admin/settings/PluginsManager.d.ts +4 -0
  163. package/dist/apps/shared/components/admin/settings/PluginsManager.js +390 -78
  164. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +9 -0
  165. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +40 -11
  166. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.d.ts +14 -0
  167. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +29 -13
  168. package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +36 -0
  169. package/dist/apps/shared/components/admin/setup/SetupWizard.js +87 -21
  170. package/dist/apps/shared/components/admin/signOut.d.ts +23 -0
  171. package/dist/apps/shared/components/admin/signOut.js +75 -0
  172. package/dist/apps/shared/components/admin/usePagedList.d.ts +39 -0
  173. package/dist/apps/shared/components/admin/usePagedList.js +99 -0
  174. package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +26 -0
  175. package/dist/apps/shared/components/calendar/EventModal.d.ts +46 -0
  176. package/dist/apps/shared/components/calendar/EventModal.js +142 -21
  177. package/dist/apps/shared/components/calendar/MonthView.d.ts +15 -0
  178. package/dist/apps/shared/components/calendar/MonthView.js +12 -5
  179. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +20 -0
  180. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +40 -5
  181. package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +19 -0
  182. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +28 -0
  183. package/dist/apps/shared/components/calendar/SplitDayView.js +10 -4
  184. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +17 -0
  185. package/dist/apps/shared/components/calendar/TimeGridView.js +23 -7
  186. package/dist/apps/shared/components/calendar/allDay.d.ts +51 -0
  187. package/dist/apps/shared/components/calendar/allDay.js +111 -0
  188. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +40 -0
  189. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +3 -3
  190. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +23 -0
  191. package/dist/apps/shared/components/contacts/ContactDetailPane.js +43 -5
  192. package/dist/apps/shared/components/contacts/ContactForm.d.ts +20 -0
  193. package/dist/apps/shared/components/contacts/ContactForm.js +32 -10
  194. package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +40 -0
  195. package/dist/apps/shared/components/contacts/ContactsSidebar.js +2 -2
  196. package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +25 -0
  197. package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +40 -0
  198. package/dist/apps/shared/components/contacts/KeyChangeReview.js +63 -0
  199. package/dist/apps/shared/components/contacts/contactKeys.d.ts +29 -0
  200. package/dist/apps/shared/components/contacts/contactKeys.js +64 -0
  201. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +21 -0
  202. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +2 -2
  203. package/dist/apps/shared/components/escrow/layout/EscrowShell.d.ts +25 -0
  204. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +24 -5
  205. package/dist/apps/shared/components/forms/StringListField.d.ts +22 -0
  206. package/dist/apps/shared/components/layout/AppShell.d.ts +49 -0
  207. package/dist/apps/shared/components/layout/AppShell.js +97 -26
  208. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +18 -0
  209. package/dist/apps/shared/components/layout/BrandingChrome.js +45 -10
  210. package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +51 -0
  211. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +49 -12
  212. package/dist/apps/shared/components/layout/MailboxProvisioning.d.ts +13 -0
  213. package/dist/apps/shared/components/layout/MailboxProvisioning.js +10 -2
  214. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +66 -0
  215. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +174 -0
  216. package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +45 -0
  217. package/dist/apps/shared/components/layout/UnlockPromptProvider.js +73 -14
  218. package/dist/apps/shared/components/layout/UserMenu.d.ts +23 -0
  219. package/dist/apps/shared/components/mail/ConversationList.d.ts +11 -0
  220. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +23 -0
  221. package/dist/apps/shared/components/mail/ConversationThreadPane.js +50 -12
  222. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +93 -0
  223. package/dist/apps/shared/components/mail/MessageDetailPane.js +441 -36
  224. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +58 -0
  225. package/dist/apps/shared/components/mail/compose/ComposeContext.js +9 -6
  226. package/dist/apps/shared/components/mail/compose/ComposeToolbar.d.ts +15 -0
  227. package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +37 -0
  228. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +699 -128
  229. package/dist/apps/shared/components/mail/compose/EmojiPicker.d.ts +14 -0
  230. package/dist/apps/shared/components/mail/compose/GifPicker.d.ts +13 -0
  231. package/dist/apps/shared/components/mail/compose/RichTextEditor.d.ts +34 -0
  232. package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.d.ts +16 -0
  233. package/dist/apps/shared/components/mail/compose/composeFlushRegistry.d.ts +27 -0
  234. package/dist/apps/shared/components/mail/compose/composeFlushRegistry.js +50 -0
  235. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +57 -0
  236. package/dist/apps/shared/components/mail/layout/MailShell.js +13 -4
  237. package/dist/apps/shared/components/mail/pinnedSigners.d.ts +33 -0
  238. package/dist/apps/shared/components/mail/pinnedSigners.js +98 -0
  239. package/dist/apps/shared/components/mail/verificationSeals.d.ts +22 -0
  240. package/dist/apps/shared/components/mail/verificationSeals.js +112 -0
  241. package/dist/apps/shared/components/mail/writableMailboxes.d.ts +15 -0
  242. package/dist/apps/shared/components/mail/writableMailboxes.js +87 -0
  243. package/dist/apps/shared/components/rules/RuleBuilder.d.ts +70 -0
  244. package/dist/apps/shared/components/rules/RuleBuilder.js +34 -6
  245. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +41 -0
  246. package/dist/apps/shared/components/settings/layout/SettingsShell.js +19 -9
  247. package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +41 -0
  248. package/dist/apps/shared/components/tasks/TasksToolbar.d.ts +14 -0
  249. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +24 -0
  250. package/dist/apps/shared/components/tasks/layout/TasksShell.js +2 -2
  251. package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -0
  252. package/dist/apps/shared/mail/listAllPages.d.ts +17 -0
  253. package/dist/apps/shared/mail/listAllPages.js +25 -0
  254. package/dist/apps/shared/plugins/pluginNav.d.ts +39 -0
  255. package/dist/apps/shared/plugins/pluginNav.js +33 -0
  256. package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +13 -0
  257. package/dist/apps/shared/search/LocalIndexLifecycle.js +58 -54
  258. package/dist/apps/shared/search/localIndexBlockCipher.d.ts +36 -0
  259. package/dist/apps/shared/search/localIndexBuilder.d.ts +85 -0
  260. package/dist/apps/shared/search/localIndexBuilder.js +292 -37
  261. package/dist/apps/shared/search/localIndexKey.d.ts +4 -0
  262. package/dist/apps/shared/search/localIndexRpcClient.d.ts +71 -0
  263. package/dist/apps/shared/search/localIndexRpcClient.js +191 -26
  264. package/dist/apps/shared/search/localIndexSchema.d.ts +111 -0
  265. package/dist/apps/shared/search/localIndexSchema.js +12 -6
  266. package/dist/apps/shared/search/localIndexSizePreference.d.ts +27 -0
  267. package/dist/apps/shared/search/localIndexStorage.d.ts +28 -0
  268. package/dist/apps/shared/search/localIndexStorage.js +86 -0
  269. package/dist/apps/shared/search/localIndexVFS.d.ts +101 -0
  270. package/dist/apps/shared/search/localIndexVFS.js +68 -40
  271. package/dist/apps/shared/search/localIndexWorker.d.ts +145 -0
  272. package/dist/apps/shared/search/localIndexWorker.js +519 -173
  273. package/dist/apps/shared/search/searchTier2.d.ts +30 -0
  274. package/dist/apps/www/_404.d.ts +2 -0
  275. package/dist/apps/www/_500.d.ts +2 -0
  276. package/dist/apps/www/_layout.d.ts +14 -0
  277. package/dist/apps/www/calendar/index.d.ts +3 -0
  278. package/dist/apps/www/calendar/index.js +28 -10
  279. package/dist/apps/www/contacts/[uid].d.ts +13 -0
  280. package/dist/apps/www/contacts/[uid].js +13 -2
  281. package/dist/apps/www/contacts/index.d.ts +3 -0
  282. package/dist/apps/www/contacts/index.js +80 -10
  283. package/dist/apps/www/index.d.ts +3 -0
  284. package/dist/apps/www/index.js +339 -108
  285. package/dist/apps/www/messages/[uid].d.ts +11 -0
  286. package/dist/apps/www/messages/[uid].js +18 -6
  287. package/dist/apps/www/settings/auto-reply/index.d.ts +4 -0
  288. package/dist/apps/www/settings/auto-reply/index.js +9 -4
  289. package/dist/apps/www/settings/encryption/index.d.ts +7 -0
  290. package/dist/apps/www/settings/encryption/index.js +514 -97
  291. package/dist/apps/www/settings/filters/[uid].d.ts +8 -0
  292. package/dist/apps/www/settings/filters/[uid].js +22 -7
  293. package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +11 -0
  294. package/dist/apps/www/settings/filters/index.d.ts +4 -0
  295. package/dist/apps/www/settings/filters/new/index.d.ts +4 -0
  296. package/dist/apps/www/settings/filters/new/index.js +8 -2
  297. package/dist/apps/www/settings/focused-inbox/index.d.ts +4 -0
  298. package/dist/apps/www/settings/focused-inbox/index.js +3 -1
  299. package/dist/apps/www/settings/labels/index.d.ts +4 -0
  300. package/dist/apps/www/settings/privacy/index.d.ts +4 -0
  301. package/dist/apps/www/settings/privacy/index.js +57 -22
  302. package/dist/apps/www/settings/read-receipts/index.d.ts +4 -0
  303. package/dist/apps/www/settings/read-receipts/index.js +10 -3
  304. package/dist/apps/www/settings/sharing/index.d.ts +4 -0
  305. package/dist/apps/www/settings/sharing/index.js +7 -11
  306. package/dist/apps/www/settings/signatures/[uid].d.ts +8 -0
  307. package/dist/apps/www/settings/signatures/index.d.ts +4 -0
  308. package/dist/apps/www/settings/signatures/new/index.d.ts +4 -0
  309. package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +10 -0
  310. package/dist/apps/www/tasks/index.d.ts +3 -0
  311. package/dist/apps/www/tasks/index.js +50 -10
  312. package/package.json +3 -3
  313. package/apps/shared/components/booking/AvailabilityEditor.tsx +0 -118
  314. package/apps/www/settings/booking-types/[uid].tsx +0 -300
  315. package/apps/www/settings/booking-types/index.tsx +0 -98
  316. package/apps/www/settings/booking-types/new/index.tsx +0 -212
  317. package/dist/apps/shared/components/booking/AvailabilityEditor.js +0 -45
  318. package/dist/apps/www/settings/booking-types/[uid].js +0 -129
  319. package/dist/apps/www/settings/booking-types/index.js +0 -29
  320. package/dist/apps/www/settings/booking-types/new/index.js +0 -86
@@ -1,98 +1,174 @@
1
- ///////////////////////////////////////////////////////////////////////////////
2
- // Copyright (C) 2026 Jean-Philippe Steinmetz
3
- // SPDX-License-Identifier: MPL-2.0
4
- ///////////////////////////////////////////////////////////////////////////////
5
- import React, { FormEvent, useState } from "react";
6
- import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
7
- import { MIN_AUDIT_LOG_RETENTION_DAYS, RetentionPolicy, updateRetentionPolicy } from "@rapidmx/react-shared/admin/retentionPolicyApi.js";
8
- import Alert from "@rapidmx/react-shared/components/feedback/Alert.js";
9
- import Button from "@rapidmx/react-shared/components/buttons/Button.js";
10
-
11
- const INPUT_CLASS =
12
- "w-full text-sm py-2 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
13
-
14
- /** The retention policy editor, shared by the Retention Policy page and the setup wizard. */
15
- export default function RetentionPolicyForm({ policy, onChange }: { policy: RetentionPolicy; onChange: (p: RetentionPolicy) => void }) {
16
- const [messageRetentionDays, setMessageRetentionDays] = useState(policy.messageRetentionDays?.toString() ?? "");
17
- const [auditLogRetentionDays, setAuditLogRetentionDays] = useState(policy.auditLogRetentionDays?.toString() ?? "");
18
- const [error, setError] = useState<string | null>(null);
19
- const [saving, setSaving] = useState(false);
20
- const [saved, setSaved] = useState(false);
21
-
22
- async function handleSubmit(e: FormEvent) {
23
- e.preventDefault();
24
- setError(null);
25
- setSaved(false);
26
- setSaving(true);
27
- try {
28
- const patch: Partial<RetentionPolicy> = {};
29
- if (messageRetentionDays.trim() !== "") {
30
- patch.messageRetentionDays = Number(messageRetentionDays);
31
- }
32
- if (auditLogRetentionDays.trim() !== "") {
33
- patch.auditLogRetentionDays = Number(auditLogRetentionDays);
34
- }
35
- const updated = await updateRetentionPolicy(patch);
36
- onChange(updated);
37
- setSaved(true);
38
- } catch (err) {
39
- setError(err instanceof ApiRequestError ? err.message : "Could not save the retention policy.");
40
- } finally {
41
- setSaving(false);
42
- }
43
- }
44
-
45
- return (
46
- <div className="max-w-xl">
47
- <h1 className="text-xl font-bold uppercase tracking-wide mb-1">Retention Policy</h1>
48
- <p className="text-sm text-text-muted mb-5">
49
- Automatically and permanently deletes mail/audit-log entries older than the configured age.
50
- Leave a field blank for no automatic purge. This does not apply to a mailbox that is a
51
- custodian on an active legal hold — a held message is skipped and retried on a later run once
52
- the hold is lifted.
53
- </p>
54
-
55
- {error && <Alert>{error}</Alert>}
56
- {saved && !error && <div className="mb-4 text-sm text-success font-medium">Saved.</div>}
57
-
58
- <form onSubmit={handleSubmit} className="flex flex-col gap-4">
59
- <label className="flex flex-col gap-1.5 text-sm">
60
- <span className="font-semibold">Message retention (days)</span>
61
- <input
62
- aria-label="Message retention (days)"
63
- type="number"
64
- min={1}
65
- className={INPUT_CLASS}
66
- value={messageRetentionDays}
67
- onChange={(e) => setMessageRetentionDays(e.target.value)}
68
- placeholder="No automatic purge"
69
- />
70
- <span className="text-xs text-text-muted">
71
- Applies to any message, in any folder, regardless of age.
72
- </span>
73
- </label>
74
- <label className="flex flex-col gap-1.5 text-sm">
75
- <span className="font-semibold">Audit log retention (days)</span>
76
- <input
77
- aria-label="Audit log retention (days)"
78
- type="number"
79
- min={MIN_AUDIT_LOG_RETENTION_DAYS}
80
- className={INPUT_CLASS}
81
- value={auditLogRetentionDays}
82
- onChange={(e) => setAuditLogRetentionDays(e.target.value)}
83
- placeholder="Keep forever"
84
- />
85
- <span className="text-xs text-text-muted">
86
- Cannot be set below {MIN_AUDIT_LOG_RETENTION_DAYS} days. Never applies to the
87
- tamper-evident escrow audit chain.
88
- </span>
89
- </label>
90
- <div>
91
- <Button type="submit" loading={saving} disabled={saving} className="!w-auto">
92
- Save
93
- </Button>
94
- </div>
95
- </form>
96
- </div>
97
- );
98
- }
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ import React, { FormEvent, useEffect, useState } from "react";
6
+ import { ApiRequestError } from "@rapidmx/react-shared/util/api.js";
7
+ import { MIN_AUDIT_LOG_RETENTION_DAYS, RetentionPolicy, RetentionPolicyUpdate, updateRetentionPolicy } from "@rapidmx/react-shared/admin/retentionPolicyApi.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 Modal from "@rapidmx/react-shared/components/overlays/Modal.js";
11
+
12
+ const INPUT_CLASS =
13
+ "w-full text-sm py-2 px-3 border border-border rounded-sm bg-surface text-text focus:outline-none focus:border-primary";
14
+
15
+ /** Whether saving `next` days newly starts purging (nothing was configured) or purges sooner than `saved` days. */
16
+ function shortensRetention(next: number | null | undefined, saved: number | null | undefined): boolean {
17
+ return next != null && (saved == null || next < saved);
18
+ }
19
+
20
+ /** The retention policy editor, shared by the Retention Policy page and the setup wizard. */
21
+ export default function RetentionPolicyForm({
22
+ policy,
23
+ onChange,
24
+ onDirtyChange,
25
+ }: {
26
+ policy: RetentionPolicy;
27
+ onChange: (p: RetentionPolicy) => void;
28
+ /** Told whether the form has edits that haven't been saved. */
29
+ onDirtyChange?: (dirty: boolean) => void;
30
+ }) {
31
+ const [messageRetentionDays, setMessageRetentionDays] = useState(policy.messageRetentionDays?.toString() ?? "");
32
+ const [auditLogRetentionDays, setAuditLogRetentionDays] = useState(policy.auditLogRetentionDays?.toString() ?? "");
33
+ const [error, setError] = useState<string | null>(null);
34
+ const [saving, setSaving] = useState(false);
35
+ const [saved, setSaved] = useState(false);
36
+
37
+ // Edits are unsaved until they match what was loaded or last saved.
38
+ const snapshot = JSON.stringify([messageRetentionDays, auditLogRetentionDays]);
39
+ const [savedSnapshot, setSavedSnapshot] = useState(snapshot);
40
+ const dirty: boolean = snapshot !== savedSnapshot;
41
+ useEffect(() => onDirtyChange?.(dirty), [dirty]);
42
+
43
+ // The retention currently in effect, and a pending save that would newly start or shorten either period - which
44
+ // permanently deletes existing mail or audit-log entries on the next purge run, so it's confirmed first.
45
+ const [savedMessageDays, setSavedMessageDays] = useState(policy.messageRetentionDays);
46
+ const [savedAuditDays, setSavedAuditDays] = useState(policy.auditLogRetentionDays);
47
+ const [pendingPatch, setPendingPatch] = useState<RetentionPolicyUpdate | null>(null);
48
+
49
+ function handleSubmit(e: FormEvent) {
50
+ e.preventDefault();
51
+ // A blank field is sent as `null`, which clears a configured age back to no automatic purge.
52
+ const patch: RetentionPolicyUpdate = {
53
+ messageRetentionDays: messageRetentionDays.trim() === "" ? null : Number(messageRetentionDays),
54
+ auditLogRetentionDays: auditLogRetentionDays.trim() === "" ? null : Number(auditLogRetentionDays),
55
+ };
56
+ if (
57
+ shortensRetention(patch.messageRetentionDays, savedMessageDays) ||
58
+ shortensRetention(patch.auditLogRetentionDays, savedAuditDays)
59
+ ) {
60
+ setPendingPatch(patch);
61
+ return;
62
+ }
63
+ void save(patch);
64
+ }
65
+
66
+ async function save(patch: RetentionPolicyUpdate) {
67
+ setPendingPatch(null);
68
+ setError(null);
69
+ setSaved(false);
70
+ setSaving(true);
71
+ try {
72
+ const updated = await updateRetentionPolicy(patch);
73
+ setSavedMessageDays(updated.messageRetentionDays);
74
+ setSavedAuditDays(updated.auditLogRetentionDays);
75
+ onChange(updated);
76
+ setSavedSnapshot(snapshot);
77
+ setSaved(true);
78
+ } catch (err) {
79
+ setError(err instanceof ApiRequestError ? err.message : "Could not save the retention policy.");
80
+ } finally {
81
+ setSaving(false);
82
+ }
83
+ }
84
+
85
+ return (
86
+ <div className="max-w-xl">
87
+ <h1 className="text-xl font-bold uppercase tracking-wide mb-1">Retention Policy</h1>
88
+ <p className="text-sm text-text-muted mb-5">
89
+ Automatically and permanently deletes mail/audit-log entries older than the configured age.
90
+ Leave a field blank for no automatic purge. This does not apply to a mailbox that is a
91
+ custodian on an active legal hold — a held message is skipped and retried on a later run once
92
+ the hold is lifted.
93
+ </p>
94
+
95
+ {error && <Alert>{error}</Alert>}
96
+ {saved && !error && <div className="mb-4 text-sm text-success font-medium">Saved.</div>}
97
+
98
+ <form onSubmit={handleSubmit} className="flex flex-col gap-4">
99
+ <label className="flex flex-col gap-1.5 text-sm">
100
+ <span className="font-semibold">Message retention (days)</span>
101
+ <input
102
+ aria-label="Message retention (days)"
103
+ type="number"
104
+ min={1}
105
+ className={INPUT_CLASS}
106
+ value={messageRetentionDays}
107
+ onChange={(e) => setMessageRetentionDays(e.target.value)}
108
+ placeholder="No automatic purge"
109
+ />
110
+ <span className="text-xs text-text-muted">
111
+ Applies to any message, in any folder, regardless of age.
112
+ </span>
113
+ </label>
114
+ <label className="flex flex-col gap-1.5 text-sm">
115
+ <span className="font-semibold">Audit log retention (days)</span>
116
+ <input
117
+ aria-label="Audit log retention (days)"
118
+ type="number"
119
+ min={MIN_AUDIT_LOG_RETENTION_DAYS}
120
+ className={INPUT_CLASS}
121
+ value={auditLogRetentionDays}
122
+ onChange={(e) => setAuditLogRetentionDays(e.target.value)}
123
+ placeholder="Keep forever"
124
+ />
125
+ <span className="text-xs text-text-muted">
126
+ Cannot be set below {MIN_AUDIT_LOG_RETENTION_DAYS} days. Never applies to the
127
+ tamper-evident escrow audit chain.
128
+ </span>
129
+ </label>
130
+ <div>
131
+ <Button type="submit" loading={saving} disabled={saving} className="!w-auto">
132
+ Save
133
+ </Button>
134
+ </div>
135
+ </form>
136
+
137
+ <Modal open={pendingPatch !== null} onClose={() => setPendingPatch(null)} title="Delete older data?">
138
+ {shortensRetention(pendingPatch?.messageRetentionDays, savedMessageDays) && (
139
+ <p className="text-sm mb-3">
140
+ {savedMessageDays == null
141
+ ? "Mail isn't deleted automatically today."
142
+ : `Mail is currently kept for ${savedMessageDays} days.`}{" "}
143
+ With this change, every message older than <strong>{pendingPatch?.messageRetentionDays} days</strong>,
144
+ in every mailbox and folder, is permanently deleted on the next purge run - and so on from then on.
145
+ Mailboxes on an active legal hold are skipped.
146
+ </p>
147
+ )}
148
+ {shortensRetention(pendingPatch?.auditLogRetentionDays, savedAuditDays) && (
149
+ <p className="text-sm mb-3">
150
+ {savedAuditDays == null
151
+ ? "Audit-log entries are kept forever today."
152
+ : `Audit-log entries are currently kept for ${savedAuditDays} days.`}{" "}
153
+ With this change, every audit-log entry older than{" "}
154
+ <strong>{pendingPatch?.auditLogRetentionDays} days</strong> is permanently deleted on the next purge
155
+ run. The escrow audit chain is never purged.
156
+ </p>
157
+ )}
158
+ <p className="text-sm font-semibold text-danger mb-4">Deleted data can&rsquo;t be recovered.</p>
159
+ <div className="flex gap-3 justify-end">
160
+ <Button type="button" variant="secondary" className="!w-auto" onClick={() => setPendingPatch(null)}>
161
+ Cancel
162
+ </Button>
163
+ <Button
164
+ type="button"
165
+ className="!w-auto !bg-none !bg-danger !border-danger hover:!bg-danger"
166
+ onClick={() => void save(pendingPatch!)}
167
+ >
168
+ Save and delete older data
169
+ </Button>
170
+ </div>
171
+ </Modal>
172
+ </div>
173
+ );
174
+ }
@@ -13,6 +13,7 @@ import FormField from "@rapidmx/react-shared/components/forms/FormField.js";
13
13
  import EscrowScopeKeyAndHoldersFields, {
14
14
  emptyEscrowScopeKeyAndHoldersValue,
15
15
  EscrowScopeKeyAndHoldersValue,
16
+ selfAsHolderError,
16
17
  } from "../escrowScopes/EscrowScopeKeyAndHoldersFields.js";
17
18
 
18
19
  const INPUT_CLASS =
@@ -20,6 +21,9 @@ const INPUT_CLASS =
20
21
 
21
22
  type Mode = "none" | "generate" | "existing";
22
23
 
24
+ /** How long a download's object URL is kept, since some browsers are still reading it after the click returns. */
25
+ export const DOWNLOAD_URL_LIFETIME_MS = 60_000;
26
+
23
27
  /** Offers `text` to the browser as a file download. */
24
28
  export function downloadTextFile(filename: string, text: string, type: string = "application/x-pem-file"): void {
25
29
  const url = URL.createObjectURL(new Blob([text], { type }));
@@ -29,7 +33,7 @@ export function downloadTextFile(filename: string, text: string, type: string =
29
33
  document.body.appendChild(link);
30
34
  link.click();
31
35
  link.remove();
32
- URL.revokeObjectURL(url);
36
+ setTimeout(() => URL.revokeObjectURL(url), DOWNLOAD_URL_LIFETIME_MS);
33
37
  }
34
38
 
35
39
  function fileSafe(name: string): string {
@@ -42,12 +46,13 @@ function fileSafe(name: string): string {
42
46
  * generate the key pair here (downloading the private key, which never leaves the browser), paste in an existing
43
47
  * certificate, or go without escrow.
44
48
  */
45
- export default function EscrowSetupStep() {
49
+ export default function EscrowSetupStep({ adminUid }: { adminUid?: string }) {
46
50
  const [scopes, setScopes] = useState<EscrowScope[] | null>(null);
47
51
  const [mode, setMode] = useState<Mode>("none");
48
52
  const [name, setName] = useState("Escrow");
49
53
  const [validYears, setValidYears] = useState(5);
50
54
  const [generated, setGenerated] = useState<GeneratedEscrowKeys | null>(null);
55
+ const [downloadedPrivateKey, setDownloadedPrivateKey] = useState(false);
51
56
  const [savedPrivateKey, setSavedPrivateKey] = useState(false);
52
57
  const [keyAndHolders, setKeyAndHolders] = useState<EscrowScopeKeyAndHoldersValue>(emptyEscrowScopeKeyAndHoldersValue());
53
58
  const [error, setError] = useState<string | null>(null);
@@ -63,6 +68,7 @@ export default function EscrowSetupStep() {
63
68
  setMode(next);
64
69
  setError(null);
65
70
  setGenerated(null);
71
+ setDownloadedPrivateKey(false);
66
72
  setSavedPrivateKey(false);
67
73
  setKeyAndHolders(emptyEscrowScopeKeyAndHoldersValue());
68
74
  }
@@ -99,7 +105,17 @@ export default function EscrowSetupStep() {
99
105
  setError("A name is required.");
100
106
  return;
101
107
  }
102
- if (!keyAndHolders.publicKey.trim() || !keyAndHolders.keyType.trim() || !keyAndHolders.fingerprint.trim()) {
108
+ // Generated keys are used exactly as generated; only a pasted-in certificate's fields come from the form.
109
+ const publicKey = generated
110
+ ? generated.publicKey
111
+ : {
112
+ publicKey: keyAndHolders.publicKey.trim(),
113
+ type: keyAndHolders.keyType.trim(),
114
+ fingerprint: keyAndHolders.fingerprint.trim(),
115
+ notBefore: new Date(keyAndHolders.notBefore).getTime(),
116
+ notAfter: new Date(keyAndHolders.notAfter).getTime(),
117
+ };
118
+ if (!publicKey.publicKey || !publicKey.type || !publicKey.fingerprint) {
103
119
  setError("The public key, its type, and its fingerprint are all required.");
104
120
  return;
105
121
  }
@@ -111,17 +127,16 @@ export default function EscrowSetupStep() {
111
127
  setError("Required holders must be between 1 and the number of holders.");
112
128
  return;
113
129
  }
130
+ const selfError = selfAsHolderError(keyAndHolders.holderUserUids, adminUid);
131
+ if (selfError) {
132
+ setError(selfError);
133
+ return;
134
+ }
114
135
  setBusy(true);
115
136
  try {
116
137
  const created = await createEscrowScope({
117
138
  name: name.trim(),
118
- publicKey: {
119
- publicKey: keyAndHolders.publicKey.trim(),
120
- type: keyAndHolders.keyType.trim(),
121
- fingerprint: keyAndHolders.fingerprint.trim(),
122
- notBefore: new Date(keyAndHolders.notBefore).getTime(),
123
- notAfter: new Date(keyAndHolders.notAfter).getTime(),
124
- },
139
+ publicKey,
125
140
  holderUserUids: keyAndHolders.holderUserUids,
126
141
  requiredHolders: keyAndHolders.requiredHolders,
127
142
  notifySubjectOnAccess: keyAndHolders.notifySubjectOnAccess,
@@ -138,7 +153,12 @@ export default function EscrowSetupStep() {
138
153
 
139
154
  const scopeForm = (
140
155
  <form onSubmit={create} className="flex flex-col gap-5">
141
- <EscrowScopeKeyAndHoldersFields value={keyAndHolders} onChange={setKeyAndHolders} disabled={mode === "generate" && busy} />
156
+ <EscrowScopeKeyAndHoldersFields
157
+ value={keyAndHolders}
158
+ onChange={setKeyAndHolders}
159
+ disabled={mode === "generate" && busy}
160
+ keyReadOnly={mode === "generate"}
161
+ />
142
162
  <div>
143
163
  <Button type="submit" loading={busy} disabled={busy} className="!w-auto">
144
164
  Create escrow scope
@@ -221,11 +241,19 @@ export default function EscrowSetupStep() {
221
241
  Download the private key now and give it to your escrow holders. It isn&rsquo;t stored
222
242
  anywhere else - if it&rsquo;s lost, no escrowed mail can ever be recovered.
223
243
  </Alert>
244
+ <Alert>
245
+ You&rsquo;re downloading this private key, so you must not also be one of its holders:
246
+ pick holders other than yourself, hand the key over, and delete your copy once they
247
+ have it. Otherwise one person could both configure escrow and recover mail with it.
248
+ </Alert>
224
249
  <div className="flex flex-wrap gap-2">
225
250
  <Button
226
251
  type="button"
227
252
  className="!w-auto"
228
- onClick={() => downloadTextFile(`${fileSafe(name)}-private-key.pem`, generated.privateKeyPem)}
253
+ onClick={() => {
254
+ downloadTextFile(`${fileSafe(name)}-private-key.pem`, generated.privateKeyPem);
255
+ setDownloadedPrivateKey(true);
256
+ }}
229
257
  >
230
258
  Download private key
231
259
  </Button>
@@ -239,9 +267,17 @@ export default function EscrowSetupStep() {
239
267
  </Button>
240
268
  </div>
241
269
  <label className="flex items-center gap-2">
242
- <input type="checkbox" checked={savedPrivateKey} onChange={(e) => setSavedPrivateKey(e.target.checked)} />
270
+ <input
271
+ type="checkbox"
272
+ checked={savedPrivateKey}
273
+ disabled={!downloadedPrivateKey}
274
+ onChange={(e) => setSavedPrivateKey(e.target.checked)}
275
+ />
243
276
  I&rsquo;ve saved the private key somewhere safe
244
277
  </label>
278
+ {!downloadedPrivateKey && (
279
+ <p className="text-xs text-text-muted">Download the private key before continuing.</p>
280
+ )}
245
281
  </div>
246
282
  )}
247
283
  </div>