diff --git a/CHANGELOG.md b/CHANGELOG.md index baa9ef0af..4442dba80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [2.6.7](https://github.com/wallabag/wallabag/tree/2.6.7) +[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.6...2.6.7) + +### Security fix +* A user can disable her 2FA unintentionally by @kdecherf in https://github.com/wallabag/wallabag/commit/0cfdddc2eb0aee5ffb69bf499d377d75655ba157 + +### Fixes +* Fix deprecated null tag parameter by @Simounet in https://github.com/wallabag/wallabag/pull/6985 +* Full clickable card on mass action by @Simounet in https://github.com/wallabag/wallabag/pull/6991 +* Add tag form submit button always displayed by @Simounet in https://github.com/wallabag/wallabag/pull/6986 + ## [2.6.6](https://github.com/wallabag/wallabag/tree/2.6.6) [Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.5...2.6.6) diff --git a/app/Resources/static/themes/material/css/article.scss b/app/Resources/static/themes/material/css/article.scss index d826dfabe..a3d34d1ad 100644 --- a/app/Resources/static/themes/material/css/article.scss +++ b/app/Resources/static/themes/material/css/article.scss @@ -235,6 +235,12 @@ z-index: 9999; } +.tags-add-form { + display: flex; + align-items: center; + gap: 20px; +} + @media only screen and (max-width: 640px) { .entry-info { margin-bottom: 20px; @@ -258,4 +264,12 @@ #article .entry-info .chip-action { min-width: 40px; } + + .tags-add-form { + display: block; + } + + .tags-add-form-submit { + margin-top: 10px; + } } diff --git a/app/Resources/static/themes/material/css/entries.scss b/app/Resources/static/themes/material/css/entries.scss index b79a201da..0db39d7c0 100644 --- a/app/Resources/static/themes/material/css/entries.scss +++ b/app/Resources/static/themes/material/css/entries.scss @@ -38,25 +38,29 @@ border-radius: 2px 0 0 2px; } -.entry-checkbox { +.card-stacked .entry-checkbox { margin: 10px 15px 10px 5px; +} - .card & { - float: right; - margin-right: 0; - padding: 10px; - } +.card .entry-checkbox { + position: absolute; + display: flex; + padding: 10px; + inset: 0; + justify-content: flex-end; + align-items: start; + background-color: rgb(0 172 193 / 20%); + cursor: pointer; + z-index: 10; } .entries .entry-checkbox-input, .mass-action .entry-checkbox-input { position: relative; - left: 0; width: 20px; min-height: 25px; - height: 100%; - vertical-align: middle; opacity: initial; + cursor: pointer; z-index: 10; } diff --git a/app/config/wallabag.yml b/app/config/wallabag.yml index bd57d6377..7beb915d3 100644 --- a/app/config/wallabag.yml +++ b/app/config/wallabag.yml @@ -1,5 +1,5 @@ wallabag_core: - version: 2.6.6 + version: 2.6.7 paypal_url: "https://liberapay.com/wallabag/donate" languages: en: 'English' diff --git a/composer.lock b/composer.lock index 65db12987..008dbd167 100644 --- a/composer.lock +++ b/composer.lock @@ -4604,16 +4604,16 @@ }, { "name": "j0k3r/graby-site-config", - "version": "1.0.173", + "version": "1.0.177", "source": { "type": "git", "url": "https://github.com/j0k3r/graby-site-config.git", - "reference": "e54353732d257639039d358972e8947b5d7f05d2" + "reference": "cce11a0d0ec6fc06cebda65c340fcfb7c63ce78a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/j0k3r/graby-site-config/zipball/e54353732d257639039d358972e8947b5d7f05d2", - "reference": "e54353732d257639039d358972e8947b5d7f05d2", + "url": "https://api.github.com/repos/j0k3r/graby-site-config/zipball/cce11a0d0ec6fc06cebda65c340fcfb7c63ce78a", + "reference": "cce11a0d0ec6fc06cebda65c340fcfb7c63ce78a", "shasum": "" }, "require": { @@ -4642,9 +4642,9 @@ "description": "Graby site config files", "support": { "issues": "https://github.com/j0k3r/graby-site-config/issues", - "source": "https://github.com/j0k3r/graby-site-config/tree/1.0.173" + "source": "https://github.com/j0k3r/graby-site-config/tree/1.0.177" }, - "time": "2023-08-21T09:46:59+00:00" + "time": "2023-10-01T02:12:17+00:00" }, { "name": "j0k3r/httplug-ssrf-plugin", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d0df52940..392051cfc 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -17,7 +17,7 @@ parameters: - message: "#^Method FOS\\\\UserBundle\\\\Model\\\\UserManagerInterface\\:\\:updateUser\\(\\) invoked with 2 parameters, 1 required\\.$#" - count: 7 + count: 6 path: src/Wallabag/CoreBundle/Controller/ConfigController.php - @@ -74,3 +74,8 @@ parameters: message: "#^Call to an undefined method Wallabag\\\\ImportBundle\\\\Import\\\\ImportInterface\\:\\:setFilepath\\(\\)\\.$#" count: 1 path: src/Wallabag/ImportBundle/Controller/HtmlController.php + + - + message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch()#" + count: 16 + path: src/* diff --git a/phpstan.neon b/phpstan.neon index 6a4823c9b..843528b11 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -14,6 +14,3 @@ parameters: - vendor/bin/.phpunit/phpunit-8.5-0/vendor/autoload.php inferPrivatePropertyTypeFromConstructor: true - - ignoreErrors: - - "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch\\(\\) invoked with 2 parameters, 1 required\\.$#" diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index 65edbb888..49d909e3d 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php @@ -262,10 +262,14 @@ class ConfigController extends AbstractController /** * Disable 2FA using email. * - * @Route("/config/otp/email/disable", name="disable_otp_email") + * @Route("/config/otp/email/disable", name="disable_otp_email", methods={"POST"}) */ - public function disableOtpEmailAction() + public function disableOtpEmailAction(Request $request) { + if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { + throw $this->createAccessDeniedException('Bad CSRF token.'); + } + $user = $this->getUser(); $user->setEmailTwoFactor(false); @@ -282,10 +286,14 @@ class ConfigController extends AbstractController /** * Enable 2FA using email. * - * @Route("/config/otp/email", name="config_otp_email") + * @Route("/config/otp/email", name="config_otp_email", methods={"POST"}) */ - public function otpEmailAction() + public function otpEmailAction(Request $request) { + if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { + throw $this->createAccessDeniedException('Bad CSRF token.'); + } + $user = $this->getUser(); $user->setGoogleAuthenticatorSecret(null); @@ -305,10 +313,14 @@ class ConfigController extends AbstractController /** * Disable 2FA using OTP app. * - * @Route("/config/otp/app/disable", name="disable_otp_app") + * @Route("/config/otp/app/disable", name="disable_otp_app", methods={"POST"}) */ - public function disableOtpAppAction() + public function disableOtpAppAction(Request $request) { + if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { + throw $this->createAccessDeniedException('Bad CSRF token.'); + } + $user = $this->getUser(); $user->setGoogleAuthenticatorSecret(''); @@ -327,10 +339,14 @@ class ConfigController extends AbstractController /** * Enable 2FA using OTP app, user will need to confirm the generated code from the app. * - * @Route("/config/otp/app", name="config_otp_app") + * @Route("/config/otp/app", name="config_otp_app", methods={"POST"}) */ - public function otpAppAction(GoogleAuthenticatorInterface $googleAuthenticator) + public function otpAppAction(Request $request, GoogleAuthenticatorInterface $googleAuthenticator) { + if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { + throw $this->createAccessDeniedException('Bad CSRF token.'); + } + $user = $this->getUser(); $secret = $googleAuthenticator->generateSecret(); @@ -365,8 +381,10 @@ class ConfigController extends AbstractController * Cancelling 2FA using OTP app. * * @Route("/config/otp/app/cancel", name="config_otp_app_cancel") + * + * XXX: commented until we rewrite 2fa with a real two-steps activation */ - public function otpAppCancelAction() + /*public function otpAppCancelAction() { $user = $this->getUser(); $user->setGoogleAuthenticatorSecret(null); @@ -375,15 +393,19 @@ class ConfigController extends AbstractController $this->userManager->updateUser($user, true); return $this->redirect($this->generateUrl('config') . '#set3'); - } + }*/ /** * Validate OTP code. * - * @Route("/config/otp/app/check", name="config_otp_app_check") + * @Route("/config/otp/app/check", name="config_otp_app_check", methods={"POST"}) */ public function otpAppCheckAction(Request $request, GoogleAuthenticatorInterface $googleAuthenticator) { + if (!$this->isCsrfTokenValid('otp', $request->request->get('token'))) { + throw $this->createAccessDeniedException('Bad CSRF token.'); + } + $isValid = $googleAuthenticator->checkCode( $this->getUser(), $request->get('_auth_code') @@ -403,7 +425,12 @@ class ConfigController extends AbstractController 'scheb_two_factor.code_invalid' ); - return $this->redirect($this->generateUrl('config_otp_app')); + $this->addFlash( + 'notice', + 'scheb_two_factor.code_invalid' + ); + + return $this->redirect($this->generateUrl('config') . '#set3'); } /** diff --git a/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php b/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php index c8544e428..eaddb01ff 100644 --- a/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php +++ b/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php @@ -4,7 +4,6 @@ namespace Wallabag\CoreBundle\Form\Type; use FOS\UserBundle\Form\Type\RegistrationFormType; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -23,15 +22,6 @@ class UserInformationType extends AbstractType ->add('email', EmailType::class, [ 'label' => 'config.form_user.email_label', ]) - ->add('emailTwoFactor', CheckboxType::class, [ - 'required' => false, - 'label' => 'config.form_user.emailTwoFactor_label', - ]) - ->add('googleTwoFactor', CheckboxType::class, [ - 'required' => false, - 'label' => 'config.form_user.googleTwoFactor_label', - 'mapped' => false, - ]) ->add('save', SubmitType::class, [ 'label' => 'config.form.save', ]) diff --git a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig index a91b5fad7..34e556505 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig @@ -269,38 +269,66 @@ {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} -
-
-
-
{{ 'config.otp.page_title'|trans }}
- -

{{ 'config.form_user.two_factor_description'|trans }}

- - - - - - - - - - - - - - - - - - - - - - -
{{ 'config.form_user.two_factor.table_method'|trans }}{{ 'config.form_user.two_factor.table_state'|trans }}{{ 'config.form_user.two_factor.table_action'|trans }}
{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}{% if app.user.isEmailTwoFactor %}{{ 'config.form_user.two_factor.state_enabled'|trans }}{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}{{ 'config.form_user.two_factor.action_email'|trans }} {% if app.user.isEmailTwoFactor %}Disable{% endif %}
{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}{% if app.user.isGoogleTwoFactor %}{{ 'config.form_user.two_factor.state_enabled'|trans }}{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}{{ 'config.form_user.two_factor.action_app'|trans }} {% if app.user.isGoogleTwoFactor %}Disable{% endif %}
-
{{ form_widget(form.user._token) }} - + + {{ form_end(form.user) }} + +
+
+
+
{{ 'config.otp.page_title'|trans }}
+ +

{{ 'config.form_user.two_factor_description'|trans }}

+ + + + + + + + + + + + + + + + + + + + + + +
{{ 'config.form_user.two_factor.table_method'|trans }}{{ 'config.form_user.two_factor.table_state'|trans }}{{ 'config.form_user.two_factor.table_action'|trans }}
{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}{% if app.user.isEmailTwoFactor %}{{ 'config.form_user.two_factor.state_enabled'|trans }}{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %} +
+ + + +
+ {% if app.user.isEmailTwoFactor %} +
+ + + +
+ {% endif %} +
{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}{% if app.user.isGoogleTwoFactor %}{{ 'config.form_user.two_factor.state_enabled'|trans }}{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %} +
+ + + +
+ {% if app.user.isGoogleTwoFactor %} +
+ + + +
+ {% endif %} +
+
diff --git a/src/Wallabag/CoreBundle/Resources/views/Config/otp_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/Config/otp_app.html.twig index 3beaf241f..6d5d402b1 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Config/otp_app.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Config/otp_app.html.twig @@ -40,6 +40,7 @@ {% endfor %}
+
@@ -49,9 +50,6 @@
- - {{ 'config.otp.app.cancel'|trans }} -