passbolt-styleguide 3.8.4 → 3.9.0-alpha2

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 (318) hide show
  1. package/build/css/help.min.css +3 -3
  2. package/build/css/public.min.css +3 -3
  3. package/build/css/themes/default/api_authentication.min.css +3 -3
  4. package/build/css/themes/default/api_cloud.min.css +3 -3
  5. package/build/css/themes/default/api_main.min.css +3 -3
  6. package/build/css/themes/default/api_reports.min.css +3 -3
  7. package/build/css/themes/default/api_webinstaller.min.css +3 -3
  8. package/build/css/themes/default/ext_app.min.css +3 -3
  9. package/build/css/themes/default/ext_authentication.min.css +3 -3
  10. package/build/css/themes/default/ext_external.min.css +2 -2
  11. package/build/css/themes/default/ext_in_form_cta.min.css +3 -3
  12. package/build/css/themes/default/ext_in_form_menu.min.css +3 -3
  13. package/build/css/themes/default/ext_quickaccess.min.css +3 -3
  14. package/build/css/themes/midgar/api_authentication.min.css +3 -3
  15. package/build/css/themes/midgar/api_main.min.css +3 -3
  16. package/build/css/themes/midgar/api_reports.min.css +3 -3
  17. package/build/css/themes/midgar/ext_app.min.css +3 -3
  18. package/build/css/themes/midgar/ext_authentication.min.css +3 -3
  19. package/build/css/themes/midgar/ext_in_form_cta.min.css +3 -3
  20. package/build/css/themes/midgar/ext_in_form_menu.min.css +3 -3
  21. package/build/css/themes/midgar/ext_quickaccess.min.css +3 -3
  22. package/build/css/themes/solarized_dark/api_authentication.min.css +1 -1
  23. package/build/css/themes/solarized_dark/api_main.min.css +1 -1
  24. package/build/css/themes/solarized_dark/api_reports.min.css +1 -1
  25. package/build/css/themes/solarized_dark/ext_app.min.css +1 -1
  26. package/build/css/themes/solarized_dark/ext_authentication.min.css +1 -1
  27. package/build/css/themes/solarized_dark/ext_in_form_cta.min.css +1 -1
  28. package/build/css/themes/solarized_dark/ext_in_form_menu.min.css +1 -1
  29. package/build/css/themes/solarized_dark/ext_quickaccess.min.css +1 -1
  30. package/build/css/themes/solarized_light/api_authentication.min.css +1 -1
  31. package/build/css/themes/solarized_light/api_main.min.css +1 -1
  32. package/build/css/themes/solarized_light/api_reports.min.css +1 -1
  33. package/build/css/themes/solarized_light/ext_app.min.css +1 -1
  34. package/build/css/themes/solarized_light/ext_authentication.min.css +1 -1
  35. package/build/css/themes/solarized_light/ext_in_form_cta.min.css +1 -1
  36. package/build/css/themes/solarized_light/ext_in_form_menu.min.css +1 -1
  37. package/build/css/themes/solarized_light/ext_quickaccess.min.css +1 -1
  38. package/build/js/dist/api-account-recovery.js +1 -1
  39. package/build/js/dist/api-app.js +1 -1
  40. package/build/js/dist/api-app.js.LICENSE.txt +75 -5
  41. package/build/js/dist/api-feedback.js +2 -0
  42. package/build/js/dist/api-feedback.js.LICENSE.txt +45 -0
  43. package/build/js/dist/api-recover.js +1 -1
  44. package/build/js/dist/api-setup.js +1 -1
  45. package/build/js/dist/api-triage.js +1 -1
  46. package/build/js/dist/api-vendors.js +1 -1
  47. package/build/js/dist/api-vendors.js.LICENSE.txt +19 -9
  48. package/build/js/dist/src/locales/de-DE/common.json +995 -0
  49. package/build/js/dist/src/locales/en-UK/common.json +1061 -0
  50. package/build/js/dist/src/locales/es-ES/common.json +995 -0
  51. package/build/js/dist/src/locales/fr-FR/common.json +995 -0
  52. package/build/js/dist/src/locales/ja-JP/common.json +980 -0
  53. package/build/js/dist/src/locales/lt-LT/common.json +1025 -0
  54. package/build/js/dist/src/locales/nl-NL/common.json +995 -0
  55. package/build/js/dist/src/locales/pl-PL/common.json +1025 -0
  56. package/build/js/dist/src/locales/sv-SE/common.json +995 -0
  57. package/package.json +18 -1
  58. package/src/img/controls/attention.svg +1 -0
  59. package/src/locales/en-UK/common.json +80 -16
  60. package/src/react-extension/ApiApp.js +17 -5
  61. package/src/react-extension/ApiFeedback.entry.js +24 -0
  62. package/src/react-extension/ExtApp.js +12 -5
  63. package/src/react-extension/ExtAuthenticationLogin.js +17 -15
  64. package/src/react-extension/ExtAuthenticationLogin.test.stories.js +59 -0
  65. package/src/react-extension/ExtBootstrapApp.js +1 -0
  66. package/src/react-extension/components/Administration/AdministrationWorkspace.js +24 -0
  67. package/src/react-extension/components/Administration/AdministrationWorkspace.test.data.js +3 -3
  68. package/src/react-extension/components/Administration/AdministrationWorkspace.test.js +13 -1
  69. package/src/react-extension/components/Administration/AdministrationWorkspace.test.page.js +7 -0
  70. package/src/react-extension/components/Administration/ConfirmDeleteSsoSettingsDialog/ConfirmDeleteSsoSettingsDialog.js +101 -0
  71. package/src/react-extension/components/Administration/ConfirmDeleteSsoSettingsDialog/ConfirmDeleteSsoSettingsDialog.test.data.js +23 -0
  72. package/src/react-extension/components/Administration/ConfirmDeleteSsoSettingsDialog/ConfirmDeleteSsoSettingsDialog.test.stories.js +27 -0
  73. package/src/react-extension/components/Administration/ConfirmSaveAccountRecoverySettings/ConfirmSaveAccountRecoverySettings.js +1 -1
  74. package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.js +78 -2
  75. package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.test.data.js +3 -1
  76. package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.test.js +60 -0
  77. package/src/react-extension/components/Administration/DisplayAdministrationMenu/DisplayAdministrationMenu.test.page.js +23 -4
  78. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationInternationalisationActions/DisplayAdministrationInternationalisationActions.js +125 -0
  79. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationMfaActions/DisplayAdministrationMfaActions.js +131 -0
  80. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationSelfRegistrationActions/DisplayAdministrationSelfRegistrationActions.js +103 -0
  81. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationSsoActions/DisplayAdministrationSsoActions.js +91 -0
  82. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationSubscriptionActions/DisplayAdministrationSubscriptionActions.js +85 -0
  83. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationUserDirectoryActions/DisplayAdministrationUserDirectoryActions.js +228 -0
  84. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceBreadcrumb/DisplayAdministrationWorkspaceBreadcrumb.js +4 -0
  85. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceBreadcrumb/DisplayAdministrationWorkspaceBreadcrumb.test.js +9 -0
  86. package/src/react-extension/components/Administration/DisplayEmailNotificationsAdministration/DisplayEmailNotificationsAdministration.js +3 -3
  87. package/src/react-extension/components/Administration/DisplayEmailNotificationsAdministration/DisplayEmailNotificationsAdministration.test.data.js +14 -0
  88. package/src/react-extension/components/Administration/DisplayEmailNotificationsAdministration/DisplayEmailNotificationsAdministration.test.page.js +0 -17
  89. package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.js +18 -115
  90. package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.test.data.js +11 -13
  91. package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.test.js +38 -43
  92. package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.test.page.js +47 -10
  93. package/src/react-extension/components/Administration/DisplayInternationalizationAdministration/DisplayInternationalizationAdministration.test.stories.js +10 -43
  94. package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.js +82 -367
  95. package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.data.js +128 -42
  96. package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.js +75 -121
  97. package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.page.js +46 -16
  98. package/src/react-extension/components/Administration/DisplayMfaAdministration/DisplayMfaAdministration.test.stories.js +18 -14
  99. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmDeletionSelfRegistrationSettings/ConfirmDeletionSelfRegistrationSettings.js +103 -0
  100. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmDeletionSelfRegistrationSettings/ConfirmDeletionSelfRegistrationSettings.test.js +53 -0
  101. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmDeletionSelfRegistrationSettings/ConfirmDeletionSelfRegistrationSettings.test.page.js +81 -0
  102. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmDeletionSelfRegistrationSettings/ConfirmDeletionSelfRegistrationSettings.test.stories.js +34 -0
  103. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.js +125 -0
  104. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.test.data.js +63 -0
  105. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.test.js +54 -0
  106. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.test.page.js +88 -0
  107. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/ConfirmSaveSelfRegistrationSettings/ConfirmSaveSelfRegistrationSettings.test.stories.js +35 -0
  108. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.js +381 -0
  109. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.test.data.js +69 -0
  110. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.test.js +332 -0
  111. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.test.page.js +247 -0
  112. package/src/react-extension/components/Administration/DisplaySelfRegistrationAdministration/DisplaySelfRegistrationAdministration.test.stories.js +72 -0
  113. package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.js +19 -19
  114. package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.data.js +1717 -1729
  115. package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.js +11 -3
  116. package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.page.js +4 -1
  117. package/src/react-extension/components/Administration/DisplaySimulateSynchronizeUserDirectoryAdministration/DisplaySimulateSynchronizeUserDirectoryAdministration.test.stories.js +11 -1784
  118. package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.js +41 -140
  119. package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.data.js +15 -3
  120. package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.js +22 -49
  121. package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.page.js +19 -11
  122. package/src/react-extension/components/Administration/DisplaySubscriptionKey/DisplaySubscriptionKey.test.stories.js +9 -3
  123. package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.js +5 -6
  124. package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.data.js +1717 -1728
  125. package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.js +11 -3
  126. package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.page.js +4 -1
  127. package/src/react-extension/components/Administration/DisplaySynchronizeUserDirectoryAdministration/DisplaySynchronizeUserDirectoryAdministration.test.stories.js +11 -1784
  128. package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.js +362 -835
  129. package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.data.js +427 -418
  130. package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.js +134 -175
  131. package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.page.js +108 -11
  132. package/src/react-extension/components/Administration/DisplayUserDirectoryAdministration/DisplayUserDirectoryAdministration.test.stories.js +17 -25
  133. package/src/react-extension/components/Administration/EditSubscriptionKey/EditSubscriptionKey.js +4 -2
  134. package/src/react-extension/components/Administration/ManageAccountRecoveryAdministrationSettings/ManageAccountRecoveryAdministrationSettings.js +3 -3
  135. package/src/react-extension/components/Administration/ManageAccountRecoveryAdministrationSettings/ManageAccountRecoveryAdministrationSettings.test.js +1 -1
  136. package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.js +32 -7
  137. package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.test.data.js +0 -3
  138. package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.test.js +145 -1
  139. package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.test.page.js +52 -1
  140. package/src/react-extension/components/Administration/ManageSmtpAdministrationSettings/ManageSmtpAdministrationSettings.test.stories.js +15 -0
  141. package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.js +340 -0
  142. package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.test.data.js +56 -0
  143. package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.test.js +223 -0
  144. package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.test.page.js +235 -0
  145. package/src/react-extension/components/Administration/ManageSsoSettings/ManageSsoSettings.test.stories.js +55 -0
  146. package/src/react-extension/components/Administration/ManageSsoSettings/SsoProviders.data.js +34 -0
  147. package/src/react-extension/components/Administration/SelectAccountRecoveryOrganizationKey/GenerateOrganizationKey.js +12 -3
  148. package/src/react-extension/components/Administration/SelectAccountRecoveryOrganizationKey/GenerateOrganizationKey.test.js +27 -0
  149. package/src/react-extension/components/Administration/SelectAccountRecoveryOrganizationKey/SelectAccountRecoveryOrganizationKey.test.page.js +8 -0
  150. package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.js +197 -0
  151. package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.test.data.js +37 -0
  152. package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.test.js +187 -0
  153. package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.test.page.js +120 -0
  154. package/src/react-extension/components/Administration/TestSsoSettingsDialog/TestSsoSettingsDialog.test.stories.js +31 -0
  155. package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.js +9 -5
  156. package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.test.data.js +4 -0
  157. package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.test.js +11 -42
  158. package/src/react-extension/components/Authentication/CheckPassphrase/CheckPassphrase.test.page.js +1 -0
  159. package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.js +9 -5
  160. package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.test.data.js +4 -0
  161. package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.test.js +16 -2
  162. package/src/react-extension/components/Authentication/CreateGpgKey/CreateGpgKey.test.page.js +17 -1
  163. package/src/react-extension/components/AuthenticationLogin/Login/Login.js +159 -61
  164. package/src/react-extension/components/AuthenticationLogin/Login/Login.test.data.js +14 -11
  165. package/src/react-extension/components/AuthenticationLogin/Login/Login.test.js +79 -0
  166. package/src/react-extension/components/AuthenticationLogin/Login/Login.test.page.js +16 -0
  167. package/src/react-extension/components/AuthenticationLogin/OrchestrateLogin/OrchestrateLoginBoxMain.js +2 -0
  168. package/src/react-extension/components/AuthenticationSetup/SetupAuthentication/SetupAuthentication.js +4 -0
  169. package/src/react-extension/components/Common/Error/ApiError/ApiError.js +119 -0
  170. package/src/react-extension/components/Common/Error/ApiError/ApiError.test.js +43 -0
  171. package/src/react-extension/components/Common/Error/ApiError/ApiError.test.page.js +108 -0
  172. package/src/react-extension/components/Common/Error/ApiError/ApiError.test.stories.js +39 -0
  173. package/src/react-extension/components/Common/Inputs/Autocomplete/Autocomplete.test.js +12 -0
  174. package/src/react-extension/components/Common/Inputs/Autocomplete/AutocompleteItem.js +2 -2
  175. package/src/react-extension/components/Common/Legacy/HandleLegacyAppjs.js +1 -1
  176. package/src/react-extension/components/Common/Navigation/Header/Logo.js +13 -1
  177. package/src/react-extension/components/Resource/CreateResource/CreateResource.js +103 -30
  178. package/src/react-extension/components/Resource/CreateResource/CreateResource.test.js +44 -10
  179. package/src/react-extension/components/Resource/CreateResource/CreateResource.test.page.js +35 -7
  180. package/src/react-extension/components/Resource/DisplayResourcesList/DisplayResourcesList.js +3 -3
  181. package/src/react-extension/components/Resource/DisplayResourcesList/DisplayResourcesListContextualMenu.js +6 -5
  182. package/src/react-extension/components/Resource/DisplayResourcesWorkspace/DisplayResourcesWorkspaceMenu.js +5 -4
  183. package/src/react-extension/components/Resource/EditResource/EditResource.js +95 -23
  184. package/src/react-extension/components/Resource/EditResource/EditResource.test.js +45 -13
  185. package/src/react-extension/components/Resource/EditResource/EditResource.test.page.js +35 -2
  186. package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetails.js +2 -1
  187. package/src/react-extension/components/ResourceDetails/DisplayResourceDetails/DisplayResourceDetailsInformation.js +3 -2
  188. package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.js +23 -2
  189. package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.test.js +8 -0
  190. package/src/react-extension/components/ResourceFolder/CreateResourceFolder/CreateResourceFolder.test.page.js +26 -2
  191. package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.js +22 -1
  192. package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.test.js +8 -0
  193. package/src/react-extension/components/ResourceFolder/RenameResourceFolder/RenameResourceFolder.test.page.js +25 -2
  194. package/src/react-extension/components/ResourceFolderDetails/DisplayResourceFolderDetails/DisplayResourceFolderDetails.js +2 -1
  195. package/src/react-extension/components/ResourcePassword/GenerateResourcePassword/GenerateResourcePassword.js +2 -1
  196. package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.js +14 -1
  197. package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.test.js +8 -0
  198. package/src/react-extension/components/ResourceTag/EditResourceTag/EditResourceTag.test.page.js +12 -0
  199. package/src/react-extension/components/User/CreateUser/CreateUser.js +42 -3
  200. package/src/react-extension/components/User/CreateUser/CreateUser.test.js +16 -0
  201. package/src/react-extension/components/User/CreateUser/CreateUser.test.page.js +26 -0
  202. package/src/react-extension/components/User/DisplayUserWorkspaceActions/DisplayUserWorkspaceActions.js +2 -1
  203. package/src/react-extension/components/User/DisplayUsersContextualMenu/DisplayUsersContextualMenu.js +5 -5
  204. package/src/react-extension/components/User/EditUser/EditUser.js +29 -2
  205. package/src/react-extension/components/User/EditUser/EditUser.test.js +12 -0
  206. package/src/react-extension/components/User/EditUser/EditUser.test.page.js +26 -0
  207. package/src/react-extension/components/UserDetails/DisplayUserDetails/DisplayUserDetails.js +2 -1
  208. package/src/react-extension/components/UserDetails/DisplayUserDetails/DisplayUserDetails.test.data.js +1332 -1331
  209. package/src/react-extension/components/UserDetails/DisplayUserDetailsPublicKey/DisplayUserDetailsPublicKey.js +2 -1
  210. package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.js +19 -1
  211. package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.test.js +9 -0
  212. package/src/react-extension/components/UserGroup/CreateUserGroup/CreateUserGroup.test.page.js +12 -0
  213. package/src/react-extension/components/UserGroup/DisplayUserGroupDetails/DisplayUserGroupDetails.js +2 -1
  214. package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.js +16 -1
  215. package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.test.js +8 -0
  216. package/src/react-extension/components/UserGroup/EditUserGroup/EditUserGroup.test.page.js +26 -1
  217. package/src/react-extension/components/UserSetting/ChangeUserPassphrase/ConfirmPassphrase.js +1 -1
  218. package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.js +6 -4
  219. package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.data.js +4 -1
  220. package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.js +21 -11
  221. package/src/react-extension/components/UserSetting/ChangeUserPassphrase/EnterNewPassphrase.test.page.js +10 -1
  222. package/src/react-extension/contexts/AdminSmtpSettingsContext.js +2 -0
  223. package/src/react-extension/contexts/AdminSmtpSettingsContext.test.data.js +13 -0
  224. package/src/react-extension/contexts/AdminSmtpSettingsContext.test.js +3 -1
  225. package/src/react-extension/contexts/AdminSsoContext.js +558 -0
  226. package/src/react-extension/contexts/AdminSsoContext.test.data.js +51 -0
  227. package/src/react-extension/contexts/Administration/AdministrationInternationalizationContext/AdministrationInternationalizationContext.js +194 -0
  228. package/src/react-extension/contexts/Administration/AdministrationInternationalizationContext/AdministrationInternationalizationContext.test.js +111 -0
  229. package/src/react-extension/contexts/Administration/AdministrationMfa/AdministrationMfaContext.js +265 -0
  230. package/src/react-extension/contexts/Administration/AdministrationMfa/AdministrationMfaContext.test.js +178 -0
  231. package/src/react-extension/contexts/Administration/AdministrationSelfRegistration/AdministrationSelfRegistrationContext.js +453 -0
  232. package/src/react-extension/contexts/Administration/AdministrationSelfRegistration/AdministrationSelfRegistrationContext.test.js +218 -0
  233. package/src/react-extension/contexts/Administration/AdministrationSubscription/AdministrationSubscription.js +168 -0
  234. package/src/react-extension/contexts/Administration/AdministrationSubscription/AdministrationSubscription.test.js +73 -0
  235. package/src/react-extension/contexts/Administration/AdministrationUserDirectory/AdministrationUserDirectoryContext.js +353 -0
  236. package/src/react-extension/contexts/Administration/AdministrationUserDirectory/AdministrationUserDirectoryContext.test.js +220 -0
  237. package/src/react-extension/contexts/AdministrationWorkspaceContext.js +17 -178
  238. package/src/react-extension/contexts/AdministrationWorkspaceContext.test.js +0 -26
  239. package/src/react-extension/contexts/ApiAppContext.test.data.js +4 -2
  240. package/src/react-extension/contexts/Authentication/AuthenticationLoginContext.js +54 -4
  241. package/src/react-extension/contexts/Authentication/AuthenticationLoginContext.test.data.js +10 -1
  242. package/src/react-extension/contexts/Authentication/AuthenticationLoginContext.test.js +92 -14
  243. package/src/react-extension/contexts/Authentication/AuthenticationSetupContext.js +1 -0
  244. package/src/react-extension/contexts/NavigationContext.js +34 -0
  245. package/src/react-extension/contexts/SsoContext.js +151 -0
  246. package/src/react-extension/contexts/SsoContext.test.data.js +36 -0
  247. package/src/react-extension/contexts/SsoContext.test.js +104 -0
  248. package/src/react-extension/lib/Domain/DomainUtil.js +70 -0
  249. package/src/react-extension/lib/Domain/DomainUtil.test.js +129 -0
  250. package/src/react-extension/lib/Domain/Domains.js +6113 -0
  251. package/src/react-extension/lib/Error/InputValidator.js +24 -0
  252. package/src/react-extension/lib/Map/DynamicRef.js +49 -0
  253. package/src/react-extension/lib/Map/DynamicRef.test.js +56 -0
  254. package/src/react-extension/lib/Map/MapObject.js +48 -0
  255. package/src/react-extension/lib/Map/MapObject.test.js +43 -0
  256. package/src/react-quickaccess/ExtQuickAccess.js +7 -4
  257. package/src/react-quickaccess/components/GeneratePasswordPage/GeneratePasswordPage.js +3 -1
  258. package/src/react-quickaccess/components/GeneratePasswordPage/GeneratePasswordPage.test.data.js +4 -0
  259. package/src/react-quickaccess/components/LoginPage/LoginPage.js +115 -4
  260. package/src/react-quickaccess/components/LoginPage/LoginPage.test.data.js +10 -0
  261. package/src/react-quickaccess/components/LoginPage/LoginPage.test.stories.js +30 -3
  262. package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.js +33 -1
  263. package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.test.data.js +25 -0
  264. package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.test.js +60 -0
  265. package/src/react-quickaccess/components/ResourceAutoSave/SaveResource.test.page.js +60 -0
  266. package/src/react-quickaccess/components/ResourceCreatePage/ResourceCreatePage.js +33 -1
  267. package/src/react-quickaccess/components/ResourceCreatePage/ResourceCreatePage.test.js +36 -7
  268. package/src/react-quickaccess/components/ResourceViewPage/ResourceViewPage.js +3 -2
  269. package/src/react-quickaccess/contexts/SsoContext.js +150 -0
  270. package/src/react-web-integration/lib/InForm/InFormFieldSelector.js +5 -0
  271. package/src/shared/constants/inputs.const.js +30 -0
  272. package/src/shared/lib/Browser/clipBoard.js +45 -0
  273. package/src/shared/lib/Browser/clipBoard.test.js +59 -0
  274. package/src/shared/models/Mfa/Duo.js +36 -0
  275. package/src/shared/models/Mfa/Duo.test.js +59 -0
  276. package/src/shared/models/Mfa/MfaDTO.js +51 -0
  277. package/src/shared/models/Mfa/MfaDTO.test.js +48 -0
  278. package/src/shared/models/Mfa/MfaEnumeration.js +17 -0
  279. package/src/shared/models/Mfa/MfaModel.js +48 -0
  280. package/src/shared/models/Mfa/MfaModel.test.js +37 -0
  281. package/src/shared/models/Mfa/Yubikey.js +35 -0
  282. package/src/shared/models/Mfa/Yubikey.test.js +47 -0
  283. package/src/shared/models/selfRegistration/SelfRegistrationDomainsViewModel.js +55 -0
  284. package/src/shared/models/selfRegistration/SelfRegistrationDomainsViewModel.test.js +37 -0
  285. package/src/shared/models/selfRegistration/SelfRegistrationDto.js +42 -0
  286. package/src/shared/models/selfRegistration/SelfRegistrationDto.test.js +48 -0
  287. package/src/shared/models/selfRegistration/SelfRegistrationEnumeration.js +17 -0
  288. package/src/shared/models/subscription/SubscriptionDto.js +34 -0
  289. package/src/shared/models/subscription/SubscriptionDto.test.js +31 -0
  290. package/src/shared/models/subscription/SubscriptionModel.js +33 -0
  291. package/src/shared/models/subscription/SubscriptionModel.test.js +48 -0
  292. package/src/shared/models/user/UserModel.js +37 -0
  293. package/src/shared/models/userDirectory/UserDirectoryDTO.js +57 -0
  294. package/src/shared/models/userDirectory/UserDirectoryDTO.test.js +40 -0
  295. package/src/shared/models/userDirectory/UserDirectoryEnum.js +22 -0
  296. package/src/shared/models/userDirectory/UserDirectoryModel.js +64 -0
  297. package/src/shared/models/userDirectory/UserDirectoryModel.test.js +37 -0
  298. package/src/shared/services/actions/subscription/SubscriptionActionService.js +69 -0
  299. package/src/shared/services/actions/subscription/SubscriptionActionService.test.js +73 -0
  300. package/src/shared/services/api/Internationalisation/InternationalisationService.js +46 -0
  301. package/src/shared/services/api/Mfa/MfaService.js +54 -0
  302. package/src/shared/services/{accountRecovery → api/accountRecovery}/ApiAppAccountRecoveryUserService.js +2 -2
  303. package/src/shared/services/{accountRecovery → api/accountRecovery}/ExtAppAccountRecoveryUserService.js +0 -0
  304. package/src/shared/services/api/secrets/pownedService.js +64 -0
  305. package/src/shared/services/api/secrets/pownedService.test.js +63 -0
  306. package/src/shared/services/api/selfRegistration/selfRegistrationService.js +64 -0
  307. package/src/shared/services/api/user/UserService.js +45 -0
  308. package/src/shared/services/api/userDirectory/UserDirectoryService.js +108 -0
  309. package/src/shared/services/forms/Mfa/MfaFormService.js +195 -0
  310. package/src/shared/services/forms/Mfa/MfaFormService.test.js +341 -0
  311. package/src/shared/services/forms/selfRegistration/SelfRegistrationFormService.js +92 -0
  312. package/src/shared/services/forms/selfRegistration/SelfRegistrationFormService.test.js +101 -0
  313. package/src/shared/services/forms/userDirectory/UserDirectoryFormService.js +118 -0
  314. package/src/shared/services/forms/userDirectory/UserDirectoryFormService.test.js +128 -0
  315. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationWorkspaceActions.js +0 -205
  316. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationWorkspaceActions.test.data.js +0 -37
  317. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationWorkspaceActions.test.js +0 -197
  318. package/src/react-extension/components/Administration/DisplayAdministrationWorkspaceActions/DisplayAdministrationWorkspaceActions.test.page.js +0 -133
