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.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 %} | -
{{ '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 %} + | +