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
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Passbolt ~ Open source password manager for teams
3
+ * Copyright (c) 2022 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) 2022 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
+
15
+ export function maxSizeValidation(value, maxLength, translate) {
16
+ /*
17
+ * The parser can't find the translation for warningMessage variable
18
+ * To fix that we can use it in comment
19
+ * this.translate("this is the maximum size for this field, make sure your data was not truncated")
20
+ */
21
+ const sizeExceeded = value.length >= maxLength;
22
+ const warningMessage = translate("this is the maximum size for this field, make sure your data was not truncated");
23
+ return sizeExceeded ? warningMessage : "";
24
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Passbolt ~ Open source password manager for teams
3
+ * Copyright (c) 2022 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) 2022 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
+
15
+ import * as React from "react";
16
+
17
+ /**
18
+ * Dynamic ref is used to generate ref automaticly, like we can do with a hook.
19
+ * Use this when we do not have the control of elements: like during a generation of inputs, buttons, ...
20
+ */
21
+
22
+ const map = new Map();
23
+
24
+ /**
25
+ * set a new ref to map
26
+ */
27
+ function setRef(key) {
28
+ if (typeof key !== "string") { return console.warn(`useDynamicRefs: Cannot set ref without key`); }
29
+ const ref = React.createRef();
30
+ map.set(key, ref);
31
+ return ref;
32
+ }
33
+
34
+ /**
35
+ * get input ref
36
+ */
37
+ function getRef(key) {
38
+ if (!key) { return console.warn(`useDynamicRefs: Cannot get ref without key`); }
39
+ return map.get(key);
40
+ }
41
+
42
+ /**
43
+ * return the dynamic object
44
+ */
45
+ function useDynamicRefs() {
46
+ return {getRef, setRef};
47
+ }
48
+
49
+ export default useDynamicRefs;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Passbolt ~ Open source password manager for teams
3
+ * Copyright (c) 2022 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) 2022 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
+
15
+ import useDynamicRefs from './DynamicRef';
16
+
17
+ describe("DynamicRef", () => {
18
+ const dynamicRefs = useDynamicRefs();
19
+
20
+ describe("DynamicRef::setRef", () => {
21
+ it("should set value if valid key provided", () => {
22
+ expect.assertions(2);
23
+
24
+ const key = "test";
25
+ dynamicRefs.setRef(key);
26
+ expect(dynamicRefs.getRef(key)).not.toBeNull();
27
+ expect(dynamicRefs.getRef(key)).toBeDefined();
28
+ });
29
+
30
+ it("should not set value if key does not exist", () => {
31
+ expect.assertions(1);
32
+
33
+ console.warn = jest.fn();
34
+ dynamicRefs.setRef();
35
+ expect(console.warn.mock.calls[0][0]).toBe("useDynamicRefs: Cannot set ref without key");
36
+ });
37
+
38
+ it("should not set value if key is not a string", () => {
39
+ expect.assertions(1);
40
+
41
+ console.warn = jest.fn();
42
+ dynamicRefs.setRef(null);
43
+ expect(console.warn.mock.calls[0][0]).toBe("useDynamicRefs: Cannot set ref without key");
44
+ });
45
+ });
46
+
47
+ describe("DynamicRef::getRef", () => {
48
+ it("should not set value if key does not exist", () => {
49
+ expect.assertions(1);
50
+
51
+ console.warn = jest.fn();
52
+ dynamicRefs.getRef();
53
+ expect(console.warn.mock.calls[0][0]).toBe("useDynamicRefs: Cannot get ref without key");
54
+ });
55
+ });
56
+ });
@@ -0,0 +1,48 @@
1
+
2
+ /**
3
+ * Passbolt ~ Open source password manager for teams
4
+ * Copyright (c) Passbolt SA (https://www.passbolt.com)
5
+ *
6
+ * Licensed under GNU Affero General Public License version 3 of the or any later version.
7
+ * For full copyright and license information, please see the LICENSE.txt
8
+ * Redistributions of files must retain the above copyright notice.
9
+ *
10
+ * @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
11
+ * @license https://opensource.org/licenses/AGPL-3.0 AGPL License
12
+ * @link https://www.passbolt.com Passbolt(tm)
13
+ * @since 3.8.3
14
+ */
15
+
16
+ /**
17
+ * This util is used to generalise map method
18
+ */
19
+ class MapObject {
20
+ /**
21
+ * clone a map object
22
+ * @param {any} object
23
+ * @returns clone of object
24
+ */
25
+ static clone(object) {
26
+ return new Map(JSON.parse(JSON.stringify(Array.from(object))));
27
+ }
28
+
29
+ /**
30
+ * return map iteration
31
+ * @param {any} object
32
+ * @returns iterations
33
+ */
34
+ static iterators(object) {
35
+ return [...object.keys()];
36
+ }
37
+
38
+ /**
39
+ * return values array
40
+ * @param {any} object
41
+ * @returns iterations
42
+ */
43
+ static listValues(object) {
44
+ return [...object.values()];
45
+ }
46
+ }
47
+
48
+ export default MapObject;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Passbolt ~ Open source password manager for teams
3
+ * Copyright (c) 2022 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) 2022 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.8.3
13
+ */
14
+
15
+ import MapObject from './MapObject';
16
+
17
+ describe("MapObject", () => {
18
+ describe("MapObject::clone", () => {
19
+ it("should clone map object", () => {
20
+ expect.assertions(2);
21
+
22
+ const map1 = new Map();
23
+ map1.set('a', 1);
24
+ const clonedMap = MapObject.clone(map1);
25
+ clonedMap.set('a', 2);
26
+
27
+ expect(clonedMap.get("a")).toEqual(2);
28
+ expect(map1.get("a")).toEqual(1);
29
+ });
30
+ });
31
+
32
+ describe("MapObject::iterators", () => {
33
+ it("should return an array of keys", () => {
34
+ expect.assertions(1);
35
+
36
+ const map1 = new Map();
37
+ map1.set('a', 1);
38
+ map1.set('b', 2);
39
+
40
+ expect(MapObject.iterators(map1)).toEqual(["a", "b"]);
41
+ });
42
+ });
43
+ });
@@ -30,6 +30,7 @@ import SaveResource from "./components/ResourceAutoSave/SaveResource";
30
30
  import GeneratePasswordPage from "./components/GeneratePasswordPage/GeneratePasswordPage";
