From 28d19c86e3f33d13d5317859c0b3e1391e987a84 Mon Sep 17 00:00:00 2001 From: Simon Kobyda Date: Mon, 21 Aug 2023 16:36:34 +0200 Subject: [PATCH 1/4] lib: Add show/hide feature to password input field --- pkg/lib/cockpit-components-password.jsx | 40 +++++++++++++++++++++---- test/verify/check-users | 14 +++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/pkg/lib/cockpit-components-password.jsx b/pkg/lib/cockpit-components-password.jsx index 38c7cd6dbf8c..03f552b85857 100644 --- a/pkg/lib/cockpit-components-password.jsx +++ b/pkg/lib/cockpit-components-password.jsx @@ -18,12 +18,14 @@ */ import cockpit from 'cockpit'; import React, { useState } from 'react'; +import { Button } from '@patternfly/react-core/dist/esm/components/Button/index.js'; import { FormGroup, FormHelperText } from "@patternfly/react-core/dist/esm/components/Form/index.js"; +import { InputGroup, InputGroupItem } from '@patternfly/react-core/dist/esm/components/InputGroup/index.js'; import { HelperText, HelperTextItem } from "@patternfly/react-core/dist/esm/components/HelperText/index.js"; import { Popover } from "@patternfly/react-core/dist/esm/components/Popover/index.js"; import { Progress, ProgressMeasureLocation, ProgressSize } from "@patternfly/react-core/dist/esm/components/Progress/index.js"; import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput/index.js"; -import { HelpIcon } from '@patternfly/react-icons'; +import { EyeIcon, EyeSlashIcon, HelpIcon } from '@patternfly/react-icons'; import { FormHelper } from "cockpit-components-form-helper"; @@ -62,6 +64,8 @@ export const PasswordFormFields = ({ const [passwordConfirm, setConfirmPassword] = useState(""); const [passwordStrength, setPasswordStrength] = useState(""); const [passwordMessage, setPasswordMessage] = useState(""); + const [passwordHidden, setPasswordHidden] = useState(true); + const [passwordConfirmHidden, setPasswordConfirmHidden] = useState(true); function onPasswordChanged(value) { setPassword(value); @@ -106,9 +110,21 @@ export const PasswordFormFields = ({ validated={error_password ? "warning" : "default"} id={idPrefix + "-pw1-group"} fieldId={idPrefix + "-pw1"}> - onPasswordChanged(value)} - validated={error_password ? "warning" : "default"} /> + + + onPasswordChanged(value)} + validated={error_password ? "warning" : "default"} /> + + + + +
- { setConfirmPassword(value); change("password_confirm", value) }} /> + + + { setConfirmPassword(value); change("password_confirm", value) }} /> + + + + + } diff --git a/test/verify/check-users b/test/verify/check-users index b0c92dbb443e..3b3288593a31 100755 --- a/test/verify/check-users +++ b/test/verify/check-users @@ -213,6 +213,20 @@ class TestAccounts(testlib.MachineCase): b.set_input_text('#accounts-create-password-pw1', good_password) b.wait_visible("#accounts-create-password-meter.success") + # Test password show/hide functionality + b.wait_visible('#accounts-create-password-pw1[type="password"]') + b.click("#accounts-create-password-pw1-group button[aria-label='Show password']") + b.wait_visible('#accounts-create-password-pw1[type="text"]') + b.click("#accounts-create-password-pw1-group button[aria-label='Hide password']") + b.wait_visible('#accounts-create-password-pw1[type="password"]') + + # Test confirmation password show/hide functionality + b.wait_visible('#accounts-create-password-pw2[type="password"]') + b.click("#accounts-create-password-pw2-group button[aria-label='Show confirmation password']") + b.wait_visible('#accounts-create-password-pw2[type="text"]') + b.click("#accounts-create-password-pw2-group button[aria-label='Hide confirmation password']") + b.wait_visible('#accounts-create-password-pw2[type="password"]') + # wrong password confirmation b.set_input_text('#accounts-create-password-pw2', good_password + 'b') b.click('#accounts-create-dialog button.apply') From ac86485d1a01c377da157b31e7f118d8f0c1842f Mon Sep 17 00:00:00 2001 From: Simon Kobyda Date: Mon, 21 Aug 2023 17:12:58 +0200 Subject: [PATCH 2/4] lib: Change width of password progress --- pkg/lib/cockpit-components-password.jsx | 14 ++++++++------ pkg/lib/cockpit-components-password.scss | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pkg/lib/cockpit-components-password.jsx b/pkg/lib/cockpit-components-password.jsx index 03f552b85857..13827821ea79 100644 --- a/pkg/lib/cockpit-components-password.jsx +++ b/pkg/lib/cockpit-components-password.jsx @@ -96,6 +96,8 @@ export const PasswordFormFields = ({ else variant = "danger"; + let passwordStrengthValue = Number.isInteger(passwordStrength) ? passwordStrength : 0; + return ( <>
+ className={"ct-password-strength-meter " + variant} + title={_("password quality")} + size={ProgressSize.sm} + measureLocation={ProgressMeasureLocation.none} + variant={variant} + value={passwordStrengthValue} />
{passwordMessage}
{error_password && diff --git a/pkg/lib/cockpit-components-password.scss b/pkg/lib/cockpit-components-password.scss index 99f7725621c4..316e938f64c8 100644 --- a/pkg/lib/cockpit-components-password.scss +++ b/pkg/lib/cockpit-components-password.scss @@ -1,5 +1,6 @@ .ct-password-strength-meter { grid-gap: var(--pf-v5-global--spacer--xs); + inline-size: var(--pf-v5-global--spacer--2xl); .pf-v5-c-progress__description, .pf-v5-c-progress__status { display: none; From 1ce5c92fd354fe96141fc685c5b4d03027e81a2e Mon Sep 17 00:00:00 2001 From: Simon Kobyda Date: Mon, 21 Aug 2023 17:14:08 +0200 Subject: [PATCH 3/4] lib: Add minimum progress value --- pkg/lib/cockpit-components-password.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/lib/cockpit-components-password.jsx b/pkg/lib/cockpit-components-password.jsx index 13827821ea79..15cfe30aba65 100644 --- a/pkg/lib/cockpit-components-password.jsx +++ b/pkg/lib/cockpit-components-password.jsx @@ -96,7 +96,9 @@ export const PasswordFormFields = ({ else variant = "danger"; - let passwordStrengthValue = Number.isInteger(passwordStrength) ? passwordStrength : 0; + let passwordStrengthValue = Number.isInteger(passwordStrength) ? Number.parseInt(passwordStrength) : -1; + if (password !== "" && (passwordStrengthValue >= 0 && passwordStrengthValue < 25)) + passwordStrengthValue = 25; return ( <> From 1ade659ff9d409332a1e34775906a6f22a8f079a Mon Sep 17 00:00:00 2001 From: Simon Kobyda Date: Tue, 22 Aug 2023 14:31:14 +0200 Subject: [PATCH 4/4] lib: Show message next to password progress bar --- pkg/lib/cockpit-components-password.jsx | 49 ++++++++++++++++-------- pkg/lib/cockpit-components-password.scss | 3 ++ test/reference | 2 +- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/pkg/lib/cockpit-components-password.jsx b/pkg/lib/cockpit-components-password.jsx index 15cfe30aba65..795d7a2c1c49 100644 --- a/pkg/lib/cockpit-components-password.jsx +++ b/pkg/lib/cockpit-components-password.jsx @@ -30,6 +30,7 @@ import { EyeIcon, EyeSlashIcon, HelpIcon } from '@patternfly/react-icons'; import { FormHelper } from "cockpit-components-form-helper"; import './cockpit-components-password.scss'; +import { Flex, FlexItem } from '@patternfly/react-core'; const _ = cockpit.gettext; @@ -62,7 +63,7 @@ export const PasswordFormFields = ({ }) => { const [password, setPassword] = useState(initial_password || ""); const [passwordConfirm, setConfirmPassword] = useState(""); - const [passwordStrength, setPasswordStrength] = useState(""); + const [passwordStrength, setPasswordStrength] = useState(); const [passwordMessage, setPasswordMessage] = useState(""); const [passwordHidden, setPasswordHidden] = useState(true); const [passwordConfirmHidden, setPasswordConfirmHidden] = useState(true); @@ -81,20 +82,30 @@ export const PasswordFormFields = ({ setPasswordMessage(strength.message); }); } else { - setPasswordStrength(""); + setPasswordStrength(); setPasswordMessage(""); } } let variant; - if (passwordStrength === "") - variant = "default"; - else if (passwordStrength > 66) + let message; + let messageColor; + if (passwordStrength > 66) { variant = "success"; - else if (passwordStrength > 33) + messageColor = "pf-v5-u-success-color-200"; + message = _("Strong password"); + } else if (passwordStrength > 33) { variant = "warning"; - else + messageColor = "pf-v5-u-warning-color-200"; + message = _("Acceptable password"); + } else { variant = "danger"; + messageColor = "pf-v5-u-danger-color-200"; + message = _("Weak password"); + } + + if (!passwordMessage && message) + setPasswordMessage(message); let passwordStrengthValue = Number.isInteger(passwordStrength) ? Number.parseInt(passwordStrength) : -1; if (password !== "" && (passwordStrengthValue >= 0 && passwordStrengthValue < 25)) @@ -129,16 +140,20 @@ export const PasswordFormFields = ({ -
- -
{passwordMessage}
-
+ {passwordStrengthValue >= 0 && + + + + +
{passwordMessage}
+
+
} {error_password && diff --git a/pkg/lib/cockpit-components-password.scss b/pkg/lib/cockpit-components-password.scss index 316e938f64c8..e1d2d449067e 100644 --- a/pkg/lib/cockpit-components-password.scss +++ b/pkg/lib/cockpit-components-password.scss @@ -1,3 +1,6 @@ +@import "global-variables"; +@import "@patternfly/patternfly/utilities/Text/text.scss"; + .ct-password-strength-meter { grid-gap: var(--pf-v5-global--spacer--xs); inline-size: var(--pf-v5-global--spacer--2xl); diff --git a/test/reference b/test/reference index 1a9d33687e9e..45f3107a5d1c 160000 --- a/test/reference +++ b/test/reference @@ -1 +1 @@ -Subproject commit 1a9d33687e9e054ae355716357ec4e436df3e283 +Subproject commit 45f3107a5d1c74dc9d653eda7cb0a68855a12123