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,340 @@
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
+ import React from "react";
15
+ import PropTypes from "prop-types";
16
+ import {withActionFeedback} from "../../../contexts/ActionFeedbackContext";
17
+ import Icon from "../../../../shared/components/Icons/Icon";
18
+ import {withAdministrationWorkspace} from "../../../contexts/AdministrationWorkspaceContext";
19
+ import {Trans, withTranslation} from "react-i18next";
20
+ import Select from "../../Common/Select/Select";
21
+ import DisplayAdministrationSsoActions from "../DisplayAdministrationWorkspaceActions/DisplayAdministrationSsoActions/DisplayAdministrationSsoActions";
22
+ import {withAdminSso} from "../../../contexts/AdminSsoContext";
23
+ import SsoProviders from "./SsoProviders.data";
24
+ import {withAppContext} from "../../../contexts/AppContext";
25
+ import Password from "../../../../shared/components/Password/Password";
26
+
27
+ /**
28
+ * This component displays the SSO administration settings
29
+ */
30
+ class ManageSsoSettings extends React.Component {
31
+ /**
32
+ * Constructor
33
+ * @param {Object} props
34
+ */
35
+ constructor(props) {
36
+ super(props);
37
+ this.state = this.defaultState;
38
+ this.bindCallbacks();
39
+ this.createRefs();
40
+ }
41
+
42
+ /**
43
+ * Get default state
44
+ * @returns {*}
45
+ */
46
+ get defaultState() {
47
+ return {
48
+ loading: true,
49
+ };
50
+ }
51
+
52
+ async componentDidMount() {
53
+ this.props.administrationWorkspaceContext.setDisplayAdministrationWorkspaceAction(DisplayAdministrationSsoActions);
54
+ await this.props.adminSsoContext.loadSsoConfiguration();
55
+ this.setState({
56
+ loading: false
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Bind callbacks methods
62
+ */
63
+ bindCallbacks() {
64
+ this.handleInputChange = this.handleInputChange.bind(this);
65
+ this.handleProviderInputChange = this.handleProviderInputChange.bind(this);
66
+ this.handleSsoSettingToggle = this.handleSsoSettingToggle.bind(this);
67
+ this.handleCopyRedirectUrl = this.handleCopyRedirectUrl.bind(this);
68
+ this.handleFormSubmit = this.handleFormSubmit.bind(this);
69
+ }
70
+
71
+ createRefs() {
72
+ this.datePickerRef = React.createRef();
73
+ }
74
+
75
+ /**
76
+ * Handle form input changes.
77
+ * @params {ReactEvent} The react event
78
+ * @returns {void}
79
+ */
80
+ handleInputChange(event) {
81
+ const target = event.target;
82
+ const value = target.type === "checkbox" ? target.checked : target.value;
83
+ const name = target.name;
84
+ this.props.adminSsoContext.setValue(name, value);
85
+ }
86
+
87
+ /**
88
+ * Handle provider input change.
89
+ */
90
+ handleProviderInputChange(event) {
91
+ this.props.adminSsoContext.changeProvider({
92
+ id: event.target.value
93
+ });
94
+ }
95
+
96
+ /**
97
+ * Handle the SSO settings toggle
98
+ */
99
+ handleSsoSettingToggle() {
100
+ this.props.adminSsoContext.disableSso();
101
+ }
102
+
103
+ /**
104
+ * Handle the copy to clipboard button
105
+ */
106
+ async handleCopyRedirectUrl() {
107
+ await navigator.clipboard.writeText(this.fullRedirectUrl);
108
+ await this.props.actionFeedbackContext.displaySuccess(this.translate("The redirection URL has been copied to the clipboard."));
109
+ }
110
+
111
+ async handleFormSubmit(event) {
112
+ event.preventDefault();
113
+ const context = this.props.adminSsoContext;
114
+ if (!context.hasFormChanged() || !context.validateData()) {
115
+ return;
116
+ }
117
+ await context.saveAndTestConfiguration();
118
+ }
119
+
120
+ /**
121
+ * Should input be disabled? True if state is loading or processing
122
+ * @returns {boolean}
123
+ */
124
+ hasAllInputDisabled() {
125
+ return this.props.adminSsoContext.isProcessing() || this.state.loading;
126
+ }
127
+
128
+ /**
129
+ * Get the supported SSO providers.
130
+ */
131
+ get supportedSsoProviders() {
132
+ const supportedProviders = this.props.adminSsoContext.getProvidersList();
133
+ return supportedProviders.map(provider => ({
134
+ value: provider.id,
135
+ label: provider.name
136
+ }));
137
+ }
138
+
139
+ /**
140
+ * Get the full redirection URL;
141
+ */
142
+ get fullRedirectUrl() {
143
+ const ssoConfig = this.props.adminSsoContext.getSsoConfiguration();
144
+ const trustedDomain = this.props.context.userSettings.getTrustedDomain();
145
+ return `${trustedDomain}${ssoConfig?.data?.redirect_url}`;
146
+ }
147
+
148
+ /**
149
+ * Returns true if the data is loaded.
150
+ * Useful to avoid UI blinking during data loading.
151
+ * @returns {boolean}
152
+ */
153
+ isReady() {
154
+ return this.props.adminSsoContext.isDataReady();
155
+ }
156
+
157
+ /**
158
+ * Get the translate function
159
+ * @returns {function(...[*]=)}
160
+ */
161
+ get translate() {
162
+ return this.props.t;
163
+ }
164
+
165
+ /**
166
+ * Render the component
167
+ * @returns {JSX}
168
+ */
169
+ render() {
170
+ const ssoContext = this.props.adminSsoContext;
171
+ const ssoConfig = ssoContext.getSsoConfiguration();
172
+ const isSsoActivated = ssoContext.isSsoConfigActivated();
173
+ const errors = ssoContext.getErrors();
174
+ return (
175
+ <div className="row">
176
+ <div className="third-party-provider-settings sso-settings col8 main-column">
177
+ <h3>
178
+ <span className="input toggle-switch form-element">
179
+ <input type="checkbox" className="toggle-switch-checkbox checkbox" name="ssoToggle"
180
+ onChange={this.handleSsoSettingToggle} checked={isSsoActivated} disabled={this.hasAllInputDisabled()}
181
+ id="ssoToggle"/>
182
+ <label htmlFor="ssoToggle"><Trans>Single Sign-On</Trans></label>
183
+ </span>
184
+ </h3>
185
+ {this.props.adminSsoContext.hasFormChanged() &&
186
+ <div className="warning message" id="sso-setting-overridden-banner">
187
+ <p>
188
+ <Trans>Warning, Don&apos;t forget to save your settings to apply your modification.</Trans>
189
+ </p>
190
+ </div>
191
+ }
192
+ {this.isReady() && !isSsoActivated &&
193
+ <>
194
+ <h4 className="no-border"><Trans>Select a provider</Trans></h4>
195
+ <div className="provider-list">
196
+ {SsoProviders.map(provider =>
197
+ <div key={provider.id} className={`provider button ${provider.disabled ? "disabled" : ""}`} id={provider.id} onClick={() => this.props.adminSsoContext.changeProvider(provider)}>
198
+ <div className="provider-logo">
199
+ {provider.icon}
200
+ </div>
201
+ <p className="provider-name">{provider.name}<br/>
202
+ {provider.disabled &&
203
+ <Trans>(not yet available)</Trans>
204
+ }
205
+ </p>
206
+ </div>
207
+ )}
208
+ </div>
209
+ </>
210
+ }
211
+ {this.isReady() && isSsoActivated &&
212
+ <form className="form" onSubmit={this.handleFormSubmit}>
213
+ <div className="select-wrapper input">
214
+ <label htmlFor="sso-provider-input"><Trans>Single Sign-On provider</Trans></label>
215
+ <Select id="sso-provider-input" name="provider" items={this.supportedSsoProviders} value={ssoConfig?.provider} onChange={this.handleProviderInputChange}/>
216
+ </div>
217
+ {ssoConfig?.provider === "azure" &&
218
+ <>
219
+ <hr/>
220
+ <div className={`input text required ${this.hasAllInputDisabled() ? 'disabled' : ''}`}>
221
+ <label><Trans>Login URL</Trans></label>
222
+ <input id="sso-azure-url-input" type="text" className="fluid form-element" name="url"
223
+ value={ssoConfig?.data?.url} onChange={this.handleInputChange} placeholder={this.translate("Login URL")}
224
+ disabled={this.hasAllInputDisabled()}/>
225
+ {errors.url &&
226
+ <div className="error-message">{errors.url}</div>
227
+ }
228
+ <p>
229
+ <Trans>The Azure AD authentication endpoint. See <a href="https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-national-cloud#azure-ad-authentication-endpoints" rel="noopener noreferrer" target="_blank">alternatives</a>.</Trans>
230
+ </p>
231
+ </div>
232
+ <div className={`input text input-wrapper ${this.hasAllInputDisabled() ? 'disabled' : ''}`}>
233
+ <label><Trans>Redirect URL</Trans></label>
234
+ <div className="button-inline">
235
+ <input id="sso-redirect-url-input" type="text" className="fluid form-element disabled" name="redirect_url"
236
+ value={this.fullRedirectUrl} placeholder={this.translate("Redirect URL")} readOnly disabled={true}/>
237
+ <a onClick={this.handleCopyRedirectUrl} className="copy-to-clipboard button button-icon">
238
+ <Icon name="copy-to-clipboard"/>
239
+ </a>
240
+ </div>
241
+ <p>
242
+ <Trans>The URL to provide to Azure when registering the application.</Trans>
243
+ </p>
244
+ </div>
245
+ <hr/>
246
+ <div className={`input text required ${this.hasAllInputDisabled() ? 'disabled' : ''}`}>
247
+ <label><Trans>Application (client) ID</Trans></label>
248
+ <input id="sso-azure-client-id-input" type="text" className="fluid form-element" name="client_id"
249
+ value={ssoConfig?.data?.client_id} onChange={this.handleInputChange} placeholder={this.translate("Application (client) ID")}
250
+ disabled={this.hasAllInputDisabled()}/>
251
+ {errors.client_id &&
252
+ <div className="error-message">{errors.client_id}</div>
253
+ }
254
+ <p>
255
+ <Trans>The public identifier for the app in Azure in UUID format.</Trans> <Trans><a href="https://learn.microsoft.com/en-gb/azure/active-directory/develop/quickstart-register-app" rel="noopener noreferrer" target="_blank">Where to find it?</a></Trans>
256
+ </p>
257
+ </div>
258
+ <div className={`input text required ${this.hasAllInputDisabled() ? 'disabled' : ''}`}>
259
+ <label><Trans>Directory (tenant) ID</Trans></label>
260
+ <input id="sso-azure-tenant-id-input" type="text" className="fluid form-element" name="tenant_id"
261
+ value={ssoConfig?.data?.tenant_id} onChange={this.handleInputChange} placeholder={this.translate("Directory ID")}
262
+ disabled={this.hasAllInputDisabled()}/>
263
+ {errors.tenant_id &&
264
+ <div className="error-message">{errors.tenant_id}</div>
265
+ }
266
+ <p>
267
+ <Trans>The Azure Active Directory tenant ID, in UUID format.</Trans> <Trans><a href="https://learn.microsoft.com/en-gb/azure/active-directory/develop/quickstart-create-new-tenant#create-a-new-azure-ad-tenant" rel="noopener noreferrer" target="_blank">Where to find it?</a></Trans>
268
+ </p>
269
+ </div>
270
+ <div className={`input text required ${this.hasAllInputDisabled() ? 'disabled' : ''}`}>
271
+ <label><Trans>Secret</Trans></label>
272
+ <Password
273
+ id="sso-azure-secret-input"
274
+ className="fluid form-element"
275
+ onChange={this.handleInputChange}
276
+ autoComplete="off"
277
+ name="client_secret"
278
+ placeholder={this.translate("Secret")}
279
+ disabled={this.hasAllInputDisabled()}
280
+ value={ssoConfig?.data?.client_secret}
281
+ preview={true}/>
282
+ {errors.client_secret &&
283
+ <div className="error-message">{errors.client_secret}</div>
284
+ }
285
+ <p>
286
+ <Trans>Allows Azure and Passbolt API to securely share information.</Trans> <Trans><a href="https://learn.microsoft.com/en-gb/azure/active-directory/develop/quickstart-register-app#add-a-client-secret" rel="noopener noreferrer" target="_blank">Where to find it?</a></Trans>
287
+ </p>
288
+ </div>
289
+ <div className={`input text date-wrapper required ${this.hasAllInputDisabled() ? 'disabled' : ''}`}>
290
+ <label><Trans>Secret expiry</Trans></label>
291
+ <div className="button-inline">
292
+ <input id="sso-azure-secret-expiry-input" type="date" className={`fluid form-element ${ssoConfig.data.client_secret_expiry ? "" : "empty"}`} name="client_secret_expiry"
293
+ value={ssoConfig?.data?.client_secret_expiry} onChange={this.handleInputChange} disabled={this.hasAllInputDisabled()}/>
294
+ <Icon name="calendar"/>
295
+ </div>
296
+ {errors.client_secret_expiry &&
297
+ <div className="error-message">{errors.client_secret_expiry}</div>
298
+ }
299
+ </div>
300
+ <div className="warning message">
301
+ <Trans><b>Warning</b>: This secret will expire after some time (typically a few months). Make sure you save the expiry date and rotate it on time.</Trans>
302
+ </div>
303
+ </>
304
+ }
305
+ </form>
306
+ }
307
+ </div>
308
+ <div className="col4 last">
309
+ <div className="sidebar-help">
310
+ <h3><Trans>Need some help?</Trans></h3>
311
+ <p><Trans>For more information about SSO, checkout the dedicated page on the help website.</Trans></p>
312
+ <a className="button" href="https://help.passbolt.com/configure/sso" target="_blank" rel="noopener noreferrer">
313
+ <Icon name="document"/>
314
+ <span><Trans>Read the documentation</Trans></span>
315
+ </a>
316
+ </div>
317
+ {ssoConfig?.provider === "azure" &&
318
+ <div className="sidebar-help">
319
+ <h3><Trans>How do I configure a AzureAD SSO?</Trans></h3>
320
+ <a className="button" href="https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/add-application-portal-setup-sso" target="_blank" rel="noopener noreferrer">
321
+ <Icon name="external-link"/>
322
+ <span><Trans>Read the documentation</Trans></span>
323
+ </a>
324
+ </div>
325
+ }
326
+ </div>
327
+ </div>
328
+ );
329
+ }
330
+ }
331
+
332
+ ManageSsoSettings.propTypes = {
333
+ administrationWorkspaceContext: PropTypes.object, // The administration workspace context
334
+ adminSsoContext: PropTypes.object, // The administration sso configuration context
335
+ actionFeedbackContext: PropTypes.any, // The action feedback context
336
+ context: PropTypes.any, // The application context
337
+ t: PropTypes.func, // The translation function
338
+ };
339
+
340
+ export default withAppContext(withActionFeedback(withAdministrationWorkspace(withAdminSso(withTranslation('common')(ManageSsoSettings)))));
@@ -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
+ import {defaultAppContext} from "../../../contexts/ExtAppContext.test.data";
15
+
16
+ /**
17
+ * Default props.
18
+ * @param {Object} props The props to override
19
+ * @returns {object}
20
+ */
21
+ export function defaultProps(data = {}) {
22
+ const defaultProps = {
23
+ context: defaultAppContext(data?.context),
24
+ administrationWorkspaceContext: {
25
+ setDisplayAdministrationWorkspaceAction: jest.fn(),
26
+ resetDisplayAdministrationWorkspaceAction: jest.fn(),
27
+ must: {
28
+ save: jest.fn()
29
+ }
30
+ }
31
+ };
32
+ delete data.context; // Treated in the default
33
+ return Object.assign(defaultProps, data);
34
+ }
35
+
36
+ export function disabledSso(data = {}) {
37
+ const defaultData = {
38
+ provider: null,
39
+ providers: ["azure", "Fake provider"]
40
+ };
41
+ return Object.assign(defaultData, data);
42
+ }
43
+
44
+ export function azureConfiguredSso(data = {}) {
45
+ const defaultData = {
46
+ provider: "azure",
47
+ data: {
48
+ url: "https://login.microsoftonline.com/..",
49
+ tenant_id: "5n6p8r9s-m5n6-6p7q-3k5n-8r9s3k4m5n7q",
50
+ client_id: "f2j3m5n6-c3k4-m5p7-x2j4-y2k4m5n7q8r9",
51
+ client_secret: "u8x!A%D*G-KaPdSgVkYp3s6v9y$B?E..",
52
+ client_secret_expiry: "2022-11-02",
53
+ }
54
+ };
55
+ return disabledSso(Object.assign(defaultData, data));
56
+ }
@@ -0,0 +1,223 @@
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
+ /**
16
+ * Unit tests on ManageSsoSettings in regard of specifications
17
+ */
18
+ import SsoProviders from "./SsoProviders.data";
19
+ import ManageSsoSettingsPage from "./ManageSsoSettings.test.page";
20
+ import {waitFor} from "@testing-library/react";
21
+ import {defaultProps} from "./ManageSsoSettings.test.data";
22
+ import {
23
+ defaultSsoSettings,
24
+ withAzureSsoSettings,
25
+ } from "../../../contexts/AdminSsoContext.test.data";
26
+ import NotifyError from "../../Common/Error/NotifyError/NotifyError";
27
+ import {v4 as uuid} from "uuid";
28
+ import TestSsoSettingsDialog from "../TestSsoSettingsDialog/TestSsoSettingsDialog";
29
+
30
+ beforeEach(() => {
31
+ jest.resetModules();
32
+ });
33
+
34
+ describe("ManageSsoSettings", () => {
35
+ describe("As a signed-in administrator I can enable the SSO organisation settings", () => {
36
+ it('As a signed-in administrator on the administration workspace, I can see the SSO settings populated with the current settings: without settings', async() => {
37
+ expect.assertions(3);
38
+ const props = defaultProps();
39
+ props.context.port.addRequestListener("passbolt.sso.get-current", async() => defaultSsoSettings());
40
+
41
+ const page = new ManageSsoSettingsPage(props);
42
+
43
+ await waitFor(() => {
44
+ if (page.providerButtons.length === 0) {
45
+ throw new Error("Page is not loaded yet");
46
+ }
47
+ });
48
+
49
+ expect(page.exists()).toBeTruthy();
50
+ expect(page.title.textContent).toBe("Single Sign-On");
51
+ expect(page.providerButtons.length).toBe(SsoProviders.length);
52
+ });
53
+
54
+ it('As a signed-in administrator on the administration workspace, I can see the SSO settings populated with the current settings: with Azure settings', async() => {
55
+ expect.assertions(15);
56
+ const settingsData = withAzureSsoSettings();
57
+ const providerDefaultConfig = SsoProviders.find(provider => provider.id === settingsData.provider);
58
+
59
+ const props = defaultProps();
60
+ props.context.port.addRequestListener("passbolt.sso.get-current", async() => settingsData);
61
+
62
+ const exepectedRedirectUrl = `${props.context.userSettings.getTrustedDomain()}${providerDefaultConfig.defaultConfig.redirect_url}`;
63
+
64
+ const page = new ManageSsoSettingsPage(props);
65
+
66
+ await waitFor(() => {
67
+ if (!page.url) {
68
+ throw new Error("Page is not loaded yet");
69
+ }
70
+ });
71
+
72
+ expect(page.exists()).toBeTruthy();
73
+ expect(page.title.textContent).toBe("Single Sign-On");
74
+ expect(page.providerButtons.length).toBe(0);
75
+ expect(page.url).toBeTruthy();
76
+ expect(page.redirect_url).toBeTruthy();
77
+ expect(page.tenant_id).toBeTruthy();
78
+ expect(page.client_id).toBeTruthy();
79
+ expect(page.client_secret).toBeTruthy();
80
+ expect(page.client_secret_expiry).toBeTruthy();
81
+
82
+ expect(page.url.value).toBe(settingsData.data.url);
83
+ expect(page.redirect_url.value).toBe(exepectedRedirectUrl);
84
+ expect(page.tenant_id.value).toBe(settingsData.data.tenant_id);
85
+ expect(page.client_id.value).toBe(settingsData.data.client_id);
86
+ expect(page.client_secret.value).toBe(settingsData.data.client_secret);
87
+ expect(page.client_secret_expiry.value).toBe(settingsData.data.client_secret_expiry);
88
+ });
89
+
90
+ it("As a signed-in administrator on the administration workspace, I can see a dialog with detailed error if the settings can't be read from the server", async() => {
91
+ expect.assertions(1);
92
+ const mockDialogContext = {
93
+ dialogContext: {
94
+ open: jest.fn()
95
+ }
96
+ };
97
+
98
+ const error = new Error("Something went wrong!");
99
+ const props = defaultProps(mockDialogContext);
100
+ props.context.port.addRequestListener("passbolt.sso.get-current", async() => { throw error; });
101
+
102
+ new ManageSsoSettingsPage(props);
103
+
104
+ await waitFor(() => {
105
+ const callCount = mockDialogContext.dialogContext.open.mock.calls.length;
106
+ if (!callCount) {
107
+ throw new Error("Call to dialog has not been done yet");
108
+ }
109
+ });
110
+
111
+ expect(mockDialogContext.dialogContext.open).toHaveBeenCalledWith(NotifyError, {error});
112
+ });
113
+
114
+ it("As an administrator I can disable SSO Settings", async() => {
115
+ expect.assertions(4);
116
+ const settingsData = withAzureSsoSettings();
117
+
118
+ const props = defaultProps();
119
+ props.context.port.addRequestListener("passbolt.sso.get-current", async() => settingsData);
120
+ props.context.port.addRequestListener("passbolt.sso.delete-settings", async settingsId => {
121
+ expect(settingsId).toStrictEqual(settingsData.id);
122
+ });
123
+
124
+ const page = new ManageSsoSettingsPage(props);
125
+
126
+ await waitFor(() => {
127
+ if (!page.url) {
128
+ throw new Error("Page is not loaded yet");
129
+ }
130
+ });
131
+
132
+ await page.toggleSsoSettings();
133
+
134
+ expect(page.toolbarActionsSaveSettingsButton.classList.contains("disabled")).toBeFalsy();
135
+
136
+ await page.saveSettings(() => Boolean(page.deleteConfirmationDialog));
137
+
138
+ expect(page.deleteConfirmationDialog).toBeTruthy();
139
+
140
+ await page.confirmDelete();
141
+
142
+ expect(page.deleteConfirmationDialog).toBeFalsy();
143
+ });
144
+ });
145
+
146
+ describe("As a signed-in administrator I can save the SSO server settings", () => {
147
+ it('As a signed-in administrator when the “Single Sign On” settings have not changed, I cannot trigger the “Save settings” action', async() => {
148
+ expect.assertions(2);
149
+ const settingsData = withAzureSsoSettings();
150
+ const props = defaultProps();
151
+ props.context.port.addRequestListener("passbolt.sso.get-current", async() => settingsData);
152
+
153
+ const page = new ManageSsoSettingsPage(props);
154
+
155
+ await waitFor(() => {
156
+ if (!page.url) {
157
+ throw new Error("Page is not loaded yet");
158
+ }
159
+ });
160
+
161
+ expect(page.toolbarActionsSaveSettingsButton.classList.contains("disabled")).toBeTruthy();
162
+
163
+ await page.setFormWith({
164
+ tenant_id: "tenant id test"
165
+ });
166
+
167
+ expect(page.toolbarActionsSaveSettingsButton.classList.contains("disabled")).toBeFalsy();
168
+ });
169
+
170
+ it('As AD I cannot save the SSO settings before testing them', async() => {
171
+ expect.assertions(2);
172
+ const settingsData = withAzureSsoSettings();
173
+ const mockDialogContext = {
174
+ dialogContext: {
175
+ open: jest.fn()
176
+ }
177
+ };
178
+ const props = defaultProps(mockDialogContext);
179
+
180
+ const formData = {
181
+ url: "https://fakeurl.passbolt.com/",
182
+ client_id: uuid(),
183
+ tenant_id: uuid(),
184
+ client_secret: uuid(),
185
+ client_secret_expiry: "2050-12-31"
186
+ };
187
+
188
+ props.context.port.addRequestListener("passbolt.sso.get-current", async() => settingsData);
189
+ props.context.port.addRequestListener("passbolt.sso.save-draft", async ssoSettings => {
190
+ expect(ssoSettings).toStrictEqual({
191
+ provider: settingsData.provider,
192
+ data: {
193
+ url: formData.url,
194
+ tenant_id: formData.tenant_id,
195
+ client_id: formData.client_id,
196
+ client_secret: formData.client_secret,
197
+ client_secret_expiry: formData.client_secret_expiry,
198
+ },
199
+ });
200
+ return Object.assign({}, settingsData, ssoSettings);
201
+ });
202
+
203
+ const page = new ManageSsoSettingsPage(props);
204
+
205
+ await waitFor(() => {
206
+ if (!page.url) {
207
+ throw new Error("Page is not loaded yet");
208
+ }
209
+ });
210
+
211
+ await page.setFormWith(formData);
212
+
213
+ await page.saveSettings(() => mockDialogContext.dialogContext.open.mock.calls.length > 0);
214
+
215
+ expect(mockDialogContext.dialogContext.open).toHaveBeenCalledWith(TestSsoSettingsDialog, expect.objectContaining({
216
+ provider: SsoProviders.find(provider => provider.id === "azure"),
217
+ configurationId: settingsData.id,
218
+ handleClose: expect.any(Function),
219
+ onSuccessfulSettingsActivation: expect.any(Function),
220
+ }));
221
+ });
222
+ });
223
+ });