@antelopejs/dms 0.6.2 → 0.7.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 (444) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/db/models/notification-feed-filter.d.ts +0 -1
  3. package/dist/db/models/notification-feed-filter.js +0 -4
  4. package/dist/db/models/notification-feed-filter.js.map +1 -1
  5. package/dist/db/models/signInAttempts.model.d.ts +18 -0
  6. package/dist/db/models/signInAttempts.model.js +83 -12
  7. package/dist/db/models/signInAttempts.model.js.map +1 -1
  8. package/dist/db/models/userEmailChanges.model.d.ts +8 -1
  9. package/dist/db/models/userEmailChanges.model.js +27 -2
  10. package/dist/db/models/userEmailChanges.model.js.map +1 -1
  11. package/dist/db/models/userNotificationPreferences.model.d.ts +0 -2
  12. package/dist/db/models/userNotificationPreferences.model.js +0 -13
  13. package/dist/db/models/userNotificationPreferences.model.js.map +1 -1
  14. package/dist/db/models/userNotifications.model.d.ts +5 -2
  15. package/dist/db/models/userNotifications.model.js +19 -2
  16. package/dist/db/models/userNotifications.model.js.map +1 -1
  17. package/dist/db/tables/signInAttempts.table.d.ts +2 -1
  18. package/dist/db/tables/signInAttempts.table.js +4 -0
  19. package/dist/db/tables/signInAttempts.table.js.map +1 -1
  20. package/dist/db/tables/userEmailChanges.table.d.ts +2 -1
  21. package/dist/db/tables/userEmailChanges.table.js +6 -1
  22. package/dist/db/tables/userEmailChanges.table.js.map +1 -1
  23. package/dist/db/tables/userNotificationPreferences.table.d.ts +0 -1
  24. package/dist/db/tables/userNotificationPreferences.table.js +0 -4
  25. package/dist/db/tables/userNotificationPreferences.table.js.map +1 -1
  26. package/dist/implementations/dms/nav-badges.d.ts +6 -4
  27. package/dist/implementations/dms/nav-badges.js +6 -5
  28. package/dist/implementations/dms/nav-badges.js.map +1 -1
  29. package/dist/implementations/dms/page.d.ts +1 -0
  30. package/dist/implementations/dms/page.js +46 -8
  31. package/dist/implementations/dms/page.js.map +1 -1
  32. package/dist/implementations/dms/permission-preview.d.ts +1 -1
  33. package/dist/implementations/dms/permission-preview.js +9 -4
  34. package/dist/implementations/dms/permission-preview.js.map +1 -1
  35. package/dist/implementations/dms-auth/index.d.ts +3 -2
  36. package/dist/implementations/dms-auth/index.js +39 -35
  37. package/dist/implementations/dms-auth/index.js.map +1 -1
  38. package/dist/implementations/dms-auth/token-session.d.ts +3 -0
  39. package/dist/implementations/dms-auth/token-session.js +22 -0
  40. package/dist/implementations/dms-auth/token-session.js.map +1 -0
  41. package/dist/implementations/dms-notifications/index.d.ts +0 -1
  42. package/dist/implementations/dms-notifications/index.js +0 -7
  43. package/dist/implementations/dms-notifications/index.js.map +1 -1
  44. package/dist/pages/settings/settings-index.js +3 -2
  45. package/dist/pages/settings/settings-index.js.map +1 -1
  46. package/dist/pages/settings/users/account-activity-feed.d.ts +1 -1
  47. package/dist/pages/settings/users/account-activity-feed.js +1 -1
  48. package/dist/pages/settings/users/account-activity-feed.js.map +1 -1
  49. package/dist/pages/settings/users/account-activity.d.ts +1 -1
  50. package/dist/pages/settings/users/account-activity.js +1 -1
  51. package/dist/pages/settings/users/account-activity.js.map +1 -1
  52. package/dist/pages/settings/users/account-credentials.d.ts +3 -0
  53. package/dist/pages/settings/users/account-credentials.js +2 -0
  54. package/dist/pages/settings/users/account-credentials.js.map +1 -1
  55. package/dist/pages/settings/users/current-password.d.ts +1 -1
  56. package/dist/pages/settings/users/current-password.js +23 -2
  57. package/dist/pages/settings/users/current-password.js.map +1 -1
  58. package/dist/pages/settings/users/email-change.d.ts +1 -1
  59. package/dist/pages/settings/users/email-change.js +33 -26
  60. package/dist/pages/settings/users/email-change.js.map +1 -1
  61. package/dist/pages/settings/users/invite-resend.js +0 -1
  62. package/dist/pages/settings/users/invite-resend.js.map +1 -1
  63. package/dist/pages/settings/users/invites.d.ts +1 -2
  64. package/dist/pages/settings/users/invites.js +21 -19
  65. package/dist/pages/settings/users/invites.js.map +1 -1
  66. package/dist/pages/settings/users/member-invite-batch.js +0 -1
  67. package/dist/pages/settings/users/member-invite-batch.js.map +1 -1
  68. package/dist/pages/settings/users/member-invite-form.js +10 -22
  69. package/dist/pages/settings/users/member-invite-form.js.map +1 -1
  70. package/dist/pages/settings/users/member-role-options.d.ts +6 -4
  71. package/dist/pages/settings/users/member-role-options.js +15 -4
  72. package/dist/pages/settings/users/member-role-options.js.map +1 -1
  73. package/dist/pages/settings/users/members.d.ts +2 -3
  74. package/dist/pages/settings/users/members.js +7 -12
  75. package/dist/pages/settings/users/members.js.map +1 -1
  76. package/dist/pages/settings/users/notifications.d.ts +1 -8
  77. package/dist/pages/settings/users/notifications.js +6 -38
  78. package/dist/pages/settings/users/notifications.js.map +1 -1
  79. package/dist/pages/settings/users/permission-tree-nodes.d.ts +1 -1
  80. package/dist/pages/settings/users/permission-tree-nodes.js +23 -9
  81. package/dist/pages/settings/users/permission-tree-nodes.js.map +1 -1
  82. package/dist/pages/settings/users/permission-warnings.d.ts +7 -0
  83. package/dist/pages/settings/users/permission-warnings.js +42 -0
  84. package/dist/pages/settings/users/permission-warnings.js.map +1 -0
  85. package/dist/pages/settings/users/profile-helpers.d.ts +1 -3
  86. package/dist/pages/settings/users/profile-helpers.js +0 -16
  87. package/dist/pages/settings/users/profile-helpers.js.map +1 -1
  88. package/dist/pages/settings/users/role-editor-store.js +6 -3
  89. package/dist/pages/settings/users/role-editor-store.js.map +1 -1
  90. package/dist/pages/settings/users/role-editor.d.ts +2 -1
  91. package/dist/pages/settings/users/role-editor.js +8 -4
  92. package/dist/pages/settings/users/role-editor.js.map +1 -1
  93. package/dist/pages/settings/users/role-preview.js +2 -1
  94. package/dist/pages/settings/users/role-preview.js.map +1 -1
  95. package/dist/pages/settings/users/roles.js +5 -1
  96. package/dist/pages/settings/users/roles.js.map +1 -1
  97. package/dist/pages/settings/users/security-attention.d.ts +4 -0
  98. package/dist/pages/settings/users/security-attention.js +23 -7
  99. package/dist/pages/settings/users/security-attention.js.map +1 -1
  100. package/dist/pages/settings/users/security.d.ts +2 -1
  101. package/dist/pages/settings/users/security.js +13 -2
  102. package/dist/pages/settings/users/security.js.map +1 -1
  103. package/dist/pages/settings/users/two-factor-operations.d.ts +2 -1
  104. package/dist/pages/settings/users/two-factor-operations.js +28 -29
  105. package/dist/pages/settings/users/two-factor-operations.js.map +1 -1
  106. package/dist/routes/auth/forgot-password.js +3 -0
  107. package/dist/routes/auth/forgot-password.js.map +1 -1
  108. package/dist/routes/auth/index.d.ts +1 -0
  109. package/dist/routes/auth/index.js +1 -0
  110. package/dist/routes/auth/index.js.map +1 -1
  111. package/dist/routes/auth/invite.js +28 -4
  112. package/dist/routes/auth/invite.js.map +1 -1
  113. package/dist/routes/auth/login-throttle.d.ts +2 -0
  114. package/dist/routes/auth/login-throttle.js +5 -4
  115. package/dist/routes/auth/login-throttle.js.map +1 -1
  116. package/dist/routes/auth/request-2fa-email.js +6 -18
  117. package/dist/routes/auth/request-2fa-email.js.map +1 -1
  118. package/dist/routes/auth/reset-code.d.ts +3 -0
  119. package/dist/routes/auth/reset-code.js +37 -0
  120. package/dist/routes/auth/reset-code.js.map +1 -0
  121. package/dist/routes/auth/reset-password.d.ts +2 -2
  122. package/dist/routes/auth/reset-password.js +5 -10
  123. package/dist/routes/auth/reset-password.js.map +1 -1
  124. package/dist/routes/auth/signup.js +10 -32
  125. package/dist/routes/auth/signup.js.map +1 -1
  126. package/dist/routes/auth/two-factor-throttle.d.ts +5 -0
  127. package/dist/routes/auth/two-factor-throttle.js +81 -0
  128. package/dist/routes/auth/two-factor-throttle.js.map +1 -0
  129. package/dist/routes/auth/validate-forgot-password-token.js +2 -8
  130. package/dist/routes/auth/validate-forgot-password-token.js.map +1 -1
  131. package/dist/routes/auth/validate-invite-token.d.ts +1 -0
  132. package/dist/routes/auth/validate-invite-token.js +11 -0
  133. package/dist/routes/auth/validate-invite-token.js.map +1 -0
  134. package/dist/routes/auth/verify-2fa.js +10 -13
  135. package/dist/routes/auth/verify-2fa.js.map +1 -1
  136. package/dist/routes/auth.d.ts +1 -0
  137. package/dist/routes/auth.js +11 -1
  138. package/dist/routes/auth.js.map +1 -1
  139. package/dist/test/helpers/auth.d.ts +0 -1
  140. package/dist/test/helpers/auth.js +0 -1
  141. package/dist/test/helpers/auth.js.map +1 -1
  142. package/dist/test/helpers/emails.d.ts +10 -0
  143. package/dist/test/helpers/emails.js +36 -0
  144. package/dist/test/helpers/emails.js.map +1 -0
  145. package/dist/test/helpers/fixtures.d.ts +0 -1
  146. package/dist/test/helpers/fixtures.js +1 -2
  147. package/dist/test/helpers/fixtures.js.map +1 -1
  148. package/dist/test/helpers/page-access.d.ts +1 -0
  149. package/dist/test/helpers/page-access.js +6 -1
  150. package/dist/test/helpers/page-access.js.map +1 -1
  151. package/dist/test/integration/auth/current-password.test.d.ts +1 -0
  152. package/dist/test/integration/auth/current-password.test.js +65 -0
  153. package/dist/test/integration/auth/current-password.test.js.map +1 -0
  154. package/dist/test/integration/auth/password-reset.test.d.ts +1 -0
  155. package/dist/test/integration/auth/password-reset.test.js +126 -0
  156. package/dist/test/integration/auth/password-reset.test.js.map +1 -0
  157. package/dist/test/integration/auth/session-revocation.test.d.ts +1 -0
  158. package/dist/test/integration/auth/session-revocation.test.js +45 -0
  159. package/dist/test/integration/auth/session-revocation.test.js.map +1 -0
  160. package/dist/test/integration/auth/two-factor-codes.test.d.ts +1 -0
  161. package/dist/test/integration/auth/two-factor-codes.test.js +335 -0
  162. package/dist/test/integration/auth/two-factor-codes.test.js.map +1 -0
  163. package/dist/test/integration/auth/two-factor-password.test.js +5 -1
  164. package/dist/test/integration/auth/two-factor-password.test.js.map +1 -1
  165. package/dist/test/integration/auth/two-factor-token.test.d.ts +1 -0
  166. package/dist/test/integration/auth/two-factor-token.test.js +92 -0
  167. package/dist/test/integration/auth/two-factor-token.test.js.map +1 -0
  168. package/dist/test/integration/email-change.test.js +36 -0
  169. package/dist/test/integration/email-change.test.js.map +1 -1
  170. package/dist/test/integration/invite-extension-edit.test.js +0 -1
  171. package/dist/test/integration/invite-extension-edit.test.js.map +1 -1
  172. package/dist/test/integration/invite-link-status.test.d.ts +1 -0
  173. package/dist/test/integration/invite-link-status.test.js +110 -0
  174. package/dist/test/integration/invite-link-status.test.js.map +1 -0
  175. package/dist/test/integration/invite-resolution.test.js +0 -3
  176. package/dist/test/integration/invite-resolution.test.js.map +1 -1
  177. package/dist/test/integration/member-settings-access.test.js +17 -0
  178. package/dist/test/integration/member-settings-access.test.js.map +1 -1
  179. package/dist/test/integration/notification-unread-badge.test.d.ts +1 -0
  180. package/dist/test/integration/notification-unread-badge.test.js +92 -0
  181. package/dist/test/integration/notification-unread-badge.test.js.map +1 -0
  182. package/dist/test/integration/permission-warnings.test.d.ts +1 -0
  183. package/dist/test/integration/permission-warnings.test.js +71 -0
  184. package/dist/test/integration/permission-warnings.test.js.map +1 -0
  185. package/dist/test/integration/removed-member-notifications.test.d.ts +1 -0
  186. package/dist/test/integration/removed-member-notifications.test.js +80 -0
  187. package/dist/test/integration/removed-member-notifications.test.js.map +1 -0
  188. package/dist/test/integration/role-permission-ancestors.test.d.ts +1 -0
  189. package/dist/test/integration/role-permission-ancestors.test.js +146 -0
  190. package/dist/test/integration/role-permission-ancestors.test.js.map +1 -0
  191. package/dist/test/integration/tenant-lifecycle.test.js +0 -4
  192. package/dist/test/integration/tenant-lifecycle.test.js.map +1 -1
  193. package/dist/test/unit/auth-session-revocation.test.d.ts +1 -0
  194. package/dist/test/unit/auth-session-revocation.test.js +105 -0
  195. package/dist/test/unit/auth-session-revocation.test.js.map +1 -0
  196. package/dist/test/unit/db/email-normalization.test.js +0 -1
  197. package/dist/test/unit/db/email-normalization.test.js.map +1 -1
  198. package/dist/test/unit/db/notification-feed-filter.test.js +0 -16
  199. package/dist/test/unit/db/notification-feed-filter.test.js.map +1 -1
  200. package/dist/test/unit/db/notification-inbox.test.js +63 -13
  201. package/dist/test/unit/db/notification-inbox.test.js.map +1 -1
  202. package/dist/test/unit/db/notification-preferences.test.js +0 -17
  203. package/dist/test/unit/db/notification-preferences.test.js.map +1 -1
  204. package/dist/test/unit/implementations/dms/empty-menu-group.test.d.ts +1 -0
  205. package/dist/test/unit/implementations/dms/empty-menu-group.test.js +133 -0
  206. package/dist/test/unit/implementations/dms/empty-menu-group.test.js.map +1 -0
  207. package/dist/test/unit/implementations/dms/layout-banners.test.js +2 -1
  208. package/dist/test/unit/implementations/dms/layout-banners.test.js.map +1 -1
  209. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.d.ts +1 -0
  210. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.js +149 -0
  211. package/dist/test/unit/implementations/dms/menu-hidden-blocks.test.js.map +1 -0
  212. package/dist/test/unit/implementations/dms/nav-badges.test.js +55 -4
  213. package/dist/test/unit/implementations/dms/nav-badges.test.js.map +1 -1
  214. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.d.ts +1 -0
  215. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.js +118 -0
  216. package/dist/test/unit/implementations/dms/page-all-components-hidden.test.js.map +1 -0
  217. package/dist/test/unit/implementations/dms/permission-preview-aggregate.test.js +16 -0
  218. package/dist/test/unit/implementations/dms/permission-preview-aggregate.test.js.map +1 -1
  219. package/dist/test/unit/implementations/dms/permission-preview-cost.test.js +5 -3
  220. package/dist/test/unit/implementations/dms/permission-preview-cost.test.js.map +1 -1
  221. package/dist/test/unit/implementations/dms/permission-preview-menu.test.js +29 -3
  222. package/dist/test/unit/implementations/dms/permission-preview-menu.test.js.map +1 -1
  223. package/dist/test/unit/implementations/dms/quick-actions-button.test.js +4 -2
  224. package/dist/test/unit/implementations/dms/quick-actions-button.test.js.map +1 -1
  225. package/dist/test/unit/implementations/dms/user-permissions-gate.test.js +2 -1
  226. package/dist/test/unit/implementations/dms/user-permissions-gate.test.js.map +1 -1
  227. package/dist/test/unit/implementations/dms-base/table-view-shared-controller.test.js +2 -1
  228. package/dist/test/unit/implementations/dms-base/table-view-shared-controller.test.js.map +1 -1
  229. package/dist/test/unit/interfaces/dms/component-children-permissions.test.js +7 -2
  230. package/dist/test/unit/interfaces/dms/component-children-permissions.test.js.map +1 -1
  231. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.d.ts +1 -0
  232. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.js +133 -0
  233. package/dist/test/unit/interfaces/dms/form-watch-permissions.test.js.map +1 -0
  234. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.d.ts +1 -0
  235. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.js +149 -0
  236. package/dist/test/unit/interfaces/dms/has-permission-ancestors.test.js.map +1 -0
  237. package/dist/test/unit/interfaces/dms/invite-extension.test.js +13 -0
  238. package/dist/test/unit/interfaces/dms/invite-extension.test.js.map +1 -1
  239. package/dist/test/unit/interfaces/dms/member-access.test.js +27 -1
  240. package/dist/test/unit/interfaces/dms/member-access.test.js.map +1 -1
  241. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.d.ts +1 -0
  242. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.js +31 -0
  243. package/dist/test/unit/interfaces/dms/nav-badge-tones.test.js.map +1 -0
  244. package/dist/test/unit/interfaces/dms/page-extension.test.js +4 -1
  245. package/dist/test/unit/interfaces/dms/page-extension.test.js.map +1 -1
  246. package/dist/test/unit/interfaces/dms/permission-requirements.test.d.ts +1 -0
  247. package/dist/test/unit/interfaces/dms/permission-requirements.test.js +144 -0
  248. package/dist/test/unit/interfaces/dms/permission-requirements.test.js.map +1 -0
  249. package/dist/test/unit/interfaces/dms-base/layout-header-actions.test.js +6 -2
  250. package/dist/test/unit/interfaces/dms-base/layout-header-actions.test.js.map +1 -1
  251. package/dist/test/unit/interfaces/dms-base/lists-and-settings-catalog.test.js +1 -1
  252. package/dist/test/unit/interfaces/dms-base/lists-and-settings-catalog.test.js.map +1 -1
  253. package/dist/test/unit/interfaces/dms-base/table-view-export-permission.test.js +2 -1
  254. package/dist/test/unit/interfaces/dms-base/table-view-export-permission.test.js.map +1 -1
  255. package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js +2 -1
  256. package/dist/test/unit/interfaces/dms-base/table-view-reduced-chrome.test.js.map +1 -1
  257. package/dist/test/unit/interfaces/dms-base/table-view-shared-controller-permissions.test.js +2 -1
  258. package/dist/test/unit/interfaces/dms-base/table-view-shared-controller-permissions.test.js.map +1 -1
  259. package/dist/test/unit/pages/settings/account-activity-feed.test.js +2 -2
  260. package/dist/test/unit/pages/settings/account-activity-feed.test.js.map +1 -1
  261. package/dist/test/unit/pages/settings/account-activity.test.js +11 -2
  262. package/dist/test/unit/pages/settings/account-activity.test.js.map +1 -1
  263. package/dist/test/unit/pages/settings/invite-email-delivery.test.js +0 -1
  264. package/dist/test/unit/pages/settings/invite-email-delivery.test.js.map +1 -1
  265. package/dist/test/unit/pages/settings/invite-email-validation-option.test.d.ts +1 -0
  266. package/dist/test/unit/pages/settings/invite-email-validation-option.test.js +33 -0
  267. package/dist/test/unit/pages/settings/invite-email-validation-option.test.js.map +1 -0
  268. package/dist/test/unit/pages/settings/member-lists-page-size.test.d.ts +1 -0
  269. package/dist/test/unit/pages/settings/member-lists-page-size.test.js +22 -0
  270. package/dist/test/unit/pages/settings/member-lists-page-size.test.js.map +1 -0
  271. package/dist/test/unit/pages/settings/member-table-widths.test.js +2 -2
  272. package/dist/test/unit/pages/settings/member-table-widths.test.js.map +1 -1
  273. package/dist/test/unit/pages/settings/members-page.test.js +7 -10
  274. package/dist/test/unit/pages/settings/members-page.test.js.map +1 -1
  275. package/dist/test/unit/pages/settings/notifications-access-gate.test.js +3 -10
  276. package/dist/test/unit/pages/settings/notifications-access-gate.test.js.map +1 -1
  277. package/dist/test/unit/pages/settings/permission-tree-nodes.test.js +57 -0
  278. package/dist/test/unit/pages/settings/permission-tree-nodes.test.js.map +1 -1
  279. package/dist/test/unit/pages/settings/permission-warnings.test.d.ts +1 -0
  280. package/dist/test/unit/pages/settings/permission-warnings.test.js +49 -0
  281. package/dist/test/unit/pages/settings/permission-warnings.test.js.map +1 -0
  282. package/dist/test/unit/pages/settings/role-editor.test.js +16 -0
  283. package/dist/test/unit/pages/settings/role-editor.test.js.map +1 -1
  284. package/dist/test/unit/pages/settings/role-preview.test.js +7 -0
  285. package/dist/test/unit/pages/settings/role-preview.test.js.map +1 -1
  286. package/dist/test/unit/pages/settings/security-attention.test.d.ts +1 -0
  287. package/dist/test/unit/pages/settings/security-attention.test.js +74 -0
  288. package/dist/test/unit/pages/settings/security-attention.test.js.map +1 -0
  289. package/dist/test/unit/sanitize-user.test.d.ts +1 -0
  290. package/dist/test/unit/sanitize-user.test.js +21 -0
  291. package/dist/test/unit/sanitize-user.test.js.map +1 -0
  292. package/dist/test/unit/signup-email-validation.test.d.ts +1 -0
  293. package/dist/test/unit/signup-email-validation.test.js +79 -0
  294. package/dist/test/unit/signup-email-validation.test.js.map +1 -0
  295. package/dist/test/unit/validation/member-invite.schema.test.js +14 -52
  296. package/dist/test/unit/validation/member-invite.schema.test.js.map +1 -1
  297. package/dist/utils/account-notifications.d.ts +5 -0
  298. package/dist/utils/account-notifications.js +8 -0
  299. package/dist/utils/account-notifications.js.map +1 -1
  300. package/dist/utils/notification-emitter.d.ts +1 -1
  301. package/dist/utils/notification-emitter.js +1 -1
  302. package/dist/utils/notification-emitter.js.map +1 -1
  303. package/dist/utils/notification-tones.d.ts +2 -1
  304. package/dist/utils/notification-tones.js +5 -1
  305. package/dist/utils/notification-tones.js.map +1 -1
  306. package/dist/utils/one-time-code.d.ts +3 -0
  307. package/dist/utils/one-time-code.js +21 -0
  308. package/dist/utils/one-time-code.js.map +1 -0
  309. package/dist/utils/sign-in-monitor.d.ts +1 -0
  310. package/dist/utils/sign-in-monitor.js +3 -2
  311. package/dist/utils/sign-in-monitor.js.map +1 -1
  312. package/dist/utils/two-factor-codes.d.ts +10 -0
  313. package/dist/utils/two-factor-codes.js +76 -0
  314. package/dist/utils/two-factor-codes.js.map +1 -0
  315. package/dist/validation/auth.schema.d.ts +17 -0
  316. package/dist/validation/auth.schema.js +17 -6
  317. package/dist/validation/auth.schema.js.map +1 -1
  318. package/dist/validation/issue-message.d.ts +1 -0
  319. package/dist/validation/issue-message.js +9 -0
  320. package/dist/validation/issue-message.js.map +1 -0
  321. package/dist/validation/member-invite.schema.d.ts +1 -25
  322. package/dist/validation/member-invite.schema.js +2 -23
  323. package/dist/validation/member-invite.schema.js.map +1 -1
  324. package/frontend-vue/dms.frontend.ts +2 -0
  325. package/frontend-vue/layers/dms-auth/app/custom-pages/auth/forgot-validation.vue +3 -0
  326. package/frontend-vue/layers/dms-auth/app/custom-pages/auth/signup.vue +105 -5
  327. package/frontend-vue/layers/dms-auth/i18n/locales/auth-en-GB.json +20 -4
  328. package/frontend-vue/layers/dms-auth/i18n/locales/auth-fr-FR.json +20 -4
  329. package/frontend-vue/layers/dms-core/app/composables/useFieldErrors.ts +3 -2
  330. package/frontend-vue/layers/dms-core/app/types/menu.ts +15 -0
  331. package/frontend-vue/layers/dms-core/i18n/locales/core-en-GB.json +4 -1
  332. package/frontend-vue/layers/dms-core/i18n/locales/core-fr-FR.json +4 -1
  333. package/frontend-vue/layers/dms-layout/app/assets/css/main.css +20 -0
  334. package/frontend-vue/layers/dms-layout/app/build/components/layout/CommandPaletteAssistantAnswer.vue +75 -0
  335. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardFrame.vue +22 -0
  336. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +24 -10
  337. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardSidePanel.vue +139 -0
  338. package/frontend-vue/layers/dms-layout/app/build/components/layout/Footer.vue +4 -2
  339. package/frontend-vue/layers/dms-layout/app/build/components/layout/GithubStarPrompt.vue +90 -0
  340. package/frontend-vue/layers/dms-layout/app/build/components/layout/SidePanelHost.vue +17 -0
  341. package/frontend-vue/layers/dms-layout/app/build/components/notification/NotificationPopover.vue +25 -43
  342. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/members/MemberRolePicker.vue +24 -2
  343. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationMatrixCategory.vue +70 -25
  344. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/NotificationPreferencesForm.vue +25 -10
  345. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/notification/notificationDisplay.ts +41 -5
  346. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfilePreferencesSummary.vue +2 -1
  347. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/profile/ProfileSecuritySummary.vue +20 -4
  348. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RoleEditor.vue +21 -0
  349. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionArea.vue +16 -2
  350. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionBranch.vue +1 -0
  351. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionLeaf.vue +13 -1
  352. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionTree.vue +9 -0
  353. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/RolePermissionWarning.vue +46 -0
  354. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-permissions.ts +108 -29
  355. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/roles/role-types.ts +2 -0
  356. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityDialogFrame.vue +6 -6
  357. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityEmail.vue +7 -1
  358. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecuritySessions.vue +5 -4
  359. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityStatus.vue +4 -3
  360. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/security/SecurityTwoFactor.vue +54 -18
  361. package/frontend-vue/layers/dms-layout/app/build/components/pages/settings/shell/SettingsNav.vue +13 -8
  362. package/frontend-vue/layers/dms-layout/app/build/composables/command-palette/assistantGroups.ts +143 -0
  363. package/frontend-vue/layers/dms-layout/app/build/composables/command-palette/useCommandPaletteAssistantMode.ts +249 -0
  364. package/frontend-vue/layers/dms-layout/app/build/composables/general/useGithubStarPrompt.ts +178 -0
  365. package/frontend-vue/layers/dms-layout/app/build/composables/layout/sidePanelState.ts +191 -0
  366. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useHeaderActionControls.ts +51 -0
  367. package/frontend-vue/layers/dms-layout/app/build/composables/layout/useSidePanelWidth.ts +113 -0
  368. package/frontend-vue/layers/dms-layout/app/build/composables/navigation/useCategoryNavCards.ts +17 -10
  369. package/frontend-vue/layers/dms-layout/app/build/composables/notification/useNotificationGroupsOpen.ts +45 -0
  370. package/frontend-vue/layers/dms-layout/app/build/composables/settings/profile/useProfilePreferences.ts +8 -1
  371. package/frontend-vue/layers/dms-layout/app/build/composables/settings/security/useSecurityOverview.ts +50 -3
  372. package/frontend-vue/layers/dms-layout/app/build/composables/settings/useSettingsNavigation.ts +3 -0
  373. package/frontend-vue/layers/dms-layout/app/build/utils/categoryPages.ts +1 -2
  374. package/frontend-vue/layers/dms-layout/app/build/utils/github-repository.ts +5 -0
  375. package/frontend-vue/layers/dms-layout/app/components/layout/DashboardSearch.vue +109 -7
  376. package/frontend-vue/layers/dms-layout/app/components/navigation/NavigationMenu.vue +19 -9
  377. package/frontend-vue/layers/dms-layout/app/composables/notification/useNotifications.ts +22 -40
  378. package/frontend-vue/layers/dms-layout/app/composables/useAppSidePanels.ts +96 -0
  379. package/frontend-vue/layers/dms-layout/app/composables/useCommandPaletteAssistant.ts +129 -0
  380. package/frontend-vue/layers/dms-layout/app/composables/useHeaderActions.ts +33 -11
  381. package/frontend-vue/layers/dms-layout/app/composables/useSidePanel.ts +41 -0
  382. package/frontend-vue/layers/dms-layout/app/pages/[...slug].vue +15 -0
  383. package/frontend-vue/layers/dms-layout/app/plugins/notification-stream.client.ts +1 -7
  384. package/frontend-vue/layers/dms-layout/app/plugins/side-panel-host.ts +13 -0
  385. package/frontend-vue/layers/dms-layout/app/types/page.ts +4 -0
  386. package/frontend-vue/layers/dms-layout/i18n/locales/layout-en-GB.json +43 -13
  387. package/frontend-vue/layers/dms-layout/i18n/locales/layout-fr-FR.json +43 -13
  388. package/frontend-vue/layers/dms-ui/app/build/components/form/FormLoadError.vue +45 -0
  389. package/frontend-vue/layers/dms-ui/app/build/components/modal/ModalEscHint.vue +28 -0
  390. package/frontend-vue/layers/dms-ui/app/build/composables/form/floatingSaveBars.ts +38 -0
  391. package/frontend-vue/layers/dms-ui/app/build/composables/form/formRecordLoad.ts +66 -0
  392. package/frontend-vue/layers/dms-ui/app/build/composables/navigation/useNavBadges.ts +50 -9
  393. package/frontend-vue/layers/dms-ui/app/build/composables/table/useTable.ts +7 -1
  394. package/frontend-vue/layers/dms-ui/app/build/composables/table-view/utils/chrome.ts +2 -2
  395. package/frontend-vue/layers/dms-ui/app/build/types/tree.ts +14 -10
  396. package/frontend-vue/layers/dms-ui/app/build/utils/navBadge.ts +12 -0
  397. package/frontend-vue/layers/dms-ui/app/build/utils/tone.ts +22 -0
  398. package/frontend-vue/layers/dms-ui/app/components/activity-feed/ActivityFeed.vue +117 -82
  399. package/frontend-vue/layers/dms-ui/app/components/blocks/NavCardGridBlock.vue +12 -1
  400. package/frontend-vue/layers/dms-ui/app/components/card/NavCard.vue +16 -1
  401. package/frontend-vue/layers/dms-ui/app/components/confirm/ConfirmModal.vue +7 -8
  402. package/frontend-vue/layers/dms-ui/app/components/form/Form.vue +28 -6
  403. package/frontend-vue/layers/dms-ui/app/components/form/components/Display.vue +5 -1
  404. package/frontend-vue/layers/dms-ui/app/components/save-bar/SaveBar.vue +4 -0
  405. package/frontend-vue/layers/dms-ui/app/components/status-pill/StatusPill.vue +7 -2
  406. package/frontend-vue/layers/dms-ui/app/components/table-view/TableView.vue +7 -2
  407. package/frontend-vue/layers/dms-ui/app/composables/form/useForm.ts +48 -34
  408. package/frontend-vue/layers/dms-ui/app/composables/table-view/types/config.ts +13 -3
  409. package/frontend-vue/layers/dms-ui/i18n/locales/ui-en-GB.json +16 -14
  410. package/frontend-vue/layers/dms-ui/i18n/locales/ui-fr-FR.json +16 -14
  411. package/frontend-vue/package.json +2 -2
  412. package/frontend-vue/pnpm-lock.yaml +5 -5
  413. package/frontend-vue/tests/activity-feed-fill-height.test.ts +107 -0
  414. package/frontend-vue/tests/category-nav-cards.test.ts +21 -13
  415. package/frontend-vue/tests/command-palette-assistant.test.ts +344 -0
  416. package/frontend-vue/tests/fixtures/dashboard-search-stub.ts +91 -0
  417. package/frontend-vue/tests/forgot-validation-resend.test.ts +234 -0
  418. package/frontend-vue/tests/form-display-options.test.ts +64 -0
  419. package/frontend-vue/tests/form-load-error.test.ts +160 -0
  420. package/frontend-vue/tests/form-saved-before-success.test.ts +110 -0
  421. package/frontend-vue/tests/github-star-prompt.test.ts +328 -0
  422. package/frontend-vue/tests/header-actions.test.ts +191 -0
  423. package/frontend-vue/tests/invites-edit-modal.test.ts +157 -0
  424. package/frontend-vue/tests/member-role-picker.test.ts +26 -0
  425. package/frontend-vue/tests/menu-hidden-page.test.ts +93 -0
  426. package/frontend-vue/tests/nav-badge-tones.test.ts +274 -0
  427. package/frontend-vue/tests/nav-card-badge.test.ts +69 -0
  428. package/frontend-vue/tests/nav-card-grid-empty-category.test.ts +163 -0
  429. package/frontend-vue/tests/notification-popover-errors.test.ts +71 -37
  430. package/frontend-vue/tests/notification-preferences-groups.test.ts +268 -0
  431. package/frontend-vue/tests/notification-tone-contract.test.ts +70 -0
  432. package/frontend-vue/tests/page-fill-height.test.ts +9 -1
  433. package/frontend-vue/tests/page-no-visible-blocks.test.ts +202 -0
  434. package/frontend-vue/tests/profile-preferences-summary.test.ts +26 -2
  435. package/frontend-vue/tests/profile-security-summary.test.ts +121 -0
  436. package/frontend-vue/tests/role-permission-tree.test.ts +102 -8
  437. package/frontend-vue/tests/role-permissions.test.ts +178 -56
  438. package/frontend-vue/tests/side-panels.test.ts +470 -0
  439. package/frontend-vue/tests/signup-invitation-link.test.ts +71 -2
  440. package/frontend-vue/tests/table-actions-column-width.test.ts +51 -1
  441. package/frontend-vue/tests/table-view-chrome.test.ts +2 -2
  442. package/frontend-vue/tests/vue-inventory.test.ts +1 -1
  443. package/package.json +1 -1
  444. package/skills/dms/REFERENCE.md +1 -1
