From 64abd3164b25ab28c77c54dda89c23d2b58c34af Mon Sep 17 00:00:00 2001 From: Bob den Otter Date: Mon, 8 Nov 2021 14:10:24 +0100 Subject: [PATCH 1/2] Enable 'Remember me' by default, and make duration configurable --- config/packages/security.yaml | 2 +- config/services.yaml | 3 +++ translations/messages.en.xlf | 6 ++++++ translations/messages.nl.xlf | 6 +++--- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 05c4ef35d..ac22b20ce 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -38,7 +38,7 @@ security: remember_me: secret: '%kernel.secret%' - lifetime: 2592000 + lifetime: '%bolt.remember_lifetime%' remember_me_parameter: login[remember_me] access_control: diff --git a/config/services.yaml b/config/services.yaml index 3737e296a..a97fe8399 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -12,6 +12,7 @@ parameters: # default: bolt_ # foo_manager: foo_ bolt.backend_url: /bolt + bolt.remember_lifetime: 2592000 # 30 days in seconds services: # default configuration for services in *this* file @@ -28,6 +29,8 @@ services: $projectDir: '%kernel.project_dir%' $publicFolder: '%bolt.public_folder%' $tablePrefix: '%bolt.table_prefix%' + $rememberLifetime: '%bolt.remember_lifetime%' + _instanceof: Bolt\Menu\ExtensionBackendMenuInterface: tags: [ 'bolt.extension_backend_menu' ] diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index 40ab8119b..020690fda 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -2673,5 +2673,11 @@ Select all + + + label.remembermeduration + Remember me? (%duration% days) + + diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf index 49b3808ee..ce8815194 100644 --- a/translations/messages.nl.xlf +++ b/translations/messages.nl.xlf @@ -181,13 +181,13 @@ Copyright - + templates/security/login.twig:80 - label.rememberme - Onthoud me? + label.remembermeduration + Onthoud me? (%duration% dagen) From 5eb16381b8ada2be861eece07768d0d795af06e0 Mon Sep 17 00:00:00 2001 From: Bob den Otter Date: Mon, 8 Nov 2021 14:10:38 +0100 Subject: [PATCH 2/2] Update LoginType.php --- src/Form/LoginType.php | 147 +++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 64 deletions(-) diff --git a/src/Form/LoginType.php b/src/Form/LoginType.php index f467c94cf..352d8777a 100644 --- a/src/Form/LoginType.php +++ b/src/Form/LoginType.php @@ -1,77 +1,96 @@ authenticationUtils = $authenticationUtils; - $this->translator = $translator; - } + /** @var int */ + private $rememberLifetime; - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $builder - ->add('username', TextType::class, [ - 'label' => 'label.username_or_email', - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans('form.empty_username_email'), - ]), - ], - 'attr' => [ - 'placeholder' => 'placeholder.username_or_email', - ], - 'data' => $this->authenticationUtils->getLastUsername(), - ]) - ->add('password', PasswordWithPreviewType::class, [ - 'label' => 'label.password', - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans('form.empty_password'), - ]), - ], - // do not show the * red star - 'required' => false, - 'attr' => [ - 'placeholder' => 'placeholder.password', - ], - ])->add('remember_me', CheckboxType::class, [ - 'label' => 'label.rememberme', - 'required' => false, - ]); - } + public function __construct(AuthenticationUtils $authenticationUtils, TranslatorInterface $translator, int $rememberLifetime = 2592000) + { + $this->authenticationUtils = $authenticationUtils; + $this->translator = $translator; + + // Defaults to 2592000, 30 days in seconds + $this->rememberLifetime = $rememberLifetime; + } - // https://symfony.com/doc/current/security/csrf.html#csrf-protection-in-symfony-forms - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([ - // enable/disable CSRF protection for this form - 'csrf_protection' => true, - // the name of the hidden HTML field that stores the token - 'csrf_field_name' => '_token', - // an arbitrary string used to generate the value of the token - // using a different string for each form improves its security - 'csrf_token_id' => 'login_csrf_token', + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder + ->add('username', TextType::class, [ + 'label' => 'label.username_or_email', + 'constraints' => [ + new NotBlank([ + 'message' => $this->translator->trans('form.empty_username_email'), + ]), + ], + 'attr' => [ + 'placeholder' => 'placeholder.username_or_email', + ], + 'data' => $this->authenticationUtils->getLastUsername(), + ]) + ->add('password', PasswordWithPreviewType::class, [ + 'label' => 'label.password', + 'constraints' => [ + new NotBlank([ + 'message' => $this->translator->trans('form.empty_password'), + ]), + ], + // do not show the * red star + 'required' => false, + 'attr' => [ + 'placeholder' => 'placeholder.password', + ], + ]); + + if ($this->rememberLifetime > 0) { + $builder->add('remember_me', CheckboxType::class, [ + 'label' => 'label.remembermeduration', + 'label_translation_parameters' => [ + '%duration%' => 0 + sprintf('%0.1f', $this->rememberLifetime / 3600 / 24), + ], + 'required' => false, + 'attr' => [ + 'checked' => 'checked', + ], ]); + } else { + $builder->add('remember_me', HiddenType::class); } } + + // https://symfony.com/doc/current/security/csrf.html#csrf-protection-in-symfony-forms + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + // enable/disable CSRF protection for this form + 'csrf_protection' => true, + // the name of the hidden HTML field that stores the token + 'csrf_field_name' => '_token', + // an arbitrary string used to generate the value of the token + // using a different string for each form improves its security + 'csrf_token_id' => 'login_csrf_token', + ]); + } +}