31
31
  import PrepareResourceContextProvider from "./contexts/PrepareResourceContext";
32
32
  import Icon from "../shared/components/Icons/Icon";
33
+ import SsoContextProvider from "./contexts/SsoContext";
33
34
 
34
35
  const SEARCH_VISIBLE_ROUTES = [
35
36
  '/webAccessibleResources/quickaccess.html',
@@ -272,10 +273,12 @@ class ExtQuickAccess extends React.Component {
272
273
  <PrepareResourceContextProvider>
273
274
  <AnimatedSwitch>
274
275
  <Route path="/webAccessibleResources/quickaccess/login" render={() => (
275
- <LoginPage
276
- loginSuccessCallback={this.loginSuccessCallback}
277
- mfaRequiredCallback={this.mfaRequiredCallback}
278
- canRememberMe={this.canRememberMe}/>
276
+ <SsoContextProvider>
277
+ <LoginPage
278
+ loginSuccessCallback={this.loginSuccessCallback}
279
+ mfaRequiredCallback={this.mfaRequiredCallback}
280
+ canRememberMe={this.canRememberMe}/>
281
+ </SsoContextProvider>
279
282
  )}/>
280
283
  <PrivateRoute exact path="/webAccessibleResources/quickaccess/resources/group" component={FilterResourcesByGroupPage}/>
281
284
  <PrivateRoute path="/webAccessibleResources/quickaccess/resources/group/:id" component={FilterResourcesByGroupPage}/>
@@ -12,6 +12,7 @@ import Transition from "react-transition-group/cjs/Transition";
12
12
  import Icon from "../../../shared/components/Icons/Icon";
13
13
  import Password from "../../../shared/components/Password/Password";
14
14
  import PasswordComplexity from "../../../shared/components/PasswordComplexity/PasswordComplexity";
15
+ import ClipBoard from '../../../shared/lib/Browser/clipBoard';
15
16
 
16
17
  class GeneratePasswordPage extends React.Component {
17
18
  constructor(props) {
@@ -115,7 +116,7 @@ class GeneratePasswordPage extends React.Component {
115
116
  */
116
117
  async handleCopyPassword() {
117
118
  this.setState({copySecretState: 'processing'});
118
- await navigator.clipboard.writeText(this.state.password);
119
+ await ClipBoard.copy(this.state.password, this.props.context.port);
119
120
  this.setState({copySecretState: 'done'});
120
121
  setTimeout(() => {
121
122
  this.setState({copySecretState: 'default'});
@@ -255,6 +256,7 @@ class GeneratePasswordPage extends React.Component {
255
256
  }
256
257
 
257
258
  GeneratePasswordPage.propTypes = {
259
+ context: PropTypes.any, // The application context
258
260
  prepareResourceContext: PropTypes.any, // The password generator context
259
261
  history: PropTypes.any, // The history router
260
262
  t: PropTypes.func, // The translation function
@@ -2,8 +2,12 @@
2
2
  * Default props
3
3
  * @returns {*}
4
4
  */
5
+
6
+ import {defaultAppContext} from "../../contexts/AppContext.test.data";
7
+
5
8
  export function defaultProps() {
6
9
  return {
10
+ context: defaultAppContext(),
7
11
  prepareResourceContext: {
8
12
  settings: {
9
13
  default_generator: "passphrase",
@@ -5,6 +5,8 @@ import {withAppContext} from "../../contexts/AppContext";
5
5
  import {Trans, withTranslation} from "react-i18next";
6
6
  import Icon from "../../../shared/components/Icons/Icon";
7
7
  import Password from "../../../shared/components/Password/Password";
8
+ import SsoProviders from "../../../react-extension/components/Administration/ManageSsoSettings/SsoProviders.data";
9
+ import {withSso} from "../../contexts/SsoContext";
8
10
 
9
11
  class LoginPage extends React.Component {
10
12
  constructor(props) {
@@ -17,22 +19,35 @@ class LoginPage extends React.Component {
17
19
  initEventHandlers() {
18
20
  this.handleFormSubmit = this.handleFormSubmit.bind(this);
19
21
  this.handleInputChange = this.handleInputChange.bind(this);
22
+ this.handleSwitchToPassphrase = this.handleSwitchToPassphrase.bind(this);
23
+ this.handleSwitchToSso = this.handleSwitchToSso.bind(this);
24
+ this.handleSignInWithSso = this.handleSignInWithSso.bind(this);
20
25
  }
21
26
 
22
27
  initState() {
23
28
  return {
24
29
  error: "",
30
+ ssoError: null,
25
31
  processing: false,
26
32
  passphrase: "",
27
33
  rememberMe: false,
34
+ displaySso: false,
35
+ isSsoAvailable: false,
36
+ isReady: false,
28
37
  };
29
38
  }
30
39
 
31
40
  /**
32
41
  * Whenever the component is mounted
33
42
  */
34
- componentDidMount() {
35
- this.focusOnPassphrase();
43
+ async componentDidMount() {
44
+ await this.props.ssoContext.loadSsoConfiguration();
45
+ if (this.props.ssoContext.hasUserAnSsoKit()) {
46
+ this.setState({isSsoAvailable: true, displaySso: true, isReady: true});
47
+ } else {
48
+ this.setState({isReady: true});
49
+ this.focusOnPassphrase();
50
+ }
36
51
  }
37
52
 
38
53
  /**
@@ -60,8 +75,11 @@ class LoginPage extends React.Component {
60
75
 
61
76
  async login() {
62
77
  await this.props.context.port.request("passbolt.auth.login", this.state.passphrase, this.state.rememberMe);
63
- const isMfaRequired = await this.props.context.port.request("passbolt.auth.is-mfa-required");
78
+ await this.handleLoginSuccess();
79
+ }
64
80
 
81
+ async handleLoginSuccess() {
82
+ const isMfaRequired = await this.props.context.port.request("passbolt.auth.is-mfa-required");
65
83
  if (!isMfaRequired) {
66
84
  this.props.loginSuccessCallback();
67
85
  this.props.history.push("/webAccessibleResources/quickaccess.html");
@@ -80,10 +98,73 @@ class LoginPage extends React.Component {
80
98
  });
81
99
  }
82
100
 
101
+ /**
102
+ * Switches the UI to the SSO mode.
103
+ */
104
+ handleSwitchToSso(event) {
105
+ event.preventDefault();
106
+ this.setState({displaySso: true, ssoError: null});
107
+ }
108
+
109
+ /**
110
+ * Switches the UI to the passphrase mode.
111
+ */
112
+ handleSwitchToPassphrase(event) {
113
+ event.preventDefault();
114
+ this.setState({displaySso: false});
115
+ }
116
+
117
+ /**
118
+ * Handle the click on the SSO login button.
119
+ * @returns {Promise<void>}
120
+ */
121
+ async handleSignInWithSso(event) {
122
+ event.preventDefault();
123
+ this.setState({processing: true, ssoError: ""});
124
+ try {
125
+ await this.props.ssoContext.runSignInProcess();
126
+ await this.handleLoginSuccess();
127
+ } catch (e) {
128
+ if (e.name === "UserClosedSsoPopUpError") {
129
+ this.setState({
130
+ displaySso: false
131
+ });
132
+ } else {
133
+ this.setState({ssoError: e.message});
134
+ }
135
+ }
136
+ this.setState({
137
+ processing: false
138
+ });
139
+ }
140
+
141
+ /**
142
+ * Returns true if SSO is enabled and configured for Azure.
143
+ * @return {bool}
144
+ */
145
+ get isAzureSsoEnabled() {
146
+ const ssoProvider = this.props.ssoContext.getProvider();
147
+ return ssoProvider === "azure";
148
+ }
149
+
150
+ /**
151
+ * Returns the provider information of the current SSO provider configured.
152
+ * @return {object}
153
+ */
154
+ get ssoProviderData() {
155
+ const ssoProvider = this.props.ssoContext.getProvider();
156
+ if (!ssoProvider) {
157
+ return null;
158
+ }
159
+ return SsoProviders.find(provider => provider.id === ssoProvider);
160
+ }
161
+
83
162
  render() {
163
+ const ssoProviderData = this.ssoProviderData;
84
164
  return (
85
165
  <div className="quickaccess-login">
86
166
  <div className="login-form">
167
+ {!this.state.displaySso && this.state.isReady &&
87
168
  <form onSubmit={this.handleFormSubmit}>
88
169
  <div className="form-container">
89
170
  <div className="input text required">
@@ -122,8 +203,37 @@ class LoginPage extends React.Component {
122
203
  <Icon name="spinner"/>
123
204
  }
124
205
  </button>
206
+ {this.state.isSsoAvailable &&
207
+ <a onClick={this.handleSwitchToSso}>
208
+ <Trans>Sign in with Single Sign-On.</Trans>
209
+ </a>
210
+ }
125
211
  </div>
126
212
  </form>
213
+ }
214
+ {this.state.displaySso && this.state.isReady &&
215
+ <>
216
+ <div className="form-actions sso-login-form">
217
+ {this.isAzureSsoEnabled &&
218
+ <a className={`button sso-login-button ${this.state.processing ? "disabled" : ""} ${ssoProviderData.id}`} onClick={this.handleSignInWithSso} disabled={this.state.processing} >
219
+ <span className="provider-logo">
220
+ {ssoProviderData.icon}
221
+ </span>
222
+ {this.props.t(`Sign in with {{providerName}}`, {providerName: ssoProviderData.name})}
223
+ </a>
224
+ }
225
+ <a onClick={this.handleSwitchToPassphrase}>
226
+ <Trans>Sign in with my passphrase.</Trans>
227
+ </a>
228
+ {this.state.ssoError &&
229
+ <div className="error-message">
230
+ <Trans>An error occured during the sign-in via SSO.</Trans><br/>
231
+ {this.state.ssoError}
232
+ </div>
233
+ }
234
+ </div>
235
+ </>
236
+ }
127
237
  </div>
128
238
  </div>
129
239
  );
@@ -132,6 +242,7 @@ class LoginPage extends React.Component {
132
242
 
133
243
  LoginPage.propTypes = {
134
244
  context: PropTypes.any, // The application context
245
+ ssoContext: PropTypes.object, // The SSO context
135
246
  canRememberMe: PropTypes.bool, // True if the remember me flag must be displayed
136
247
  loginSuccessCallback: PropTypes.func,
137
248
  mfaRequiredCallback: PropTypes.func,
@@ -142,4 +253,4 @@ LoginPage.propTypes = {
142
253
  t: PropTypes.func, // The translation function
143
254
  };
144
255
 
145
- export default withAppContext(withRouter(withTranslation('common')(LoginPage)));
256
+ export default withAppContext(withRouter(withSso(withTranslation('common')(LoginPage))));
@@ -18,3 +18,13 @@ export function defaultAppContext(appContext) {
18
18
  };
19
19
  return Object.assign(defaultAppContext, appContext || {});
20
20
  }
21
+
22
+ export function defaultSsoContext(ssoContext) {
23
+ const defaultSsoContext = {
24
+ loadSsoConfiguration: () => Promise.resolve(),
25
+ hasUserAnSsoKit: () => true,
26
+ getProvider: () => "azure",
27
+ runSignInProcess: () => Promise.resolve()
28
+ };
29
+ return Object.assign(defaultSsoContext, ssoContext || {});
30
+ }
@@ -3,7 +3,7 @@ import {MemoryRouter, Route} from "react-router-dom";
3
3
  import PropTypes from "prop-types";
4
4
  import AppContext from "../../contexts/AppContext";
5
5
  import LoginPage from "./LoginPage";
6
- import {defaultAppContext} from "./LoginPage.test.data";
6
+ import {defaultAppContext, defaultSsoContext} from "./LoginPage.test.data";
7
7
 
8
8
  export default {
9
9
  title: 'Components/QuickAccess/Login',
@@ -13,18 +13,21 @@ export default {
13
13
  const Template = ({context, ...args}) =>
14
14
  <AppContext.Provider value={context}>
15
15
  <MemoryRouter initialEntries={['/']}>
16
- <Route component={routerProps => <div className="container quickaccess"><LoginPage {...args} {...routerProps}/></div>}/>
16
+ <Route component={routerProps => <div className="container quickaccess">
17
+ <LoginPage {...args} {...routerProps}/>
18
+ </div>}/>
17
19
  </MemoryRouter>
18
20
  </AppContext.Provider>;
19
21
 
20
22
  Template.propTypes = {
21
23
  context: PropTypes.object,
24
+ ssoContext: PropTypes.object,
22
25
  };
23
26
 
24
-
25
27
  export const Initial = Template.bind({});
26
28
  Initial.args = {
27
29
  context: defaultAppContext(),
30
+ ssoContext: defaultSsoContext({hasUserAnSsoKit: () => false}),
28
31
  loginSuccessCallback: () => {},
29
32
  mfaRequiredCallback: () => {},
30
33
  canRememberMe: true,
@@ -32,3 +35,27 @@ Initial.args = {
32
35
  Initial.parameters = {
33
36
  css: "ext_quickaccess"
34
37
  };
38
+
39
+ export const WithSsoAvailable = Template.bind({});
40
+ WithSsoAvailable.args = {
41
+ context: defaultAppContext(),
42
+ ssoContext: defaultSsoContext(),
43
+ loginSuccessCallback: () => {},
44
+ mfaRequiredCallback: () => {},
45
+ canRememberMe: true,
46
+ };
47
+ WithSsoAvailable.parameters = {
48
+ css: "ext_quickaccess"
49
+ };
50
+
51
+ export const WithSsoLoginError = Template.bind({});
52
+ WithSsoLoginError.args = {
53
+ context: defaultAppContext(),
54
+ ssoContext: defaultSsoContext({runSignInProcess: () => { throw new Error("Unable to decrypt the private key's with the given passphrase"); }}),
55
+ loginSuccessCallback: () => {},
56
+ mfaRequiredCallback: () => {},
57
+ canRememberMe: true,
58
+ };
59
+ WithSsoLoginError.parameters = {
60
+ css: "ext_quickaccess"
61
+ };
@@ -21,16 +21,22 @@ import Icon from "../../../shared/components/Icons/Icon";
21
21
  import Password from "../../../shared/components/Password/Password";
22
22
  import {SecretGenerator} from "../../../shared/lib/SecretGenerator/SecretGenerator";
23
23
  import PasswordComplexity from "../../../shared/components/PasswordComplexity/PasswordComplexity";
24
+ import debounce from "debounce-promise";
25
+ import PownedService from '../../../shared/services/api/secrets/pownedService';
24
26
 
25
27
  class SaveResource extends React.Component {
26
28
  constructor(props) {
27
29
  super(props);
28
30
  this.initEventHandlers();
29
31
  this.state = this.getDefaultState();
32
+ this.isPwndProcessingPromise = null;
33
+ this.evaluatePasswordIsInDictionaryDebounce = debounce(this.evaluatePasswordIsInDictionaryDebounce, 300);
30
34
  }
31
35
 
32
36
  componentDidMount() {
37
+ this.pownedService = new PownedService(this.props.context.port);
33
38
  this.loadPasswordMetaFromTabForm();
39
+ this.evaluatePasswordIsInDictionaryDebounce();
34
40
  }
35
41
 
36
42
  initEventHandlers() {
@@ -53,6 +59,8 @@ class SaveResource extends React.Component {
53
59
  password: "",
54
60
  passwordError: "",
55
61
  passwordEntropy: null,
62
+ isPwnedServiceAvailable: true,
63
+ passwordInDictionary: false
56
64
  };
57
65
  }
58
66
 
@@ -154,6 +162,9 @@ class SaveResource extends React.Component {
154
162
  }
155
163
 
156
164
  handlePasswordChange(event) {
165
+ if (event.target.value.length) {
166
+ this.isPwndProcessingPromise = this.evaluatePasswordIsInDictionaryDebounce();
167
+ }
157
168
  this.loadPassword(event.target.value);
158
169
  }
159
170
 
@@ -172,6 +183,17 @@ class SaveResource extends React.Component {
172
183
  this.setState({password, passwordEntropy});
173
184
  }
174
185
 
186
+ /**
187
+ * Evaluate to check if password is in a dictionary.
188
+ * @return {Promise}
189
+ */
190
+ async evaluatePasswordIsInDictionaryDebounce() {
191
+ if (this.state.isPwnedServiceAvailable) {
192
+ const result = await this.pownedService.evaluateSecret(this.state.password);
193
+ this.setState({isPwnedServiceAvailable: result.isPwnedServiceAvailable, passwordInDictionary: result.inDictionary});
194
+ }
195
+ }
196
+
175
197
  render() {
176
198
  return (
177
199
  <div className="resource-auto-save">
@@ -204,7 +226,10 @@ class SaveResource extends React.Component {
204
226
  }
205
227
  </div>
206
228
  <div className={`input-password-wrapper input required ${this.state.passwordError ? "error" : ""}`}>
207
- <label htmlFor="password"><Trans>Password</Trans></label>
229
+ <label htmlFor="password"><Trans>Password</Trans>
230
+ {(this.state.passwordInDictionary || !this.state.isPwnedServiceAvailable) &&
231
+ <Icon name="exclamation"/>
232
+ }</label>
208
233
  <div className="password-button-inline">
209
234
  <Password name="password" value={this.state.password} preview={true} onChange={this.handlePasswordChange} disabled={this.state.processing}
210
235
  placeholder={this.translate('Password')} id="password" autoComplete="new-password"/>
@@ -213,6 +238,13 @@ class SaveResource extends React.Component {
213
238
  {this.state.passwordError &&
214
239
  <div className="error-message">{this.state.passwordError}</div>
215
240
  }
241
+ {!this.state.isPwnedServiceAvailable &&
242
+ <div className="pwned-password warning-message"><Trans>The pwnedpasswords service is unavailable, your password might be part of an exposed data breach</Trans></div>
243
+ }
244
+ {this.state.passwordInDictionary &&
245
+ <div className="pwned-password warning-message"><Trans>The password is part of an exposed data breach.</Trans></div>
246
+ }
247
+
216
248
  </div>
217
249
  </div>
218
250
  </div>
@@ -26,3 +26,28 @@ export const mockResults = {
26
26
  "passbolt.quickaccess.prepare-autosave": mockTabInfo,
27
27
  "passbolt.resources.create": {}
28
28
  };
29
+
30
+ export function mockExtensionCall(context) {
31
+ context.port = {
32
+ request: function(event, value) {
33
+ return new Promise((resolve, reject) => {
34
+ if (event === "passbolt.quickaccess.prepare-autosave") {
35
+ resolve({
36
+ name: "Passbolt Browser Extension Test",
37
+ uri: "https://passbolt-browser-extension/test",
38
+ username: "passbolt.com",
39
+ secret_clear: "p@ssw0rd00"
40
+ });
41
+ } else if (event === "passbolt.secrets.powned-password") {
42
+ if (value === "hello-world") {
43
+ resolve(3);
44
+ } else if (value === "unavailable") {
45
+ reject();
46
+ } else {
47
+ resolve(0);
48
+ }
49
+ }
50
+ });
51
+ }
52
+ };
53
+ }