@@ -0,0 +1 @@
1
+ export declare function firstIssueMessage(error: unknown): string;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.firstIssueMessage = firstIssueMessage;
4
+ const zod_1 = require("zod");
5
+ function firstIssueMessage(error) {
6
+ const [issue] = error instanceof zod_1.ZodError ? error.issues : [];
7
+ return issue ? issue.message : String(error);
8
+ }
9
+ //# sourceMappingURL=issue-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-message.js","sourceRoot":"","sources":["../../src/validation/issue-message.ts"],"names":[],"mappings":";;AAOA,8CAGC;AAVD,6BAA+B;AAO/B,SAAgB,iBAAiB,CAAC,KAAc;IAC9C,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,YAAY,cAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC"}
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  export declare const INVITE_NAME_MAX_LENGTH = 100;
3
3
  export declare const INVITE_FULL_NAME_MAX_LENGTH: number;
4
4
  export declare const INVITE_EMAILS_MAX = 50;
5
- export declare const memberInviteSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodObject<{
5
+ export declare const memberInviteSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
6
6
  emails: z.ZodArray<z.ZodString, "many">;
7
7
  name: z.ZodOptional<z.ZodString>;
8
8
  firstname: z.ZodOptional<z.ZodString>;
@@ -10,11 +10,9 @@ export declare const memberInviteSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<
10
10
  roles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
11
11
  language: z.ZodString;
12
12
  asTenantOwner: z.ZodBoolean;
13
- skipEmailValidation: z.ZodDefault<z.ZodBoolean>;
14
13
  }, "strip", z.ZodTypeAny, {
15
14
  language: string;
16
15
  asTenantOwner: boolean;
17
- skipEmailValidation: boolean;
18
16
  emails: string[];
19
17
  name?: string | undefined;
20
18
  roles?: string[] | undefined;
@@ -28,11 +26,9 @@ export declare const memberInviteSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<
28
26
  roles?: string[] | undefined;
29
27
  firstname?: string | undefined;
30
28
  lastname?: string | undefined;
31
- skipEmailValidation?: boolean | undefined;
32
29
  }>, {
33
30
  language: string;
34
31
  asTenantOwner: boolean;
35
- skipEmailValidation: boolean;
36
32
  emails: string[];
37
33
  name?: string | undefined;
38
34
  roles?: string[] | undefined;
@@ -46,29 +42,9 @@ export declare const memberInviteSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<
46
42
  roles?: string[] | undefined;
47
43
  firstname?: string | undefined;
48
44
  lastname?: string | undefined;
49
- skipEmailValidation?: boolean | undefined;
50
45
  }>, {
51
46
  language: string;
52
47
  asTenantOwner: boolean;
53
- skipEmailValidation: boolean;
54
- emails: string[];
55
- name?: string | undefined;
56
- roles?: string[] | undefined;
57
- firstname?: string | undefined;
58
- lastname?: string | undefined;
59
- }, {
60
- language: string;
61
- asTenantOwner: boolean;
62
- emails: string[];
63
- name?: string | undefined;
64
- roles?: string[] | undefined;
65
- firstname?: string | undefined;
66
- lastname?: string | undefined;
67
- skipEmailValidation?: boolean | undefined;
68
- }>, {
69
- language: string;
70
- asTenantOwner: boolean;
71
- skipEmailValidation: boolean;
72
48
  emails: string[];
73
49
  name?: string | undefined;
74
50
  roles?: string[] | undefined;
@@ -33,32 +33,11 @@ const memberInviteObjectSchema = zod_1.z.object({
33
33
  roles: zod_1.z.array(zod_1.z.string()).optional(),
34
34
  language: zod_1.z.string(),
35
35
  asTenantOwner: zod_1.z.boolean(),
36
- skipEmailValidation: zod_1.z.boolean().default(false),
37
36
  });
38
- function addIssue(ctx, path, message) {
39
- ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message, path: [path] });
40
- }
41
- function requireNamesWhenValidationSkipped(data, ctx) {
42
- if (!data.skipEmailValidation)
43
- return;
44
- if (data.emails.length > 1) {
45
- addIssue(ctx, EMAILS_KEY, "$page.settings.members.invite.skip_validation_single_email");
46
- }
47
- if (data.name)
48
- return;
49
- if (!data.firstname) {
50
- addIssue(ctx, "firstname", "$page.settings.members.invite.firstname_required");
51
- }
52
- if (!data.lastname) {
53
- addIssue(ctx, "lastname", "$page.settings.members.invite.lastname_required");
54
- }
55
- }
56
- exports.memberInviteSchema = zod_1.z.preprocess(acceptLegacySingleEmail, memberInviteObjectSchema
57
- .refine((data) => data.asTenantOwner || (data.roles && data.roles.length > 0), {
37
+ exports.memberInviteSchema = zod_1.z.preprocess(acceptLegacySingleEmail, memberInviteObjectSchema.refine((data) => data.asTenantOwner || (data.roles && data.roles.length > 0), {
58
38
  message: "$page.settings.members.invite.roles_required",
59
39
  path: ["roles"],
60
- })
61
- .superRefine(requireNamesWhenValidationSkipped));
40
+ }));
62
41
  function resolveInviteeNameParts(payload) {
63
42
  if (payload.firstname || payload.lastname || !payload.name) {
64
43
  return { firstname: payload.firstname, lastname: payload.lastname };
@@ -1 +1 @@
1
- {"version":3,"file":"member-invite.schema.js","sourceRoot":"","sources":["../../src/validation/member-invite.schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"member-invite.schema.js","sourceRoot":"","sources":["../../src/validation/member-invite.schema.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ import fontPreloadPlugin from "./layers/dms-layout/app/plugins/font-preload";
17
17
  import permissionPreviewPrepaintPlugin from "./layers/dms-layout/app/plugins/permission-preview-prepaint";
18
18
  import regionalPreferencesPlugin from "./layers/dms-layout/app/plugins/regional-preferences";
19
19
  import seoPlugin from "./layers/dms-layout/app/plugins/seo";
20
+ import sidePanelHostPlugin from "./layers/dms-layout/app/plugins/side-panel-host";
20
21
  import onboardingMiddleware from "./layers/dms-onboarding/app/middleware/onboarding.global";
21
22
  import registerPlugin from "./layers/dms-ui/app/plugins/register";
22
23
  import shortcutsPlugin from "./layers/dms-ui/app/plugins/shortcuts";
@@ -170,6 +171,7 @@ function registerPlugins(sdk: Parameters<DmsFrontendModule["setup"]>[0]): void {
170
171
  sdk.registerPlugin(accessibilityPlugin);
171
172
  sdk.registerPlugin(regionalPreferencesPlugin);
172
173
  sdk.registerPlugin(seoPlugin);
174
+ sdk.registerPlugin(sidePanelHostPlugin);
173
175
  sdk.registerPlugin(registerPlugin);
174
176
  sdk.registerPlugin(shortcutsPlugin);
175
177
  sdk.registerPlugin(tableViewDisplaysPlugin);
@@ -124,6 +124,9 @@ async function requestForgotPassword() {
124
124
  });
125
125
 
126
126
  startCooldown();
127
+ // The refusal was about the previous code: the new one starts clean.
128
+ clearFormError();
129
+ codeError.value = undefined;
127
130
 
128
131
  toast.add({
129
132
  title: t("page.validate.request_sended"),
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { useTemplateRef } from "vue";
2
+ import { onMounted, useTemplateRef } from "vue";
3
3
  import * as z from "zod";
4
4
  import type { FormSubmitEvent } from "@nuxt/ui";
5
5
  import StageCard from "../../../../dms-layout/app/build/components/layout/StageCard.vue";
@@ -15,14 +15,70 @@ import {
15
15
  useLiveFormErrors,
16
16
  useLocalizedSchema,
17
17
  } from "#dms-core/app/composables/useFormValidation";
18
+ import { resolveApiErrorMessage } from "#dms-core/app/composables/useApiError";
18
19
 
19
20
  const MIN_NAME_LENGTH = 2;
20
21
 
22
+ /** Why an invitation link cannot open the signup form. */
23
+ type ClosedInvitation = "invalid" | "expired" | "revoked" | "replaced" | "used";
24
+ type InvitationState = "checking" | "open" | ClosedInvitation;
25
+
26
+ interface ClosedInvitationNotice {
27
+ icon: string;
28
+ title: string;
29
+ description: string;
30
+ }
31
+
32
+ // The refusals the server gives a link it would not sign up with.
33
+ const CLOSED_INVITATION_CODES: Record<string, ClosedInvitation> = {
34
+ "error.invalid_token": "invalid",
35
+ "error.invite_expired": "expired",
36
+ "error.invite_revoked": "revoked",
37
+ "error.invite_replaced": "replaced",
38
+ "error.invite_used": "used",
39
+ };
40
+
41
+ const CLOSED_INVITATION_NOTICES: Record<
42
+ ClosedInvitation,
43
+ ClosedInvitationNotice
44
+ > = {
45
+ invalid: {
46
+ icon: "i-ph-link-break",
47
+ title: "page.signup.invalid_invitation_title",
48
+ description: "page.signup.invalid_invitation_description",
49
+ },
50
+ expired: {
51
+ icon: "i-ph-hourglass",
52
+ title: "page.signup.invitation_expired_title",
53
+ description: "page.signup.invitation_expired_description",
54
+ },
55
+ revoked: {
56
+ icon: "i-ph-prohibit",
57
+ title: "page.signup.invitation_revoked_title",
58
+ description: "page.signup.invitation_revoked_description",
59
+ },
60
+ replaced: {
61
+ icon: "i-ph-envelope-simple",
62
+ title: "page.signup.invitation_replaced_title",
63
+ description: "page.signup.invitation_replaced_description",
64
+ },
65
+ used: {
66
+ icon: "i-ph-user-check",
67
+ title: "page.signup.invitation_used_title",
68
+ description: "page.signup.invitation_used_description",
69
+ },
70
+ };
71
+
72
+ function closedInvitationOf(error: unknown): ClosedInvitation | undefined {
73
+ return CLOSED_INVITATION_CODES[resolveApiErrorMessage(error)];
74
+ }
75
+
21
76
  const { locale, locales, setLocale } = useI18n();
22
77
  const config = useDmsRuntimeConfig();
23
78
  const homepage = useHomepage();
24
79
  const dmsApp = useDmsApp();
25
80
  const { formError, clearFormError, showError } = useAuthFormError();
81
+ const { $authFetch } = useAuthFetch();
26
82
  const form = useTemplateRef<AuthFormHandle>("form");
27
83
 
28
84
  const route = useDmsRoute();
@@ -35,6 +91,34 @@ const hasInvitationToken = computed(
35
91
  () => typeof queryToken.value === "string" && queryToken.value !== "",
36
92
  );
37
93
 
94
+ const invitationState = ref<InvitationState>(
95
+ hasInvitationToken.value ? "checking" : "invalid",
96
+ );
97
+ const closedInvitation = computed(() =>
98
+ invitationState.value in CLOSED_INVITATION_NOTICES
99
+ ? CLOSED_INVITATION_NOTICES[invitationState.value as ClosedInvitation]
100
+ : undefined,
101
+ );
102
+
103
+ // A revoked, replaced or expired link says so as the page opens, rather than
104
+ // after the whole form was filled. The server answers with the very check the
105
+ // signup runs; any other failure leaves the form to the signup to settle.
106
+ async function checkInvitation(): Promise<void> {
107
+ try {
108
+ await $authFetch("/api/auth/validate-invite-token", {
109
+ method: "POST",
110
+ body: { token: queryToken.value, email: queryEmail.value },
111
+ });
112
+ invitationState.value = "open";
113
+ } catch (error: unknown) {
114
+ invitationState.value = closedInvitationOf(error) ?? "open";
115
+ }
116
+ }
117
+
118
+ onMounted(() => {
119
+ if (invitationState.value === "checking") void checkInvitation();
120
+ });
121
+
38
122
  // The invitation link carries the language the invitee was invited in: the
39
123
  // page opens in it, and the footer switcher still lets them pick another one
40
124
  // before the account is created with whichever is current.
@@ -80,6 +164,12 @@ async function onSubmit(payload: FormSubmitEvent<Schema>) {
80
164
  ),
81
165
  );
82
166
  } catch (error: unknown) {
167
+ // The invitation can be retired while the form is open.
168
+ const closed = closedInvitationOf(error);
169
+ if (closed) {
170
+ invitationState.value = closed;
171
+ return;
172
+ }
83
173
  // A refused value (an address already used) shows under its field;
84
174
  // anything else above the form.
85
175
  await showError(error, "page.signup.error_title", {
@@ -95,11 +185,11 @@ async function onSubmit(payload: FormSubmitEvent<Schema>) {
95
185
 
96
186
  <template>
97
187
  <StageCard
98
- v-if="!hasInvitationToken"
99
- icon="i-ph-link-break"
188
+ v-if="closedInvitation"
189
+ :icon="closedInvitation.icon"
100
190
  tone="warning"
101
- :title="$t('page.signup.invalid_invitation_title')"
102
- :description="$t('page.signup.invalid_invitation_description')"
191
+ :title="$t(closedInvitation.title)"
192
+ :description="$t(closedInvitation.description)"
103
193
  data-testid="signup-invalid-invitation"
104
194
  >
105
195
  <UButton
@@ -111,6 +201,16 @@ async function onSubmit(payload: FormSubmitEvent<Schema>) {
111
201
  />
112
202
  </StageCard>
113
203
 
204
+ <StageCard
205
+ v-else-if="invitationState === 'checking'"
206
+ icon="i-ph-spinner"
207
+ icon-class="animate-spin"
208
+ tone="neutral"
209
+ :title="$t('page.signup.create_account_title')"
210
+ :description="$t('page.signup.checking_invitation')"
211
+ data-testid="signup-checking-invitation"
212
+ />
213
+
114
214
  <StageCard
115
215
  v-else
116
216
  :title="$t('page.signup.create_account_title')"
@@ -27,6 +27,15 @@
27
27
  "error_title": "Account creation error",
28
28
  "invalid_invitation_title": "This invitation link is invalid or incomplete",
29
29
  "invalid_invitation_description": "Open the link from your invitation email again, or ask the workspace owner to send you a new invitation. Already have an account? Log in.",
30
+ "checking_invitation": "Checking your invitation…",
31
+ "invitation_expired_title": "This invitation has expired",
32
+ "invitation_expired_description": "Ask the person who invited you to send you a new invitation. Already have an account? Log in.",
33
+ "invitation_revoked_title": "This invitation was revoked",
34
+ "invitation_revoked_description": "The person who invited you cancelled it. If you still need access, ask them for a new invitation.",
35
+ "invitation_replaced_title": "This invitation was replaced by a newer email",
36
+ "invitation_replaced_description": "A newer invitation was sent to this address, and only its link works. Open the latest invitation email, or ask the person who invited you to send it again.",
37
+ "invitation_used_title": "This invitation was already used",
38
+ "invitation_used_description": "An account was already created with this invitation. Log in to continue.",
30
39
  "description": "You've been invited. Choose your name and a password to join.",
31
40
  "submit": "Create my account"
32
41
  },
@@ -55,8 +64,8 @@
55
64
  "title_success": "Password changed",
56
65
  "title_forget": "Forgot password",
57
66
  "description_success": "Your password has been reset. Sign in with your new password.",
58
- "description_validation": "We sent a 6-digit code to {email}. Enter it to choose a new password.",
59
- "description_forget": "Enter the e-mail address of your account. We'll send you a 6-digit code to reset your password.",
67
+ "description_validation": "We sent a 6-character code to {email}. Enter it to choose a new password.",
68
+ "description_forget": "Enter the e-mail address of your account. We'll send you a 6-character code to reset your password.",
60
69
  "error_title": "Reset error",
61
70
  "title_inbox": "Check your inbox",
62
71
  "send_code": "Send the code",
@@ -368,7 +377,8 @@
368
377
  "add_method": "Add method",
369
378
  "add_named": "Add {method}",
370
379
  "password_prompt": "Confirm your password to add a sign-in method.",
371
- "password_continue": "Continue"
380
+ "password_continue": "Continue",
381
+ "email_setup_description": "We sent a 6-digit code to {email}. Enter it to turn on email codes."
372
382
  },
373
383
  "backup": {
374
384
  "title": "Backup codes",
@@ -415,6 +425,7 @@
415
425
  "email_already_used": "This email address is already used by another account.",
416
426
  "invalid_2fa_code": "That verification code is invalid or has expired.",
417
427
  "rate_limited": "Please wait a minute before asking for another code.",
428
+ "email_change_too_many_attempts": "Too many wrong codes. Ask for a new one.",
418
429
  "no_backup_codes": "You have no backup codes.",
419
430
  "session_not_found": "This session no longer exists."
420
431
  }
@@ -442,6 +453,11 @@
442
453
  "identity_malformed": "The provider returned an unusable identity, please try again."
443
454
  },
444
455
  "rate_limited": "Too many attempts, please try again in a minute.",
445
- "too_many_sign_in_attempts": "Too many sign-in attempts. Please try again in a few minutes."
456
+ "too_many_sign_in_attempts": "Too many sign-in attempts. Please try again in a few minutes.",
457
+ "too_many_2fa_attempts": "Too many wrong codes. Go back and sign in again with your password.",
458
+ "too_many_2fa_attempts_account": "Too many wrong codes on this account. Wait up to an hour, then sign in again.",
459
+ "2fa_challenge_used": "This verification is already complete. Sign in again with your password.",
460
+ "invalid_2fa_token": "This verification has expired or is invalid. Sign in again with your password.",
461
+ "too_many_current_password_attempts": "Too many wrong passwords. Wait 15 minutes, then try again."
446
462
  }
447
463
  }
@@ -27,6 +27,15 @@
27
27
  "error_title": "Erreur de création de compte",
28
28
  "invalid_invitation_title": "Ce lien d'invitation est invalide ou incomplet",
29
29
  "invalid_invitation_description": "Rouvrez le lien de votre e-mail d'invitation, ou demandez au propriétaire de l'espace de travail de vous envoyer une nouvelle invitation. Vous avez déjà un compte ? Connectez-vous.",
30
+ "checking_invitation": "Vérification de votre invitation…",
31
+ "invitation_expired_title": "Cette invitation a expiré",
32
+ "invitation_expired_description": "Demandez à la personne qui vous a invité de vous envoyer une nouvelle invitation. Vous avez déjà un compte ? Connectez-vous.",
33
+ "invitation_revoked_title": "Cette invitation a été révoquée",
34
+ "invitation_revoked_description": "La personne qui vous a invité l'a annulée. Si vous avez toujours besoin d'un accès, demandez-lui une nouvelle invitation.",
35
+ "invitation_replaced_title": "Cette invitation a été remplacée par un e-mail plus récent",
36
+ "invitation_replaced_description": "Une invitation plus récente a été envoyée à cette adresse, et seul son lien fonctionne. Ouvrez le dernier e-mail d'invitation, ou demandez à la personne qui vous a invité de vous le renvoyer.",
37
+ "invitation_used_title": "Cette invitation a déjà été utilisée",
38
+ "invitation_used_description": "Un compte a déjà été créé avec cette invitation. Connectez-vous pour continuer.",
30
39
  "description": "Vous avez été invité. Choisissez votre nom et un mot de passe pour nous rejoindre.",
31
40
  "submit": "Créer mon compte"
32
41
  },
@@ -55,8 +64,8 @@
55
64
  "title_success": "Mot de passe modifié",
56
65
  "title_forget": "Mot de passe oublié",
57
66
  "description_success": "Votre mot de passe a été réinitialisé. Connectez-vous avec votre nouveau mot de passe.",
58
- "description_validation": "Nous avons envoyé un code à 6 chiffres à {email}. Saisissez-le pour choisir un nouveau mot de passe.",
59
- "description_forget": "Saisissez l'adresse e-mail de votre compte. Nous vous enverrons un code à 6 chiffres pour réinitialiser votre mot de passe.",
67
+ "description_validation": "Nous avons envoyé un code à 6 caractères à {email}. Saisissez-le pour choisir un nouveau mot de passe.",
68
+ "description_forget": "Saisissez l'adresse e-mail de votre compte. Nous vous enverrons un code à 6 caractères pour réinitialiser votre mot de passe.",
60
69
  "error_title": "Erreur de réinitialisation",
61
70
  "title_inbox": "Consultez votre boîte mail",
62
71
  "send_code": "Envoyer le code",
@@ -368,7 +377,8 @@
368
377
  "add_method": "Ajouter une méthode",
369
378
  "add_named": "Ajouter « {method} »",
370
379
  "password_prompt": "Confirmez votre mot de passe pour ajouter une méthode de connexion.",
371
- "password_continue": "Continuer"
380
+ "password_continue": "Continuer",
381
+ "email_setup_description": "Nous avons envoyé un code à 6 chiffres à {email}. Saisissez-le pour activer les codes par e-mail."
372
382
  },
373
383
  "backup": {
374
384
  "title": "Codes de secours",
@@ -415,6 +425,7 @@
415
425
  "email_already_used": "Cette adresse e-mail est déjà utilisée par un autre compte.",
416
426
  "invalid_2fa_code": "Ce code de vérification est invalide ou a expiré.",
417
427
  "rate_limited": "Patientez une minute avant de demander un autre code.",
428
+ "email_change_too_many_attempts": "Trop de codes erronés. Demandez-en un nouveau.",
418
429
  "no_backup_codes": "Vous n'avez aucun code de secours.",
419
430
  "session_not_found": "Cette session n'existe plus."
420
431
  }
@@ -442,6 +453,11 @@
442
453
  "identity_malformed": "Le fournisseur a renvoyé une identité inexploitable, réessayez."
443
454
  },
444
455
  "rate_limited": "Trop de tentatives, réessayez dans une minute.",
445
- "too_many_sign_in_attempts": "Trop de tentatives de connexion. Réessayez dans quelques minutes."
456
+ "too_many_sign_in_attempts": "Trop de tentatives de connexion. Réessayez dans quelques minutes.",
457
+ "too_many_2fa_attempts": "Trop de codes erronés. Revenez en arrière et reconnectez-vous avec votre mot de passe.",
458
+ "too_many_2fa_attempts_account": "Trop de codes erronés sur ce compte. Patientez jusqu'à une heure, puis reconnectez-vous.",
459
+ "2fa_challenge_used": "Cette vérification est déjà validée. Reconnectez-vous avec votre mot de passe.",
460
+ "invalid_2fa_token": "Cette vérification a expiré ou n'est pas valide. Reconnectez-vous avec votre mot de passe.",
461
+ "too_many_current_password_attempts": "Trop de mots de passe erronés. Patientez 15 minutes, puis réessayez."
446
462
  }