@@ -151,13 +151,29 @@ export default class CreateGpgKeyPage {
151
151
  return Boolean(this._page.container.querySelector('#import-key-link'));
152
152
  }
153
153
 
154
+
155
+ /**
156
+ * Returns the list item concerning the 'not in dictionnary" hints
157
+ */
158
+ get notInDictionaryHint() {
159
+ return this._page.container.querySelectorAll(".password-hints li")[4];
160
+ }
161
+
162
+ /**
163
+ * Returns the tooltip for service unavailable for powned password
164
+ */
165
+ get tootltip() {
166
+ return this._page.container.querySelector(".password-hints .unavailable .tooltip .tooltip-text");
167
+ }
168
+
154
169
  /**
155
170
  * Change the passphrase input value
156
171
  * @param passphrase The new passphrase
157
172
  */
158
173
  async fill(passphrase) {
159
174
  fireEvent.change(this.passphraseInput, {target: {value: passphrase}});
160
- await waitFor(async() => {});
175
+ jest.runAllTimers();
176
+ await waitFor(() => {});
161
177
  }
162
178
 
163
179
  /**
@@ -57,7 +57,9 @@ class Login extends Component {
57
57
  emptyPassphrase: false, // True if the passphrase is empty
58
58
  invalidPassphrase: false, // True if the passphrase is invalid
59
59
  invalidGpgKey: false, // True if the gpg key is invalid
60
- }
60
+ },
61
+ isSsoAvailable: false, // true if the current user has an SSO kit built locally
62
+ displaySso: false, // true if the UI should display the SSO login button
61
63
  };
62
64
  }
63
65
 
@@ -123,6 +125,9 @@ class Login extends Component {
123
125
  this.handleSubmit = this.handleSubmit.bind(this);
124
126
  this.handleChangePassphrase = this.handleChangePassphrase.bind(this);
125
127
  this.handleToggleRememberMe = this.handleToggleRememberMe.bind(this);
128
+ this.handleSwitchToSso = this.handleSwitchToSso.bind(this);
129
+ this.handleSwitchToPassphrase = this.handleSwitchToPassphrase.bind(this);
130
+ this.handleSignInWithSso = this.handleSignInWithSso.bind(this);
126
131
  }
127
132
 
128
133
  /**
@@ -136,7 +141,14 @@ class Login extends Component {
136
141
  * Whenever the component is mounted
137
142
  */
