From c510f23184ef46ef59673d885503abf58ab322f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=A0pa=C4=8Dek?= Date: Tue, 14 Mar 2023 03:05:08 +0100 Subject: [PATCH 1/4] Raise min new password length to 15 --- site/app/Form/ChangePasswordFormFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/app/Form/ChangePasswordFormFactory.php b/site/app/Form/ChangePasswordFormFactory.php index 2bfda4905..5bcefe457 100644 --- a/site/app/Form/ChangePasswordFormFactory.php +++ b/site/app/Form/ChangePasswordFormFactory.php @@ -30,7 +30,7 @@ public function create(callable $onSuccess): Form ->setRequired('Zadejte prosím současné heslo'); $newPassword = $form->addPassword('newPassword', 'Nové heslo:') ->setRequired('Zadejte prosím nové heslo') - ->addRule($form::MIN_LENGTH, 'Nové heslo musí mít alespoň %d znaků', 6); + ->addRule($form::MIN_LENGTH, 'Nové heslo musí mít alespoň %d znaků', 15); $form->addPassword('newPasswordVerify', 'Nové heslo pro kontrolu:') ->setRequired('Zadejte prosím nové heslo pro kontrolu') ->addRule($form::EQUAL, 'Hesla se neshodují', $newPassword); From be452401ef47ccc672618ac723b83adb46a124ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=A0pa=C4=8Dek?= Date: Tue, 14 Mar 2023 03:14:20 +0100 Subject: [PATCH 2/4] Help password managers understand the username & password form fields --- site/app/Form/ChangePasswordFormFactory.php | 3 +++ site/app/Form/Controls/FormControlsFactory.php | 2 ++ 2 files changed, 5 insertions(+) diff --git a/site/app/Form/ChangePasswordFormFactory.php b/site/app/Form/ChangePasswordFormFactory.php index 5bcefe457..dfcbd54bf 100644 --- a/site/app/Form/ChangePasswordFormFactory.php +++ b/site/app/Form/ChangePasswordFormFactory.php @@ -27,11 +27,14 @@ public function create(callable $onSuccess): Form { $form = $this->factory->create(); $form->addPassword('password', 'Současné heslo:') + ->setHtmlAttribute('autocomplete', 'current-password') ->setRequired('Zadejte prosím současné heslo'); $newPassword = $form->addPassword('newPassword', 'Nové heslo:') + ->setHtmlAttribute('autocomplete', 'new-password') ->setRequired('Zadejte prosím nové heslo') ->addRule($form::MIN_LENGTH, 'Nové heslo musí mít alespoň %d znaků', 15); $form->addPassword('newPasswordVerify', 'Nové heslo pro kontrolu:') + ->setHtmlAttribute('autocomplete', 'new-password') ->setRequired('Zadejte prosím nové heslo pro kontrolu') ->addRule($form::EQUAL, 'Hesla se neshodují', $newPassword); $form->addSubmit('save', 'Uložit'); diff --git a/site/app/Form/Controls/FormControlsFactory.php b/site/app/Form/Controls/FormControlsFactory.php index b5377a264..3d974ff90 100644 --- a/site/app/Form/Controls/FormControlsFactory.php +++ b/site/app/Form/Controls/FormControlsFactory.php @@ -11,8 +11,10 @@ class FormControlsFactory public function addSignIn(Container $container): void { $container->addText('username', 'Uživatel:') + ->setHtmlAttribute('autocomplete', 'username') ->setRequired('Zadejte prosím uživatele'); $container->addPassword('password', 'Heslo:') + ->setHtmlAttribute('autocomplete', 'current-password') ->setRequired('Zadejte prosím heslo'); $container->addCheckbox('remember', 'Zůstat přihlášen'); $container->addSubmit('signin', 'Přihlásit'); From 69adf277d465ef8d22a399506316f08ed011f88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=A0pa=C4=8Dek?= Date: Tue, 14 Mar 2023 03:45:47 +0100 Subject: [PATCH 3/4] Indicate which account is the password being changed for --- site/app/Form/ChangePasswordFormFactory.php | 6 +++++ .../IdentityNotSimpleIdentityException.php | 22 +++++++++++++++++++ site/app/User/Manager.php | 19 +++++++++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 site/app/User/Exceptions/IdentityNotSimpleIdentityException.php diff --git a/site/app/Form/ChangePasswordFormFactory.php b/site/app/Form/ChangePasswordFormFactory.php index dfcbd54bf..4d5978397 100644 --- a/site/app/Form/ChangePasswordFormFactory.php +++ b/site/app/Form/ChangePasswordFormFactory.php @@ -3,6 +3,7 @@ namespace MichalSpacekCz\Form; +use MichalSpacekCz\User\Exceptions\IdentityNotSimpleIdentityException; use MichalSpacekCz\User\Manager; use Nette\Application\UI\Form; use Nette\Security\User; @@ -22,10 +23,15 @@ public function __construct( /** * @param callable(): void $onSuccess * @return Form + * @throws IdentityNotSimpleIdentityException */ public function create(callable $onSuccess): Form { $form = $this->factory->create(); + $form->addText('username') + ->setDefaultValue($this->authenticator->getIdentityByUser($this->user)->username) + ->setHtmlAttribute('autocomplete', 'username') + ->setHtmlAttribute('class', 'hidden'); $form->addPassword('password', 'Současné heslo:') ->setHtmlAttribute('autocomplete', 'current-password') ->setRequired('Zadejte prosím současné heslo'); diff --git a/site/app/User/Exceptions/IdentityNotSimpleIdentityException.php b/site/app/User/Exceptions/IdentityNotSimpleIdentityException.php new file mode 100644 index 000000000..fef1dc0da --- /dev/null +++ b/site/app/User/Exceptions/IdentityNotSimpleIdentityException.php @@ -0,0 +1,22 @@ +' : $identity::class, SimpleIdentity::class), + previous: $previous, + ); + } + +} diff --git a/site/app/User/Manager.php b/site/app/User/Manager.php index b2f46fbc4..e9a86f60c 100644 --- a/site/app/User/Manager.php +++ b/site/app/User/Manager.php @@ -5,6 +5,7 @@ use DateTimeInterface; use Exception; +use MichalSpacekCz\User\Exceptions\IdentityNotSimpleIdentityException; use Nette\Application\LinkGenerator; use Nette\Database\Explorer; use Nette\Database\Row; @@ -79,6 +80,19 @@ public function getIdentity(int $id, string $username): SimpleIdentity } + /** + * @throws IdentityNotSimpleIdentityException + */ + public function getIdentityByUser(User $user): SimpleIdentity + { + $identity = $user->getIdentity(); + if (!$identity instanceof SimpleIdentity) { + throw new IdentityNotSimpleIdentityException($identity); + } + return $identity; + } + + /** * @param string $username * @param string $password @@ -123,12 +137,11 @@ private function verifyPassword(string $username, string $password): int * @param string $newPassword * @throws AuthenticationException * @throws HaliteAlert + * @throws IdentityNotSimpleIdentityException */ public function changePassword(User $user, string $password, string $newPassword): void { - /** @var SimpleIdentity $identity */ - $identity = $user->getIdentity(); - $this->verifyPassword($identity->username, $password); + $this->verifyPassword($this->getIdentityByUser($user)->username, $password); $this->updatePassword($user->getId(), $newPassword); $this->clearPermanentLogin($user); } From 1eac78fd35d1539b0b38a29b89ee7ae0ae024a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=A0pa=C4=8Dek?= Date: Tue, 14 Mar 2023 03:58:47 +0100 Subject: [PATCH 4/4] Tell 1Password to generate a bit longer and stronger password by default --- site/app/Form/ChangePasswordFormFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/site/app/Form/ChangePasswordFormFactory.php b/site/app/Form/ChangePasswordFormFactory.php index 4d5978397..ee32691c2 100644 --- a/site/app/Form/ChangePasswordFormFactory.php +++ b/site/app/Form/ChangePasswordFormFactory.php @@ -30,6 +30,7 @@ public function create(callable $onSuccess): Form $form = $this->factory->create(); $form->addText('username') ->setDefaultValue($this->authenticator->getIdentityByUser($this->user)->username) + ->setHtmlAttribute('passwordrules', 'minlength: 42; required: lower; required: upper; required: digit; required: [ !#$%&*+,./:;=?@_~];') ->setHtmlAttribute('autocomplete', 'username') ->setHtmlAttribute('class', 'hidden'); $form->addPassword('password', 'Současné heslo:')