447
463
  }
@@ -126,7 +126,8 @@ const FIELD_PREFIXED_MESSAGE = /^([\w.]+):\s+(.+)$/s;
126
126
  const BARE_I18N_KEY = /^[a-z0-9_]+(\.[a-z0-9_]+)+$/i;
127
127
  const LIST_SEPARATOR = /\s*,\s*/;
128
128
 
129
- function statusOf(error: unknown): number | undefined {
129
+ /** The HTTP status of a fetch error; undefined for a network failure. */
130
+ export function apiErrorStatus(error: unknown): number | undefined {
130
131
  if (typeof error !== "object" || error === null) return undefined;
131
132
  const { statusCode, status, response } = error as FetchErrorLike;
132
133
  return statusCode ?? status ?? response?.status;
@@ -321,7 +322,7 @@ export function resolveFieldErrors<F extends string>(
321
322
  error: unknown,
322
323
  options: ResolveFieldErrorsOptions<F>,
323
324
  ): FieldErrorResolution {
324
- const status = statusOf(error);
325
+ const status = apiErrorStatus(error);
325
326
  if (!isClientError(status)) return { fields: [], hasUnmatched: true };
326
327
  const body = bodyOf(error);
327
328
  const mapped = lookupCode(codeOf(body), options.codes);
@@ -6,6 +6,19 @@ export type MenuItemVariant = "default" | "accent";
6
6
  /** Semantic state dot of a menu entry, mirroring `MenuItemStatus` in the backend. */
7
7
  export type MenuItemStatus = "success" | "warning" | "error" | "neutral";
8
8
 
9
+ /**
10
+ * Tone of a counted menu badge, mirroring `Tone` in the backend: the server
11
+ * serves it as `badgeTone` next to `badge`; neutral when absent.
12
+ */
13
+ export type MenuItemBadgeTone =
14
+ | "neutral"
15
+ | "primary"
16
+ | "secondary"
17
+ | "success"
18
+ | "warning"
19
+ | "error"
20
+ | "info";
21
+
9
22
  /** Query parameters carried by a menu entry's link. */
10
23
  export type MenuItemQuery = Record<string, string>;
11
24
 
@@ -27,6 +40,8 @@ export interface DmsMenuItem extends NavigationMenuItem {
27
40
  fullId?: string;
28
41
  variant?: MenuItemVariant;
29
42
  status?: MenuItemStatus;
43
+ /** The tone of the entry's counted `badge`. */
44
+ badgeTone?: MenuItemBadgeTone;
30
45
  /**
31
46
  * Set by "Preview as role" only, on an entry the previewed role could not
32
47
  * open: the menu draws it hatched and locked. Never set outside a preview.
@@ -56,8 +56,11 @@
56
56
  "email_already_requested": "This email address has already been requested. Please wait before trying again.",
57
57
  "email_validation_disabled": "Email validation is disabled on this instance.",
58
58
  "invalid_token": "The validation code is invalid.",
59
- "invalid_or_expired_token": "This link is invalid or has expired. Please request a new one.",
59
+ "invalid_or_expired_token": "This code is invalid or has expired. Please request a new one.",
60
60
  "invite_expired": "This invitation has expired. Please request a new one.",
61
+ "invite_revoked": "This invitation was revoked. Please request a new one.",
62
+ "invite_replaced": "This invitation was replaced by a newer email. Please open the latest one.",
63
+ "invite_used": "This invitation was already used. Please log in.",
61
64
  "onboarding_already_completed": "Onboarding already completed.",
62
65
  "admin_already_set": "An administrator account already exists.",
63
66
  "user_creation_failed": "The user account could not be created. Please try again.",
@@ -56,8 +56,11 @@
56
56
  "email_already_validated": "Cette adresse e-mail a déjà été validée.",
57
57
  "email_validation_disabled": "La validation par e-mail est désactivée sur cette instance.",
58
58
  "invalid_token": "Le code de validation est invalide.",
59
- "invalid_or_expired_token": "Ce lien est invalide ou a expiré. Veuillez en demander un nouveau.",
59
+ "invalid_or_expired_token": "Ce code est invalide ou a expiré. Veuillez en demander un nouveau.",
60
60
  "invite_expired": "Cette invitation a expiré. Veuillez en demander une nouvelle.",
61
+ "invite_revoked": "Cette invitation a été révoquée. Veuillez en demander une nouvelle.",
62
+ "invite_replaced": "Cette invitation a été remplacée par un e-mail plus récent. Veuillez ouvrir le plus récent.",
63
+ "invite_used": "Cette invitation a déjà été utilisée. Veuillez vous connecter.",
61
64
  "onboarding_already_completed": "L'onboarding a déjà été completé.",
62
65
  "admin_already_set": "Un compte administrateur existe déjà.",
63
66
  "user_creation_failed": "Le compte utilisateur n'a pas pu être créé. Veuillez réessayer.",
@@ -196,6 +196,13 @@
196
196
  --dms-shadow-cmdk:
197
197
  0 1px 2px rgb(11 17 20 / 0.06), 0 30px 80px rgb(11 17 20 / 0.18);
198
198
  --dms-halo-accent: 0 0 0 6px rgb(27 162 175 / 0.12);
199
+ /* Assistant mode swaps the accent halo for a violet (secondary) one,
200
+ and tints its surfaces and lines with the same violet. Plain rgb():
201
+ Chromium fringes the anti-aliased edge of an oklab colour-mix border
202
+ with its complementary yellow. */
203
+ --dms-assistant-halo: 0 0 0 6px rgb(124 58 237 / 0.1);
204
+ --dms-assistant-tint: rgb(124 58 237 / 0.08);
205
+ --dms-assistant-line: rgb(124 58 237 / 0.3);
199
206
  /* Base surfaces (v2 --shadow-card/-pop/-modal, --overlay, --glow-accent):
200
207
  cards, floating panels (menus, popovers, toasts), modals and drawers,
201
208
  their backdrop, and the ring of a selected card. */
@@ -313,6 +320,9 @@
313
320
  --dms-shadow-cmdk:
314
321
  0 50px 140px rgb(0 0 0 / 0.7), inset 0 1px 0 rgb(255 255 255 / 0.04);
315
322
  --dms-halo-accent: 0 0 0 8px rgb(77 217 230 / 0.07);
323
+ --dms-assistant-halo: 0 0 0 8px rgb(167 139 250 / 0.09);
324
+ --dms-assistant-tint: rgb(167 139 250 / 0.12);
325
+ --dms-assistant-line: rgb(167 139 250 / 0.4);
316
326
  --dms-shadow-card: inset 0 1px 0 rgb(255 255 255 / 0.03);
317
327
  --dms-shadow-pop: 0 16px 40px rgb(0 0 0 / 0.55), 0 0 0 1px rgb(0 0 0 / 0.2);
318
328
  --dms-shadow-modal:
@@ -540,6 +550,16 @@
540
550
  }
541
551
  }
542
552
 
553
+ /* The violet sweep across the command palette's assistant skeleton. */
554
+ @keyframes dms-assistant-sweep {
555
+ from {
556
+ transform: translateX(-120%);
557
+ }
558
+ to {
559
+ transform: translateX(120%);
560
+ }
561
+ }
562
+
543
563
  @keyframes dms-fresh-in {
544
564
  from {
545
565
  opacity: 0;
@@ -0,0 +1,75 @@
1
+ <script setup lang="ts">
2
+ import { computed, onErrorCaptured, ref } from "vue";
3
+ import { EYEBROW_CLASS } from "#dms-ui/app/build/utils/eyebrow";
4
+
5
+ interface CommandPaletteAssistantAnswerFrameProps {
6
+ /** The assistant's resolved label, shown as the frame's eyebrow. */
7
+ label: string;
8
+ icon: string;
9
+ /** Registered name of the module's answer component. */
10
+ component: string;
11
+ prompt: string;
12
+ close: () => void;
13
+ }
14
+
15
+ const props = defineProps<CommandPaletteAssistantAnswerFrameProps>();
16
+ const { t } = useI18n();
17
+
18
+ const answerComponent = computed(() => resolveDmsComponent(props.component));
19
+ const isLoading = ref(true);
20
+ const hasFailed = ref(false);
21
+ const eyebrowClass = [
22
+ EYEBROW_CLASS,
23
+ "mb-2 flex items-center gap-1.5 text-secondary",
24
+ ];
25
+ // Line widths of the loading skeleton, after the v2 mockup.
26
+ const SKELETON_WIDTHS = ["w-[82%]", "w-[64%]", "w-[40%]"];
27
+
28
+ // A rejected async setup would leave the skeleton up for good: the frame
29
+ // states the failure instead, and the other palette content keeps working.
30
+ onErrorCaptured((error) => {
31
+ console.error("[command-palette] the assistant answer failed", error);
32
+ hasFailed.value = true;
33
+ isLoading.value = false;
34
+ return false;
35
+ });
36
+ </script>
37
+
38
+ <template>
39
+ <section
40
+ class="text-toned m-1.5 rounded-xl border border-(--dms-assistant-line) bg-(--dms-assistant-tint) px-4 py-3.5 text-left text-sm/relaxed"
41
+ :aria-label="props.label"
42
+ :aria-busy="isLoading"
43
+ data-slot="assistantAnswer"
44
+ >
45
+ <p :class="eyebrowClass">
46
+ <UIcon :name="props.icon" class="size-3.5" />
47
+ {{ props.label }}
48
+ </p>
49
+ <p v-if="hasFailed || !answerComponent" role="alert" class="text-muted">
50
+ {{ t("commandPalette.assistant.failed") }}
51
+ </p>
52
+ <Suspense v-else @pending="isLoading = true" @resolve="isLoading = false">
53
+ <component
54
+ :is="answerComponent"
55
+ :prompt="props.prompt"
56
+ :close="props.close"
57
+ />
58
+ <template #fallback>
59
+ <div
60
+ role="status"
61
+ class="after:via-secondary/25 relative grid gap-2.5 overflow-hidden py-1.5 after:absolute after:inset-0 after:bg-linear-100 after:from-transparent after:from-30% after:to-transparent after:to-70% motion-safe:after:animate-[dms-assistant-sweep_1.6s_ease-out_infinite]"
62
+ >
63
+ <span class="sr-only">
64
+ {{ t("commandPalette.assistant.loading") }}
65
+ </span>
66
+ <USkeleton
67
+ v-for="width in SKELETON_WIDTHS"
68
+ :key="width"
69
+ :class="['h-3 bg-(--dms-assistant-tint)', width]"
70
+ />
71
+ </div>
72
+ </template>
73
+ </Suspense>
74
+ </section>
75
+ </template>