138
143
  componentDidMount() {
139
- this.focusOnPassphrase();
144
+ const isSsoAvailable = Boolean(this.ssoProviderData);
145
+ this.setState({
146
+ isSsoAvailable: isSsoAvailable,
147
+ displaySso: isSsoAvailable,
148
+ });
149
+ if (!isSsoAvailable) {
150
+ this.focusOnPassphrase();
151
+ }
140
152
  }
141
153
 
142
154
  /**
@@ -251,8 +263,47 @@ class Login extends Component {
251
263
  /**
252
264
  * Toggle the processing mode
253
265
  */
254
- async toggleProcessing() {
255
- await this.setState({actions: {processing: true}});
266
+ toggleProcessing() {
267
+ this.setState({actions: {processing: !this.state.actions.processing}});
268
+ }
269
+
270
+ /**
271
+ * Switches the UI to the SSO mode.
272
+ */
273
+ handleSwitchToSso(event) {
274
+ event.preventDefault();
275
+ this.setState({displaySso: true});
276
+ }
277
+
278
+ /**
279
+ * Switches the UI to the passphrase mode.
280
+ */
281
+ handleSwitchToPassphrase(event) {
282
+ event.preventDefault();
283
+ this.setState({displaySso: false});
284
+ }
285
+
286
+ /**
287
+ * Handle the click on the SSO login button.
288
+ * @returns {Promise<void>}
289
+ */
290
+ async handleSignInWithSso(event) {
291
+ event.preventDefault();
292
+ this.setState({actions: {
293
+ processing: true
294
+ }});
295
+ try {
296
+ await this.props.onSsoSignIn();
297
+ } catch (e) {
298
+ this.setState({
299
+ displaySso: false
300
+ });
301
+ }
302
+ this.setState({
303
+ actions: {
304
+ processing: false
305
+ }
306
+ });
256
307
  }
257
308
 
258
309
  /**
@@ -267,12 +318,29 @@ class Login extends Component {
267
318
  };
268
319
  }
269
320
 
321
+ /**
322
+ * Returns true if SSO is enabled and configured for Azure.
323
+ * @return {bool}
324
+ */
325
+ get isAzureSsoEnabled() {
326
+ return this.ssoProviderData?.id === "azure";
327
+ }
328
+
329
+ /**
330
+ * Returns the provider information of the current SSO provider configured.
331
+ * @return {object}
332
+ */
333
+ get ssoProviderData() {
334
+ return this.props.ssoProvider;
335
+ }
336
+
270
337
  /**
271
338
  * Render the component
272
339
  */
273
340
  render() {
274
341
  const processingClassName = this.isProcessing ? 'processing' : '';
275
342
  const securityToken = this.securityToken;
343
+ const ssoProviderData = this.ssoProviderData;
276
344
 
277
345
  return (
278
346
  <div className="login">
@@ -281,68 +349,95 @@ class Login extends Component {
281
349
  <p className="login-user-name">{this.fullname}</p>
282
350
  <p className="login-user-email">{this.username}</p>
283
351
  </div>
352
+ {!this.state.displaySso &&
353
+ <form acceptCharset="utf-8" onSubmit={this.handleSubmit} className="enter-passphrase">
354
+ <div className={`input-password-wrapper input required ${this.hasErrors ? "error" : ""}`}>
355
+ <label htmlFor="passphrase">
356
+ <Trans>Passphrase</Trans>
357
+ </label>
358
+ <Password
359
+ id="passphrase"
360
+ autoComplete="off"
361
+ inputRef={this.passphraseInputRef}
362
+ name="passphrase"
363
+ placeholder={this.props.t('Passphrase')}
364
+ value={this.state.passphrase}
365
+ onChange={this.handleChangePassphrase}
366
+ disabled={!this.areActionsAllowed}
367
+ preview={true}
368
+ securityToken={securityToken}/>
369
+ {this.state.hasBeenValidated &&
370
+ <>
371
+ {this.state.errors.emptyPassphrase &&
372
+ <div className="empty-passphrase error-message"><Trans>The passphrase should not be empty.</Trans></div>
373
+ }
374
+ {this.state.errors.invalidPassphrase &&
375
+ <div className="invalid-passphrase error-message">
376
+ <Trans>The passphrase is invalid.</Trans> {this.state.isSsoAvailable && <a onClick={this.props.onSecondaryActionClick}><Trans>Do you need help?</Trans></a>}
377
+ </div>
378
+ }
379
+ {this.state.errors.invalidGpgKey &&
380
+ <div className="invalid-gpg-key error-message"><Trans>The private key is invalid.</Trans></div>
381
+ }
382
+ </>
383
+ }
384
+ </div>
385
+ {this.props.canRememberMe &&
386
+ <div className="input checkbox">
387
+ <input
388
+ id="remember-me"
389
+ type="checkbox"
390
+ name="remember-me"
391
+ value={this.state.rememberMe}
392
+ onChange={this.handleToggleRememberMe}
393
+ disabled={!this.areActionsAllowed}/>
394
+ <label htmlFor="remember-me">
395
+ <Trans>Remember until signed out.</Trans>
396
+ </label>
397
+ </div>
398
+ }
284
399
 
285
- <form acceptCharset="utf-8" onSubmit={this.handleSubmit} className="enter-passphrase">
286
- <div className={`input-password-wrapper input required ${this.hasErrors ? "error" : ""}`}>
287
- <label htmlFor="passphrase">
288
- <Trans>Passphrase</Trans>
289
- </label>
290
- <Password
291
- id="passphrase"
292
- autoComplete="off"
293
- inputRef={this.passphraseInputRef}
294
- name="passphrase"
295
- placeholder={this.props.t('Passphrase')}
296
- value={this.state.passphrase}
297
- onChange={this.handleChangePassphrase}
298
- disabled={!this.areActionsAllowed}
299
- preview={true}
300
- securityToken={securityToken}/>
301
- {this.state.hasBeenValidated &&
302
- <>
303
- {this.state.errors.emptyPassphrase &&
304
- <div className="empty-passphrase error-message"><Trans>The passphrase should not be empty.</Trans></div>
400
+ <div className="form-actions">
401
+ <button
402
+ type="submit"
403
+ className={`button primary big full-width ${processingClassName}`}
404
+ role="button"
405
+ disabled={this.isProcessing}>
406
+ {{
407
+ [LoginVariations.SIGN_IN]: <Trans>Sign in</Trans>,
408
+ [LoginVariations.ACCOUNT_RECOVERY]: <Trans>Complete recovery</Trans>,
409
+ }[this.props.displayAs]}
410
+ </button>
411
+ {this.state.isSsoAvailable &&
412
+ <a className="switchToSso" onClick={this.handleSwitchToSso}>
413
+ <Trans>Sign in with Single Sign-On.</Trans>
414
+ </a>
305
415
  }
306
- {this.state.errors.invalidPassphrase &&
307
- <div className="invalid-passphrase error-message"><Trans>The passphrase is invalid.</Trans></div>
416
+ {!this.state.isSsoAvailable &&
417
+ <a onClick={this.props.onSecondaryActionClick}>
418
+ <Trans>Help, I lost my passphrase.</Trans>
419
+ </a>
308
420
  }
309
- {this.state.errors.invalidGpgKey &&
310
- <div className="invalid-gpg-key error-message"><Trans>The private key is invalid.</Trans></div>
421
+ </div>
422
+ </form>
423
+ }
424
+ {this.state.displaySso &&
425
+ <>
426
+ <div className="form-actions sso-login-form">
427
+ {this.isAzureSsoEnabled &&
428
+ <a className={`button sso-login-button ${this.isProcessing ? "disabled" : ""} ${ssoProviderData.id}`} onClick={this.handleSignInWithSso} disabled={this.isProcessing} >
429
+ <span className="provider-logo">
430
+ {ssoProviderData.icon}
431
+ </span>
432
+ {this.props.t(`Sign in with {{providerName}}`, {providerName: ssoProviderData.name})}
433
+ </a>
311
434
  }
312
- </>
313
- }
314
- </div>
315
- {this.props.canRememberMe &&
316
- <div className="input checkbox">
317
- <input
318
- id="remember-me"
319
- type="checkbox"
320
- name="remember-me"
321
- value={this.state.rememberMe}
322
- onChange={this.handleToggleRememberMe}
323
- disabled={!this.areActionsAllowed}/>
324
- <label htmlFor="remember-me">
325
- <Trans>Remember until signed out.</Trans>
326
- </label>
435
+ <a onClick={this.handleSwitchToPassphrase}>
436
+ <Trans>Sign in with my passphrase.</Trans>
437
+ </a>
327
438
  </div>
328
- }
329
-
330
- <div className="form-actions">
331
- <button
332
- type="submit"
333
- className={`button primary big full-width ${processingClassName}`}
334
- role="button"
335
- disabled={this.isProcessing}>
336
- {{
337
- [LoginVariations.SIGN_IN]: <Trans>Sign in</Trans>,
338
- [LoginVariations.ACCOUNT_RECOVERY]: <Trans>Complete recovery</Trans>,
339
- }[this.props.displayAs]}
340
- </button>
341
- <a onClick={this.props.onSecondaryActionClick}>
342
- <Trans>Help, I lost my passphrase.</Trans>
343
- </a>
344
- </div>
345
- </form>
439
+ </>
440
+ }
346
441
  </div>
347
442
  );
348
443
  }
@@ -358,12 +453,15 @@ Login.propTypes = {
358
453
  LoginVariations.ACCOUNT_RECOVERY,
359
454
  ]), // Defines how the form should be displayed and behaves
360
455
  context: PropTypes.any, // The application context
456
+ ssoContext: PropTypes.object, // The SSO context
361
457
  account: PropTypes.object, // The user account
362
458
  userSettings: PropTypes.object, // The user settings
363
459
  canRememberMe: PropTypes.bool, // True if the remember me flag must be displayed
364
460
  onSignIn: PropTypes.func.isRequired, // Callback to trigger whenever the user wants to sign-in
365
461
  onCheckPassphrase: PropTypes.func.isRequired, // Callback to trigger whenever the user wants to check the passphrase
462
+ onSsoSignIn: PropTypes.func, // Callback to trigger whenever the user wants to sign-in using SSO
366
463
  onSecondaryActionClick: PropTypes.func, // Callback to trigger when the user clicks on the secondary action link.
464
+ ssoProvider: PropTypes.object, // The SSO provider if any
367
465
  t: PropTypes.func, // The translation function
368
466
  };
369
467
  export default withAppContext(withTranslation('common')(Login));
@@ -14,6 +14,7 @@
14
14
 
15
15
  import {LoginVariations} from "./Login";
16
16
  import UserSettings from "../../../../shared/lib/Settings/UserSettings";
17
+ import {defaultAppContext} from "../../../contexts/ExtAppContext.test.data";
17
18
 
18
19
  /**
19
20
  * Default props
@@ -21,19 +22,21 @@ import UserSettings from "../../../../shared/lib/Settings/UserSettings";
21
22
  * @returns {Object}
22
23
  */
23
24
  export function defaultProps(props = {}) {
25
+ const userSettings = new UserSettings({
26
+ "user.settings.securityToken.code": "TST",
27
+ "user.settings.securityToken.color": "#f44336",
28
+ "user.settings.securityToken.textColor": "#ffffff",
29
+ "user.settings.trustedDomain": (new URL(window.location.href)).origin,
30
+ "user.id": "d57c10f5-639d-5160-9c81-8a0c6c4ec856",
31
+ "user.username": "admin@passbolt.com",
32
+ "user.firstname": "Admin",
33
+ "user.lastname": "User",
34
+ "user.settings.locale": "fr-FR"
35
+ });
24
36
  const defaultProps = {
25
37
  displayAs: LoginVariations.SIGN_IN,
26
- userSettings: new UserSettings({
27
- "user.settings.securityToken.code": "TST",
28
- "user.settings.securityToken.color": "#f44336",
29
- "user.settings.securityToken.textColor": "#ffffff",
30
- "user.settings.trustedDomain": (new URL(window.location.href)).origin,
31
- "user.id": "d57c10f5-639d-5160-9c81-8a0c6c4ec856",
32
- "user.username": "admin@passbolt.com",
33
- "user.firstname": "Admin",
34
- "user.lastname": "User",
35
- "user.settings.locale": "fr-FR"
36
- }),
38
+ context: defaultAppContext({userSettings}),
39
+ userSettings: userSettings,
37
40
  onSignIn: jest.fn(() => Promise.resolve()),
38
41
  onCheckPassphrase: jest.fn(() => Promise.resolve()),
39
42
  onSecondaryActionClick: jest.fn(() => Promise.resolve()),
@@ -19,6 +19,8 @@ import each from "jest-each";
19
19
  import LoginPage from "./Login.test.page";
20
20
  import {LoginVariations} from "./Login";
21
21
  import {defaultProps} from "./Login.test.data";
22
+ import {waitFor} from "@testing-library/dom";
23
+ import SsoProviders from "../../Administration/ManageSsoSettings/SsoProviders.data";
22
24
 
23
25
  beforeEach(() => {
24
26
  jest.resetModules();
@@ -33,6 +35,8 @@ describe("Login", () => {
33
35
  const props = defaultProps(_props);
34
36
  const page = new LoginPage(props);
35
37
 
38
+ await waitFor(() => {});
39
+
36
40
  expect.assertions(2);
37
41
  const expectedPassphrase = "some passphrase";
38
42
  await page.fillPassphrase(expectedPassphrase);
@@ -45,6 +49,8 @@ describe("Login", () => {
45
49
  const props = defaultProps({..._props, canRememberMe: false});
46
50
  const page = new LoginPage(props);
47
51
 
52
+ await waitFor(() => {});
53
+
48
54
  expect.assertions(2);
49
55
  expect(page.canRememberMe).toBeFalsy();
50
56
  const expectedPassphrase = "some passphrase";
@@ -57,6 +63,8 @@ describe("Login", () => {
57
63
  const props = defaultProps({..._props, canRememberMe: true});
58
64
  const page = new LoginPage(props);
59
65
 
66
+ await waitFor(() => {});
67
+
60
68
  expect.assertions(2);
61
69
  expect(page.canRememberMe).toBeTruthy();
62
70
  const expectedPassphrase = "some passphrase";
@@ -70,6 +78,8 @@ describe("Login", () => {
70
78
  const props = defaultProps({..._props});
71
79
  const page = new LoginPage(props);
72
80
 
81
+ await waitFor(() => {});
82
+
73
83
  expect.assertions(1);
74
84
  await page.clickSecondaryActionLink();
75
85
  expect(props.onSecondaryActionClick).toHaveBeenCalled();
@@ -81,6 +91,8 @@ describe("Login", () => {
81
91
  const props = defaultProps({..._props, onSignIn});
82
92
  const page = new LoginPage(props);
83
93
 
94
+ await waitFor(() => {});
95
+
84
96
  expect.hasAssertions();
85
97
  const inProgressFn = () => {
86
98
  expect(page.canChange).toBeFalsy();
@@ -98,6 +110,8 @@ describe("Login", () => {
98
110
  const props = defaultProps({..._props, onSignIn});
99
111
  const page = new LoginPage(props);
100
112
 
113
+ await waitFor(() => {});
114
+
101
115
  expect.hasAssertions();
102
116
  const inProgressFn = () => {
103
117
  expect(page.isProcessing).toBeTruthy();
@@ -113,6 +127,8 @@ describe("Login", () => {
113
127
  const props = defaultProps(_props);
114
128
  const page = new LoginPage(props);
115
129
 
130
+ await waitFor(() => {});
131
+
116
132
  expect.assertions(1);
117
133
  const emptyPassphrase = ' ';
118
134
  await page.fillPassphrase(emptyPassphrase);
@@ -126,6 +142,8 @@ describe("Login", () => {
126
142
  const props = defaultProps({..._props, onCheckPassphrase});
127
143
  const page = new LoginPage(props);
128
144
 
145
+ await waitFor(() => {});
146
+
129
147
  expect.assertions(1);
130
148
  await page.fillPassphrase('some passphrase');
131
149
  await page.signIn();
@@ -138,6 +156,8 @@ describe("Login", () => {
138
156
  const props = defaultProps({displayAs: LoginVariations.SIGN_IN});
139
157
  const page = new LoginPage(props);
140
158
 
159
+ await waitFor(() => {});
160
+
141
161
  expect.assertions(2);
142
162
  expect(page.signInButton.textContent).toBe("Sign in");
143
163
  expect(page.secondaryActionLink.textContent).toBe("Help, I lost my passphrase.");
@@ -149,9 +169,68 @@ describe("Login", () => {
149
169
  const props = defaultProps({displayAs: LoginVariations.ACCOUNT_RECOVERY});
150
170
  const page = new LoginPage(props);
151
171
 
172
+ await waitFor(() => {});
173
+
152
174
  expect.assertions(2);
153
175
  expect(page.signInButton.textContent).toBe("Complete recovery");
154
176
  expect(page.secondaryActionLink.textContent).toBe("Help, I lost my passphrase.");
155
177
  });
156
178
  });
179
+
180
+ describe("As a registered user I can use the SSO feature to sign in to passbolt", () => {
181
+ const ssoProvider = SsoProviders.find(provider => provider.id === "azure");
182
+
183
+ it('As AN I cannot see the SSO login button if I do not have an SSO kit set on my browser profile', async() => {
184
+ expect.assertions(1);
185
+ const props = defaultProps({
186
+ displayAs: LoginVariations.SIGN_IN,
187
+ ssoProvider: null,
188
+ });
189
+
190
+ const page = new LoginPage(props);
191
+ await waitFor(() => {});
192
+
193
+ expect(page.secondaryActionLink.textContent).toStrictEqual("Help, I lost my passphrase.");
194
+ });
195
+
196
+ it('As AN I can see the SSO login button if I have an SSO kit set on my browser profile', async() => {
197
+ expect.assertions(1);
198
+ const props = defaultProps({
199
+ displayAs: LoginVariations.SIGN_IN,
200
+ ssoProvider,
201
+ });
202
+
203
+ const page = new LoginPage(props);
204
+ await waitFor(() => {});
205
+
206
+ expect(page.azureLoginButton).toBeTruthy();
207
+ });
208
+
209
+ it('As AN I can use the SSO login feature to sign in to Passbolt', async() => {
210
+ expect.assertions(4);
211
+
212
+ let signInPromiseResolver = null;
213
+ const props = defaultProps({
214
+ displayAs: LoginVariations.SIGN_IN,
215
+ onSsoSignIn: jest.fn().mockImplementation(() => new Promise(resolve => {
216
+ signInPromiseResolver = resolve;
217
+ })),
218
+ ssoProvider,
219
+ });
220
+
221
+ const page = new LoginPage(props);
222
+ await waitFor(() => {});
223
+
224
+ expect(page.azureLoginButton).toBeTruthy();
225
+
226
+ await page.clickOnSsoLogin();
227
+ expect(page.azureLoginButton.classList.contains('disabled')).toBeTruthy();
228
+
229
+ expect(props.onSsoSignIn).toHaveBeenCalledTimes(1);
230
+
231
+ await signInPromiseResolver();
232
+
233
+ expect(page.azureLoginButton.classList.contains('disabled')).toBeFalsy();
234
+ });
235
+ });
157
236
  });
@@ -86,6 +86,13 @@ export default class LoginPage {
86
86
  return this._page.container.querySelector('.form-actions a');
87
87
  }
88
88
 
89
+ /**
90
+ * Returns the Azure SSO login button element
91
+ */
92
+ get azureLoginButton() {
93
+ return this._page.container.querySelector('.sso-login-form .sso-login-button');
94
+ }
95
+
89
96
  /**
90
97
  * Returns true if the user can change something like the token code
91
98
  */
@@ -152,4 +159,13 @@ export default class LoginPage {
152
159
  fireEvent.click(this.secondaryActionLink, leftClick);
153
160
  await waitFor(inProgressFn);
154
161
  }
162
+
163
+ /**
164
+ * Click on the secondary action link.
165
+ */
166
+ async clickOnSsoLogin(inProgressFn = () => {}) {
167
+ const leftClick = {button: 0};
168
+ fireEvent.click(this.azureLoginButton, leftClick);
169
+ await waitFor(inProgressFn);
170
+ }
155
171
  }
@@ -43,6 +43,8 @@ class OrchestrateLoginBoxMain extends Component {
43
43
  onSignIn={this.props.authenticationLoginContext.signIn}
44
44
  onCheckPassphrase={this.props.authenticationLoginContext.checkPassphrase}
45
45
  onSecondaryActionClick={this.props.authenticationLoginContext.needHelpCredentialsLost}
46
+ onSsoSignIn={this.props.authenticationLoginContext.handleSsoSignIn}
47
+ ssoProvider={this.props.authenticationLoginContext.getSsoProvider()}
46
48
  />;
47
49
  case AuthenticationLoginWorkflowStates.ACCEPT_NEW_SERVER_KEY:
48
50
  return <AcceptLoginServerKeyChange
@@ -79,6 +79,10 @@ class SetupAuthentication extends Component {
79
79
  return <ChooseSecurityToken
80
80
  onComplete={this.props.authenticationSetupContext.chooseSecurityToken}
81
81
  />;
82
+ case AuthenticationSetupWorkflowStates.CONFIGURING_SSO:
83
+ return <LoadingSpinner
84
+ title={<Trans>Configuring SSO access, please wait...</Trans>}
85
+ />;
82
86
  case AuthenticationSetupWorkflowStates.COMPLETING_SETUP:
83
87
  return <LoadingSpinner
84
88
  title={<Trans>Completing setup, please wait...</Trans>}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Passbolt ~ Open source password manager for teams
3
+ * Copyright (c) 2020 Passbolt SA (https://www.passbolt.com)
4
+ *
5
+ * Licensed under GNU Affero General Public License version 3 of the or any later version.
6
+ * For full copyright and license information, please see the LICENSE.txt
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright Copyright (c) 2020 Passbolt SA (https://www.passbolt.com)
10
+ * @license https://opensource.org/licenses/AGPL-3.0 AGPL License
11
+ * @link https://www.passbolt.com Passbolt(tm)
12
+ * @since 3.9.0
13
+ */
14
+ import React, {Component} from "react";
15
+ import PropTypes from "prop-types";
16
+ import {Trans, withTranslation} from "react-i18next";
17
+ import AnimatedFeedback from "../../../../../shared/components/Icons/AnimatedFeedback";
18
+ import Icon from "../../../../../shared/components/Icons/Icon";
19
+
20
+ class ApiError extends Component {
21
+ /**
22
+ * Constructor
23
+ * @param {Object} props
24
+ */
25
+ constructor(props) {
26
+ super(props);
27
+ this.state = this.defaultState;
28
+ this.bindCallbacks();
29
+ }
30
+
31
+ get defaultState() {
32
+ return {
33
+ isReady: false,
34
+ displayLogs: false,
35
+ errorDetails: "",
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Bind callbacks methods
41
+ * @return {void}
42
+ */
43
+ bindCallbacks() {
44
+ this.handleDisplayLogsClick = this.handleDisplayLogsClick.bind(this);
45
+ }
46
+
47
+ /**
48
+ * ComponentDidMount
49
+ * Invoked immediately after component is inserted into the tree
50
+ * @return {void}
51
+ */
52
+ componentDidMount() {
53
+ const errorDetailNode = document.getElementById("api-error-details");
54
+ const state = {
55
+ isReady: true,
56
+ errorDetails: errorDetailNode?.textContent
57
+ };
58
+
59
+ this.setState(state);
60
+ }
61
+
62
+ /**
63
+ * Handles the click on the display logs button.
64
+ */
65
+ handleDisplayLogsClick() {
66
+ this.setState({displayLogs: !this.state.displayLogs});
67
+ }
68
+
69
+ /**
70
+ * Returns true after the initial load of the page
71
+ * @returns {boolean}
72
+ */
73
+ isReady() {
74
+ return this.state.isReady;
75
+ }
76
+
77
+ /**
78
+ * Render the component
79
+ * @return {JSX}
80
+ */
81
+ render() {
82
+ return (
83
+ <div id="container" className="container api-error page">
84
+ <div className="content">
85
+ <div className="header">
86
+ <div className="logo"><span className="visually-hidden">Passbolt</span></div>
87
+ </div>
88
+ <div className="api-error-card">
89
+ {this.isReady() &&
90
+ <>
91
+ <AnimatedFeedback name="attention"/>
92
+ <p>
93
+ <Trans>Something went wrong!</Trans><br/>
94
+ <Trans>Please try again later or contact your administrator.</Trans>
95
+ </p>
96
+ <div className="accordion-header">
97
+ <a onClick={this.handleDisplayLogsClick}>
98
+ <Icon name={this.state.displayLogs ? "caret-down" : "caret-right"}/> <Trans>Logs</Trans>
99
+ </a>
100
+ </div>
101
+ {this.state.displayLogs &&
102
+ <div className="accordion-content">
103
+ <textarea readOnly={true} value={this.state.errorDetails}/>
104
+ </div>
105
+ }
106
+ </>
107
+ }
108
+ </div>
109
+ </div>
110
+ </div>
111
+ );
112
+ }
113
+ }
114
+
115
+ ApiError.propTypes = {
116
+ t: PropTypes.func // the translation function
117
+ };
118
+
119
+ export default withTranslation("common")(ApiError);