diff --git a/composer.json b/composer.json
index 73559675ead0e8fad071ce439677238a0bb691e7..9a02a3b75ad2133b0d9575a571c54fcfcba46f32 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
     "ext-json": "*"
   },
   "require-dev": {
-    "symplify/easy-coding-standard": "^10.0"
+    "symplify/easy-coding-standard": "^11.1"
   },
   "config": {
     "allow-plugins": {
diff --git a/composer.lock b/composer.lock
index 92c3e32baf25a0f57ef2fbbec7b7e3f631942a15..ea647c5dbf00c43d46bb33e742928df590d2c413 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,20 +4,20 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "8547df7281d9bbb0e01210119c97bfd6",
+    "content-hash": "a39b38757e10b0fb7fd22902b1f7c5c8",
     "packages": [
         {
             "name": "cesnet/privacyidea-php-client",
-            "version": "v1.0.0",
+            "version": "v1.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/CESNET/php-client.git",
-                "reference": "e820b3f414bb13c779e3057a283ab9de6dd05a88"
+                "reference": "5e87d0be43be09a589fef1b625c194e75dbbb980"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/CESNET/php-client/zipball/e820b3f414bb13c779e3057a283ab9de6dd05a88",
-                "reference": "e820b3f414bb13c779e3057a283ab9de6dd05a88",
+                "url": "https://api.github.com/repos/CESNET/php-client/zipball/5e87d0be43be09a589fef1b625c194e75dbbb980",
+                "reference": "5e87d0be43be09a589fef1b625c194e75dbbb980",
                 "shasum": ""
             },
             "require": {
@@ -30,6 +30,7 @@
             },
             "require-dev": {
                 "internations/http-mock": "~0.14.0",
+                "php": "^7.2",
                 "phpunit/phpunit": "^9",
                 "symplify/easy-coding-standard": "^10.0"
             },
@@ -50,22 +51,22 @@
             ],
             "support": {
                 "issues": "https://github.com/CESNET/php-client/issues",
-                "source": "https://github.com/CESNET/php-client/tree/v1.0.0"
+                "source": "https://github.com/CESNET/php-client/tree/v1.2.0"
             },
-            "time": "2022-03-21T14:47:07+00:00"
+            "time": "2022-05-04T09:47:54+00:00"
         },
         {
             "name": "gettext/gettext",
-            "version": "v4.8.6",
+            "version": "v4.8.7",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-gettext/Gettext.git",
-                "reference": "bbeb8f4d3077663739aecb4551b22e720c0e9efe"
+                "reference": "3f7bc5ef23302a9059e64934f3d59e454516bec0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/bbeb8f4d3077663739aecb4551b22e720c0e9efe",
-                "reference": "bbeb8f4d3077663739aecb4551b22e720c0e9efe",
+                "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/3f7bc5ef23302a9059e64934f3d59e454516bec0",
+                "reference": "3f7bc5ef23302a9059e64934f3d59e454516bec0",
                 "shasum": ""
             },
             "require": {
@@ -117,7 +118,7 @@
             "support": {
                 "email": "oom@oscarotero.com",
                 "issues": "https://github.com/oscarotero/Gettext/issues",
-                "source": "https://github.com/php-gettext/Gettext/tree/v4.8.6"
+                "source": "https://github.com/php-gettext/Gettext/tree/v4.8.7"
             },
             "funding": [
                 {
@@ -133,7 +134,7 @@
                     "type": "patreon"
                 }
             ],
-            "time": "2021-10-19T10:44:53+00:00"
+            "time": "2022-08-02T09:42:10+00:00"
         },
         {
             "name": "gettext/languages",
@@ -287,16 +288,16 @@
         },
         {
             "name": "phpmailer/phpmailer",
-            "version": "v6.6.0",
+            "version": "v6.6.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHPMailer/PHPMailer.git",
-                "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1"
+                "reference": "9400f305a898f194caff5521f64e5dfa926626f3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1",
-                "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1",
+                "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/9400f305a898f194caff5521f64e5dfa926626f3",
+                "reference": "9400f305a898f194caff5521f64e5dfa926626f3",
                 "shasum": ""
             },
             "require": {
@@ -308,8 +309,8 @@
             "require-dev": {
                 "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
                 "doctrine/annotations": "^1.2",
-                "php-parallel-lint/php-console-highlighter": "^0.5.0",
-                "php-parallel-lint/php-parallel-lint": "^1.3.1",
+                "php-parallel-lint/php-console-highlighter": "^1.0.0",
+                "php-parallel-lint/php-parallel-lint": "^1.3.2",
                 "phpcompatibility/php-compatibility": "^9.3.5",
                 "roave/security-advisories": "dev-latest",
                 "squizlabs/php_codesniffer": "^3.6.2",
@@ -353,7 +354,7 @@
             "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
             "support": {
                 "issues": "https://github.com/PHPMailer/PHPMailer/issues",
-                "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0"
+                "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.3"
             },
             "funding": [
                 {
@@ -361,7 +362,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-02-28T15:31:21+00:00"
+            "time": "2022-06-20T09:21:02+00:00"
         },
         {
             "name": "psr/cache",
@@ -700,16 +701,16 @@
         },
         {
             "name": "simplesamlphp/saml2",
-            "version": "v4.5.0",
+            "version": "v4.6.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/saml2.git",
-                "reference": "d98020c3d7f7331409959eab286ca3a010e5a868"
+                "reference": "bfc9c79dd6b728a41d1de988f545f6e64728a51d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/d98020c3d7f7331409959eab286ca3a010e5a868",
-                "reference": "d98020c3d7f7331409959eab286ca3a010e5a868",
+                "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/bfc9c79dd6b728a41d1de988f545f6e64728a51d",
+                "reference": "bfc9c79dd6b728a41d1de988f545f6e64728a51d",
                 "shasum": ""
             },
             "require": {
@@ -717,7 +718,7 @@
                 "ext-openssl": "*",
                 "ext-zlib": "*",
                 "php": ">=7.1 || ^8.0",
-                "psr/log": "~1.1",
+                "psr/log": "~1.1 || ^2.0 || ^3.0",
                 "robrichards/xmlseclibs": "^3.1.1",
                 "webmozart/assert": "^1.9"
             },
@@ -752,9 +753,9 @@
             "description": "SAML2 PHP library from SimpleSAMLphp",
             "support": {
                 "issues": "https://github.com/simplesamlphp/saml2/issues",
-                "source": "https://github.com/simplesamlphp/saml2/tree/v4.5.0"
+                "source": "https://github.com/simplesamlphp/saml2/tree/v4.6.3"
             },
-            "time": "2022-02-17T15:46:12+00:00"
+            "time": "2022-06-13T14:04:10+00:00"
         },
         {
             "name": "simplesamlphp/simplesamlphp",
@@ -890,16 +891,16 @@
         },
         {
             "name": "simplesamlphp/simplesamlphp-module-adfs",
-            "version": "v1.0.8",
+            "version": "v1.0.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/simplesamlphp-module-adfs.git",
-                "reference": "4d3d99fb369bee9a9627c00e60fb48bfe4ab3ca0"
+                "reference": "c47daabc262b7e14a76879015fd9db85319752ec"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-adfs/zipball/4d3d99fb369bee9a9627c00e60fb48bfe4ab3ca0",
-                "reference": "4d3d99fb369bee9a9627c00e60fb48bfe4ab3ca0",
+                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-adfs/zipball/c47daabc262b7e14a76879015fd9db85319752ec",
+                "reference": "c47daabc262b7e14a76879015fd9db85319752ec",
                 "shasum": ""
             },
             "require": {
@@ -936,7 +937,7 @@
                 "issues": "https://github.com/simplesamlphp/simplesamlphp-module-adfs/issues",
                 "source": "https://github.com/simplesamlphp/simplesamlphp-module-adfs"
             },
-            "time": "2022-01-24T23:46:31+00:00"
+            "time": "2022-04-11T10:24:25+00:00"
         },
         {
             "name": "simplesamlphp/simplesamlphp-module-authcrypt",
@@ -2397,16 +2398,16 @@
         },
         {
             "name": "symfony/cache",
-            "version": "v5.4.6",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/cache.git",
-                "reference": "c0718d0e01ac14251a45cc9c8b93716ec41ae64b"
+                "reference": "5a0fff46df349f0db3fe242263451fddf5277362"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/cache/zipball/c0718d0e01ac14251a45cc9c8b93716ec41ae64b",
-                "reference": "c0718d0e01ac14251a45cc9c8b93716ec41ae64b",
+                "url": "https://api.github.com/repos/symfony/cache/zipball/5a0fff46df349f0db3fe242263451fddf5277362",
+                "reference": "5a0fff46df349f0db3fe242263451fddf5277362",
                 "shasum": ""
             },
             "require": {
@@ -2474,7 +2475,7 @@
                 "psr6"
             ],
             "support": {
-                "source": "https://github.com/symfony/cache/tree/v5.4.6"
+                "source": "https://github.com/symfony/cache/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -2490,20 +2491,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-02T12:56:28+00:00"
+            "time": "2022-07-28T15:25:17+00:00"
         },
         {
             "name": "symfony/cache-contracts",
-            "version": "v2.5.0",
+            "version": "v2.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/cache-contracts.git",
-                "reference": "ac2e168102a2e06a2624f0379bde94cd5854ced2"
+                "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/ac2e168102a2e06a2624f0379bde94cd5854ced2",
-                "reference": "ac2e168102a2e06a2624f0379bde94cd5854ced2",
+                "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/64be4a7acb83b6f2bf6de9a02cee6dad41277ebc",
+                "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc",
                 "shasum": ""
             },
             "require": {
@@ -2553,7 +2554,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/cache-contracts/tree/v2.5.0"
+                "source": "https://github.com/symfony/cache-contracts/tree/v2.5.2"
             },
             "funding": [
                 {
@@ -2569,20 +2570,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-08-17T14:20:01+00:00"
+            "time": "2022-01-02T09:53:40+00:00"
         },
         {
             "name": "symfony/config",
-            "version": "v5.4.3",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git",
-                "reference": "d65e1bd990c740e31feb07d2b0927b8d4df9956f"
+                "reference": "ec79e03125c1d2477e43dde8528535d90cc78379"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/config/zipball/d65e1bd990c740e31feb07d2b0927b8d4df9956f",
-                "reference": "d65e1bd990c740e31feb07d2b0927b8d4df9956f",
+                "url": "https://api.github.com/repos/symfony/config/zipball/ec79e03125c1d2477e43dde8528535d90cc78379",
+                "reference": "ec79e03125c1d2477e43dde8528535d90cc78379",
                 "shasum": ""
             },
             "require": {
@@ -2632,7 +2633,7 @@
             "description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/config/tree/v5.4.3"
+                "source": "https://github.com/symfony/config/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -2648,20 +2649,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-03T09:50:52+00:00"
+            "time": "2022-07-20T13:00:38+00:00"
         },
         {
             "name": "symfony/console",
-            "version": "v5.4.5",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "d8111acc99876953f52fe16d4c50eb60940d49ad"
+                "reference": "535846c7ee6bc4dd027ca0d93220601456734b10"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/d8111acc99876953f52fe16d4c50eb60940d49ad",
-                "reference": "d8111acc99876953f52fe16d4c50eb60940d49ad",
+                "url": "https://api.github.com/repos/symfony/console/zipball/535846c7ee6bc4dd027ca0d93220601456734b10",
+                "reference": "535846c7ee6bc4dd027ca0d93220601456734b10",
                 "shasum": ""
             },
             "require": {
@@ -2731,7 +2732,7 @@
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v5.4.5"
+                "source": "https://github.com/symfony/console/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -2747,20 +2748,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-02-24T12:45:35+00:00"
+            "time": "2022-07-22T10:42:43+00:00"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v5.4.6",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git",
-                "reference": "0828fa3e6e436243dbb3dc85abe6b698b3876b89"
+                "reference": "a8b9251016e9476db73e25fa836904bc0bf74c62"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0828fa3e6e436243dbb3dc85abe6b698b3876b89",
-                "reference": "0828fa3e6e436243dbb3dc85abe6b698b3876b89",
+                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a8b9251016e9476db73e25fa836904bc0bf74c62",
+                "reference": "a8b9251016e9476db73e25fa836904bc0bf74c62",
                 "shasum": ""
             },
             "require": {
@@ -2820,7 +2821,7 @@
             "description": "Allows you to standardize and centralize the way objects are constructed in your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/dependency-injection/tree/v5.4.6"
+                "source": "https://github.com/symfony/dependency-injection/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -2836,20 +2837,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-02T12:42:23+00:00"
+            "time": "2022-07-20T13:00:38+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
-            "version": "v2.5.0",
+            "version": "v2.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/deprecation-contracts.git",
-                "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8"
+                "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8",
-                "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8",
+                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+                "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
                 "shasum": ""
             },
             "require": {
@@ -2887,7 +2888,7 @@
             "description": "A generic function and convention to trigger deprecation notices",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0"
+                "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2"
             },
             "funding": [
                 {
@@ -2903,20 +2904,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-07-12T14:48:14+00:00"
+            "time": "2022-01-02T09:53:40+00:00"
         },
         {
             "name": "symfony/error-handler",
-            "version": "v5.4.3",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/error-handler.git",
-                "reference": "c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5"
+                "reference": "f75d17cb4769eb38cd5fccbda95cd80a054d35c8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/error-handler/zipball/c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5",
-                "reference": "c4ffc2cd919950d13c8c9ce32a70c70214c3ffc5",
+                "url": "https://api.github.com/repos/symfony/error-handler/zipball/f75d17cb4769eb38cd5fccbda95cd80a054d35c8",
+                "reference": "f75d17cb4769eb38cd5fccbda95cd80a054d35c8",
                 "shasum": ""
             },
             "require": {
@@ -2958,7 +2959,7 @@
             "description": "Provides tools to manage errors and ease debugging PHP code",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/error-handler/tree/v5.4.3"
+                "source": "https://github.com/symfony/error-handler/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -2974,20 +2975,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-07-29T07:37:50+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v5.4.3",
+            "version": "v5.4.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d"
+                "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dec8a9f58d20df252b9cd89f1c6c1530f747685d",
-                "reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc",
+                "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc",
                 "shasum": ""
             },
             "require": {
@@ -3043,7 +3044,7 @@
             "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.3"
+                "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9"
             },
             "funding": [
                 {
@@ -3059,20 +3060,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-05-05T16:45:39+00:00"
         },
         {
             "name": "symfony/event-dispatcher-contracts",
-            "version": "v2.5.0",
+            "version": "v2.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher-contracts.git",
-                "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a"
+                "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a",
-                "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1",
+                "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1",
                 "shasum": ""
             },
             "require": {
@@ -3122,7 +3123,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0"
+                "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.2"
             },
             "funding": [
                 {
@@ -3138,20 +3139,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-07-12T14:48:14+00:00"
+            "time": "2022-01-02T09:53:40+00:00"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v5.4.6",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "d53a45039974952af7f7ebc461ccdd4295e29440"
+                "reference": "6699fb0228d1bc35b12aed6dd5e7455457609ddd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/d53a45039974952af7f7ebc461ccdd4295e29440",
-                "reference": "d53a45039974952af7f7ebc461ccdd4295e29440",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/6699fb0228d1bc35b12aed6dd5e7455457609ddd",
+                "reference": "6699fb0228d1bc35b12aed6dd5e7455457609ddd",
                 "shasum": ""
             },
             "require": {
@@ -3186,7 +3187,7 @@
             "description": "Provides basic utilities for the filesystem",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/filesystem/tree/v5.4.6"
+                "source": "https://github.com/symfony/filesystem/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -3202,20 +3203,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-02T12:42:23+00:00"
+            "time": "2022-07-20T13:00:38+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v5.4.3",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d"
+                "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/231313534dded84c7ecaa79d14bc5da4ccb69b7d",
-                "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c",
+                "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c",
                 "shasum": ""
             },
             "require": {
@@ -3249,7 +3250,7 @@
             "description": "Finds files and directories via an intuitive fluent interface",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/finder/tree/v5.4.3"
+                "source": "https://github.com/symfony/finder/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -3265,20 +3266,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-26T16:34:36+00:00"
+            "time": "2022-07-29T07:37:50+00:00"
         },
         {
             "name": "symfony/framework-bundle",
-            "version": "v5.4.6",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/framework-bundle.git",
-                "reference": "76ea755f30924924ea37a28e098df61679efcb63"
+                "reference": "a0660b602357d5c2ceaac1c9f80c5820bbff803d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/76ea755f30924924ea37a28e098df61679efcb63",
-                "reference": "76ea755f30924924ea37a28e098df61679efcb63",
+                "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/a0660b602357d5c2ceaac1c9f80c5820bbff803d",
+                "reference": "a0660b602357d5c2ceaac1c9f80c5820bbff803d",
                 "shasum": ""
             },
             "require": {
@@ -3332,11 +3333,11 @@
             "require-dev": {
                 "doctrine/annotations": "^1.13.1",
                 "doctrine/cache": "^1.11|^2.0",
-                "doctrine/persistence": "^1.3|^2.0",
+                "doctrine/persistence": "^1.3|^2|^3",
                 "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
                 "symfony/asset": "^5.3|^6.0",
                 "symfony/browser-kit": "^5.4|^6.0",
-                "symfony/console": "^5.4|^6.0",
+                "symfony/console": "^5.4.9|^6.0.9",
                 "symfony/css-selector": "^4.4|^5.0|^6.0",
                 "symfony/dom-crawler": "^4.4.30|^5.3.7|^6.0",
                 "symfony/dotenv": "^5.1|^6.0",
@@ -3348,7 +3349,6 @@
                 "symfony/messenger": "^5.4|^6.0",
                 "symfony/mime": "^4.4|^5.0|^6.0",
                 "symfony/notifier": "^5.4|^6.0",
-                "symfony/phpunit-bridge": "^5.3|^6.0",
                 "symfony/polyfill-intl-icu": "~1.0",
                 "symfony/process": "^4.4|^5.0|^6.0",
                 "symfony/property-info": "^4.4|^5.0|^6.0",
@@ -3401,7 +3401,7 @@
             "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/framework-bundle/tree/v5.4.6"
+                "source": "https://github.com/symfony/framework-bundle/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -3417,20 +3417,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-04T14:13:35+00:00"
+            "time": "2022-07-20T13:00:38+00:00"
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v5.4.6",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "34e89bc147633c0f9dd6caaaf56da3b806a21465"
+                "reference": "0a5868e0999e9d47859ba3d918548ff6943e6389"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/34e89bc147633c0f9dd6caaaf56da3b806a21465",
-                "reference": "34e89bc147633c0f9dd6caaaf56da3b806a21465",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0a5868e0999e9d47859ba3d918548ff6943e6389",
+                "reference": "0a5868e0999e9d47859ba3d918548ff6943e6389",
                 "shasum": ""
             },
             "require": {
@@ -3474,7 +3474,7 @@
             "description": "Defines an object-oriented layer for the HTTP specification",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-foundation/tree/v5.4.6"
+                "source": "https://github.com/symfony/http-foundation/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -3490,20 +3490,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-05T21:03:43+00:00"
+            "time": "2022-07-20T13:00:38+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v5.4.6",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "d41f29ae9af1b5f40c7ebcddf09082953229411d"
+                "reference": "4fd590a2ef3f62560dbbf6cea511995dd77321ee"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d41f29ae9af1b5f40c7ebcddf09082953229411d",
-                "reference": "d41f29ae9af1b5f40c7ebcddf09082953229411d",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4fd590a2ef3f62560dbbf6cea511995dd77321ee",
+                "reference": "4fd590a2ef3f62560dbbf6cea511995dd77321ee",
                 "shasum": ""
             },
             "require": {
@@ -3586,7 +3586,7 @@
             "description": "Provides a structured process for converting a Request into a Response",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-kernel/tree/v5.4.6"
+                "source": "https://github.com/symfony/http-kernel/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -3602,20 +3602,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-05T21:14:51+00:00"
+            "time": "2022-07-29T12:30:22+00:00"
         },
         {
             "name": "symfony/polyfill-ctype",
-            "version": "v1.25.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "30885182c981ab175d4d034db0f6f469898070ab"
+                "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
-                "reference": "30885182c981ab175d4d034db0f6f469898070ab",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
+                "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
                 "shasum": ""
             },
             "require": {
@@ -3630,7 +3630,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -3668,7 +3668,7 @@
                 "portable"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
+                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -3684,20 +3684,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-10-20T20:35:02+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-intl-grapheme",
-            "version": "v1.25.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
-                "reference": "81b86b50cf841a64252b439e738e97f4a34e2783"
+                "reference": "433d05519ce6990bf3530fba6957499d327395c2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783",
-                "reference": "81b86b50cf841a64252b439e738e97f4a34e2783",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2",
+                "reference": "433d05519ce6990bf3530fba6957499d327395c2",
                 "shasum": ""
             },
             "require": {
@@ -3709,7 +3709,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -3749,7 +3749,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0"
+                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -3765,20 +3765,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-23T21:10:46+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-intl-normalizer",
-            "version": "v1.25.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
-                "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
+                "reference": "219aa369ceff116e673852dce47c3a41794c14bd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
-                "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd",
+                "reference": "219aa369ceff116e673852dce47c3a41794c14bd",
                 "shasum": ""
             },
             "require": {
@@ -3790,7 +3790,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -3833,7 +3833,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0"
+                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -3849,20 +3849,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-02-19T12:13:01+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-mbstring",
-            "version": "v1.25.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-mbstring.git",
-                "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
+                "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
-                "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+                "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
                 "shasum": ""
             },
             "require": {
@@ -3877,7 +3877,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -3916,7 +3916,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
+                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -3932,20 +3932,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-30T18:21:41+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-php72",
-            "version": "v1.25.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php72.git",
-                "reference": "9a142215a36a3888e30d0a9eeea9766764e96976"
+                "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976",
-                "reference": "9a142215a36a3888e30d0a9eeea9766764e96976",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
+                "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
                 "shasum": ""
             },
             "require": {
@@ -3954,7 +3954,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -3992,7 +3992,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php72/tree/v1.25.0"
+                "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -4008,20 +4008,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-05-27T09:17:38+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-php73",
-            "version": "v1.25.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php73.git",
-                "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5"
+                "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5",
-                "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5",
+                "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85",
+                "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85",
                 "shasum": ""
             },
             "require": {
@@ -4030,7 +4030,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -4071,7 +4071,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php73/tree/v1.25.0"
+                "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -4087,20 +4087,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-06-05T21:20:04+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/polyfill-php80",
-            "version": "v1.25.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php80.git",
-                "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c"
+                "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c",
-                "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+                "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
                 "shasum": ""
             },
             "require": {
@@ -4109,7 +4109,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -4154,7 +4154,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0"
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -4170,20 +4170,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-04T08:16:47+00:00"
+            "time": "2022-05-10T07:21:04+00:00"
         },
         {
             "name": "symfony/polyfill-php81",
-            "version": "v1.25.0",
+            "version": "v1.26.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-php81.git",
-                "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f"
+                "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
-                "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
+                "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1",
+                "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1",
                 "shasum": ""
             },
             "require": {
@@ -4192,7 +4192,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "1.23-dev"
+                    "dev-main": "1.26-dev"
                 },
                 "thanks": {
                     "name": "symfony/polyfill",
@@ -4233,7 +4233,7 @@
                 "shim"
             ],
             "support": {
-                "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0"
+                "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0"
             },
             "funding": [
                 {
@@ -4249,20 +4249,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-09-13T13:58:11+00:00"
+            "time": "2022-05-24T11:49:31+00:00"
         },
         {
             "name": "symfony/routing",
-            "version": "v5.4.3",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "44b29c7a94e867ccde1da604792f11a469958981"
+                "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/44b29c7a94e867ccde1da604792f11a469958981",
-                "reference": "44b29c7a94e867ccde1da604792f11a469958981",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/3e01ccd9b2a3a4167ba2b3c53612762300300226",
+                "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226",
                 "shasum": ""
             },
             "require": {
@@ -4323,7 +4323,7 @@
                 "url"
             ],
             "support": {
-                "source": "https://github.com/symfony/routing/tree/v5.4.3"
+                "source": "https://github.com/symfony/routing/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -4339,26 +4339,26 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-07-20T13:00:38+00:00"
         },
         {
             "name": "symfony/service-contracts",
-            "version": "v2.5.0",
+            "version": "v2.5.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/service-contracts.git",
-                "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc"
+                "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc",
-                "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+                "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
                 "shasum": ""
             },
             "require": {
                 "php": ">=7.2.5",
                 "psr/container": "^1.1",
-                "symfony/deprecation-contracts": "^2.1"
+                "symfony/deprecation-contracts": "^2.1|^3"
             },
             "conflict": {
                 "ext-psr": "<1.1|>=2"
@@ -4406,7 +4406,7 @@
                 "standards"
             ],
             "support": {
-                "source": "https://github.com/symfony/service-contracts/tree/v2.5.0"
+                "source": "https://github.com/symfony/service-contracts/tree/v2.5.2"
             },
             "funding": [
                 {
@@ -4422,20 +4422,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2021-11-04T16:48:04+00:00"
+            "time": "2022-05-30T19:17:29+00:00"
         },
         {
             "name": "symfony/string",
-            "version": "v5.4.3",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10"
+                "reference": "5eb661e49ad389e4ae2b6e4df8d783a8a6548322"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/92043b7d8383e48104e411bc9434b260dbeb5a10",
-                "reference": "92043b7d8383e48104e411bc9434b260dbeb5a10",
+                "url": "https://api.github.com/repos/symfony/string/zipball/5eb661e49ad389e4ae2b6e4df8d783a8a6548322",
+                "reference": "5eb661e49ad389e4ae2b6e4df8d783a8a6548322",
                 "shasum": ""
             },
             "require": {
@@ -4492,7 +4492,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v5.4.3"
+                "source": "https://github.com/symfony/string/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -4508,20 +4508,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-02T09:53:40+00:00"
+            "time": "2022-07-24T16:15:25+00:00"
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v5.4.6",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "294e9da6e2e0dd404e983daa5aa74253d92c05d0"
+                "reference": "b8f306d7b8ef34fb3db3305be97ba8e088fb4861"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/294e9da6e2e0dd404e983daa5aa74253d92c05d0",
-                "reference": "294e9da6e2e0dd404e983daa5aa74253d92c05d0",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b8f306d7b8ef34fb3db3305be97ba8e088fb4861",
+                "reference": "b8f306d7b8ef34fb3db3305be97ba8e088fb4861",
                 "shasum": ""
             },
             "require": {
@@ -4581,7 +4581,7 @@
                 "dump"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-dumper/tree/v5.4.6"
+                "source": "https://github.com/symfony/var-dumper/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -4597,20 +4597,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-02T12:42:23+00:00"
+            "time": "2022-07-20T13:00:38+00:00"
         },
         {
             "name": "symfony/var-exporter",
-            "version": "v5.4.6",
+            "version": "v5.4.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-exporter.git",
-                "reference": "49e2355fe6f59ea30c18ebb68edf13b7e20582e5"
+                "reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-exporter/zipball/49e2355fe6f59ea30c18ebb68edf13b7e20582e5",
-                "reference": "49e2355fe6f59ea30c18ebb68edf13b7e20582e5",
+                "url": "https://api.github.com/repos/symfony/var-exporter/zipball/8fc03ee75eeece3d9be1ef47d26d79bea1afb340",
+                "reference": "8fc03ee75eeece3d9be1ef47d26d79bea1afb340",
                 "shasum": ""
             },
             "require": {
@@ -4654,7 +4654,7 @@
                 "serialize"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-exporter/tree/v5.4.6"
+                "source": "https://github.com/symfony/var-exporter/tree/v5.4.10"
             },
             "funding": [
                 {
@@ -4670,20 +4670,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-02T12:42:23+00:00"
+            "time": "2022-05-27T12:56:18+00:00"
         },
         {
             "name": "symfony/yaml",
-            "version": "v5.4.3",
+            "version": "v5.4.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "e80f87d2c9495966768310fc531b487ce64237a2"
+                "reference": "05d4ea560f3402c6c116afd99fdc66e60eda227e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/e80f87d2c9495966768310fc531b487ce64237a2",
-                "reference": "e80f87d2c9495966768310fc531b487ce64237a2",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/05d4ea560f3402c6c116afd99fdc66e60eda227e",
+                "reference": "05d4ea560f3402c6c116afd99fdc66e60eda227e",
                 "shasum": ""
             },
             "require": {
@@ -4729,7 +4729,7 @@
             "description": "Loads and dumps YAML files",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/yaml/tree/v5.4.3"
+                "source": "https://github.com/symfony/yaml/tree/v5.4.11"
             },
             "funding": [
                 {
@@ -4745,7 +4745,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-01-26T16:32:32+00:00"
+            "time": "2022-06-27T16:58:25+00:00"
         },
         {
             "name": "twig/extensions",
@@ -4809,16 +4809,16 @@
         },
         {
             "name": "twig/twig",
-            "version": "v2.14.11",
+            "version": "v2.15.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "66baa66f29ee30e487e05f1679903e36eb01d727"
+                "reference": "3e43405a9a8b578809426339cc3780e16fba0c52"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/66baa66f29ee30e487e05f1679903e36eb01d727",
-                "reference": "66baa66f29ee30e487e05f1679903e36eb01d727",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e43405a9a8b578809426339cc3780e16fba0c52",
+                "reference": "3e43405a9a8b578809426339cc3780e16fba0c52",
                 "shasum": ""
             },
             "require": {
@@ -4834,7 +4834,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.14-dev"
+                    "dev-master": "2.15-dev"
                 }
             },
             "autoload": {
@@ -4873,7 +4873,7 @@
             ],
             "support": {
                 "issues": "https://github.com/twigphp/Twig/issues",
-                "source": "https://github.com/twigphp/Twig/tree/v2.14.11"
+                "source": "https://github.com/twigphp/Twig/tree/v2.15.2"
             },
             "funding": [
                 {
@@ -4885,25 +4885,25 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-02-04T06:57:25+00:00"
+            "time": "2022-08-12T06:43:37+00:00"
         },
         {
             "name": "webmozart/assert",
-            "version": "1.10.0",
+            "version": "1.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/webmozarts/assert.git",
-                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
+                "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
-                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
+                "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+                "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.2 || ^8.0",
-                "symfony/polyfill-ctype": "^1.8"
+                "ext-ctype": "*",
+                "php": "^7.2 || ^8.0"
             },
             "conflict": {
                 "phpstan/phpstan": "<0.12.20",
@@ -4941,9 +4941,9 @@
             ],
             "support": {
                 "issues": "https://github.com/webmozarts/assert/issues",
-                "source": "https://github.com/webmozarts/assert/tree/1.10.0"
+                "source": "https://github.com/webmozarts/assert/tree/1.11.0"
             },
-            "time": "2021-03-09T10:59:23+00:00"
+            "time": "2022-06-03T18:03:27+00:00"
         },
         {
             "name": "whitehat101/apr1-md5",
@@ -4997,20 +4997,20 @@
     "packages-dev": [
         {
             "name": "symplify/easy-coding-standard",
-            "version": "10.1.4",
+            "version": "11.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symplify/easy-coding-standard.git",
-                "reference": "3fdbead9da24889727dc11804e9bbfb9d4502d3a"
+                "reference": "0cdd7d2e7868fa2776c8a32cdfe1a8d5055dee05"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/3fdbead9da24889727dc11804e9bbfb9d4502d3a",
-                "reference": "3fdbead9da24889727dc11804e9bbfb9d4502d3a",
+                "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/0cdd7d2e7868fa2776c8a32cdfe1a8d5055dee05",
+                "reference": "0cdd7d2e7868fa2776c8a32cdfe1a8d5055dee05",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": ">=7.2"
             },
             "conflict": {
                 "friendsofphp/php-cs-fixer": "<3.0",
@@ -5022,7 +5022,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-main": "9.5-dev"
+                    "dev-main": "10.3-dev"
                 }
             },
             "autoload": {
@@ -5036,7 +5036,7 @@
             ],
             "description": "Prefixed scoped version of ECS package",
             "support": {
-                "source": "https://github.com/symplify/easy-coding-standard/tree/10.1.4"
+                "source": "https://github.com/symplify/easy-coding-standard/tree/11.1.5"
             },
             "funding": [
                 {
@@ -5048,7 +5048,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2022-03-16T15:18:55+00:00"
+            "time": "2022-08-16T08:53:49+00:00"
         }
     ],
     "aliases": [],
diff --git a/ecs.php b/ecs.php
index 61915a0253a06a3abf41e1c0c3eed62bdd09e933..5493fd6369b0540cc9b43d66b6e71505306c76ff 100644
--- a/ecs.php
+++ b/ecs.php
@@ -2,43 +2,28 @@
 
 declare(strict_types=1);
 
-use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;
 use PhpCsFixer\Fixer\FunctionNotation\FunctionTypehintSpaceFixer;
 use PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer;
-use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
-use Symplify\EasyCodingStandard\ValueObject\Option;
+use Symplify\EasyCodingStandard\Config\ECSConfig;
 use Symplify\EasyCodingStandard\ValueObject\Set\SetList;
 
-return static function (ContainerConfigurator $containerConfigurator): void {
-    $parameters = $containerConfigurator->parameters();
-    $parameters->set(Option::PATHS, [
-        __DIR__ . '/ecs.php',
-        __DIR__ . '/lib',
-        __DIR__ . '/templates',
-        __DIR__ . '/www',
-    ]);
-    $parameters->set(Option::PARALLEL, true);
-    $parameters->set(Option::SKIP, [NotOperatorWithSuccessorSpaceFixer::class, FunctionTypehintSpaceFixer::class]);
+return static function (ECSConfig $ecsConfig): void {
+    $ecsConfig->paths([__DIR__ . '/ecs.php', __DIR__ . '/lib', __DIR__ . '/templates', __DIR__ . '/www']);
 
-    $containerConfigurator->import(SetList::PHP_CS_FIXER);
-    $containerConfigurator->import(SetList::CLEAN_CODE);
-    $containerConfigurator->import(SetList::SYMPLIFY);
-    $containerConfigurator->import(SetList::ARRAY);
-    $containerConfigurator->import(SetList::COMMON);
-    $containerConfigurator->import(SetList::COMMENTS);
-    $containerConfigurator->import(SetList::CONTROL_STRUCTURES);
-    $containerConfigurator->import(SetList::DOCBLOCK);
-    $containerConfigurator->import(SetList::NAMESPACES);
-    $containerConfigurator->import(SetList::PHPUNIT);
-    $containerConfigurator->import(SetList::SPACES);
-    $containerConfigurator->import(SetList::STRICT);
-    $containerConfigurator->import(SetList::SYMFONY);
-    $containerConfigurator->import(SetList::PSR_12);
+    $ecsConfig->sets([
+        SetList::CLEAN_CODE,
+        SetList::SYMPLIFY,
+        SetList::ARRAY,
+        SetList::COMMON,
+        SetList::COMMENTS,
+        SetList::CONTROL_STRUCTURES,
+        SetList::DOCBLOCK,
+        SetList::NAMESPACES,
+        SetList::PHPUNIT,
+        SetList::SPACES,
+        SetList::STRICT,
+        SetList::PSR_12,
+    ]);
 
-    $services = $containerConfigurator->services();
-    $services->set(ArraySyntaxFixer::class)
-        ->call('configure', [[
-            'syntax' => 'short',
-        ]])
-    ;
+    $ecsConfig->skip([NotOperatorWithSuccessorSpaceFixer::class, FunctionTypehintSpaceFixer::class]);
 };
diff --git a/lib/Auth/Process/PrivacyideaAuthProc.php b/lib/Auth/Process/PrivacyideaAuthProc.php
index 4aa449f8682b38b2a554735eb658933c06b25e20..b9cbec4f73594e7f2fe5e159e9792ba5a0c8f887 100644
--- a/lib/Auth/Process/PrivacyideaAuthProc.php
+++ b/lib/Auth/Process/PrivacyideaAuthProc.php
@@ -23,6 +23,7 @@ class PrivacyideaAuthProc extends ProcessingFilter
      * @var array This contains the authproc configuration which is set in metadata
      */
     private $authProcConfig;
+
     /**
      * @var PrivacyIDEA This is an object from privacyIDEA class
      */
@@ -34,11 +35,11 @@ class PrivacyideaAuthProc extends ProcessingFilter
      */
     public function __construct(array $config, $reserved)
     {
-        assert('array' === gettype($config));
+        assert(gettype($config) === 'array');
         parent::__construct($config, $reserved);
         $this->authProcConfig = $config;
         $this->pi = Utils::createPrivacyIDEAInstance($config);
-        if (null === $this->pi) {
+        if ($this->pi === null) {
             throw new ConfigurationError('privacyIDEA: Initialization failed.');
         }
     }
@@ -51,7 +52,7 @@ class PrivacyideaAuthProc extends ProcessingFilter
     public function process(&$state)
     {
         Logger::info('privacyIDEA: Auth Proc Filter - Entering process function.');
-        assert('array' === gettype($state));
+        assert(gettype($state) === 'array');
 
         // Update state before starting the authentication process
         $state['privacyidea:privacyidea'] = $this->authProcConfig;
@@ -71,7 +72,7 @@ class PrivacyideaAuthProc extends ProcessingFilter
 
         // If set to true in config, selectively disable the privacyIDEA authentication using the entityID and/or SAML attributes.
         // The skipping will be done in self::isPrivacyIDEADisabled
-        if (!empty($this->authProcConfig['checkEntityID']) && true === $this->authProcConfig['checkEntityID']) {
+        if (!empty($this->authProcConfig['checkEntityID']) && $this->authProcConfig['checkEntityID'] === true) {
             $stateId = State::saveState($state, 'privacyidea:privacyidea');
             $stateId = $this->checkEntityID($this->authProcConfig, $stateId);
             $state = State::loadState($stateId, 'privacyidea:privacyidea');
@@ -85,7 +86,7 @@ class PrivacyideaAuthProc extends ProcessingFilter
 
         // SSO check if authentication should be skipped
         if (array_key_exists('SSO', $this->authProcConfig)
-            && true === $this->authProcConfig['SSO']) {
+            && $this->authProcConfig['SSO'] === true) {
             if (Utils::checkForValidSSO($state)) {
                 Logger::debug('privacyIDEA: SSO data valid - logging in..');
                 ProcessingChain::resumeProcessing($state);
@@ -97,17 +98,17 @@ class PrivacyideaAuthProc extends ProcessingFilter
         $username = $state['Attributes'][$this->authProcConfig['uidKey']][0];
         $stateId = State::saveState($state, 'privacyidea:privacyidea');
 
-        if (isset($state['isPassive']) && true === $state['isPassive']) {
+        if (isset($state['isPassive']) && $state['isPassive'] === true) {
             throw new NoPassive('Passive multi-factor authentication not supported.');
         }
 
         // Check if it should be controlled that user has no tokens and a new token should be enrolled.
-        if (!empty($this->authProcConfig['doEnrollToken']) && true === $this->authProcConfig['doEnrollToken']) {
+        if (!empty($this->authProcConfig['doEnrollToken']) && $this->authProcConfig['doEnrollToken'] === true) {
             $stateId = $this->enrollToken($stateId, $username);
         }
 
         // Check if triggerChallenge or a call with a static pass to /validate/check should be done
-        if (!empty($this->authProcConfig['doTriggerChallenge']) && true === $this->authProcConfig['doTriggerChallenge']) {
+        if (!empty($this->authProcConfig['doTriggerChallenge']) && $this->authProcConfig['doTriggerChallenge'] === true) {
             // Call /validate/triggerchallenge with the service account from the configuration to trigger all token of the user
             $stateId = State::saveState($state, 'privacyidea:privacyidea');
             if (!$this->pi->serviceAccountAvailable()) {
@@ -122,11 +123,11 @@ class PrivacyideaAuthProc extends ProcessingFilter
                     Utils::handlePrivacyIDEAException($e, $state);
                 }
 
-                if (null !== $response) {
+                if ($response !== null) {
                     $stateId = Utils::processPIResponse($stateId, $response);
                 }
             }
-        } elseif (!empty($this->authProcConfig['tryFirstAuthentication']) && true === $this->authProcConfig['tryFirstAuthentication']) {
+        } elseif (!empty($this->authProcConfig['tryFirstAuthentication']) && $this->authProcConfig['tryFirstAuthentication'] === true) {
             // Call /validate/check with a static pass from the configuration
             // This could already end the authentication with the "passOnNoToken" policy, or it could trigger challenges
             $response = Utils::authenticatePI($state, [
@@ -199,13 +200,13 @@ class PrivacyideaAuthProc extends ProcessingFilter
      */
     private function enrollToken($stateId, $username)
     {
-        assert('string' === gettype($username));
-        assert('string' === gettype($stateId));
+        assert(gettype($username) === 'string');
+        assert(gettype($stateId) === 'string');
 
         $state = State::loadState($stateId, 'privacyidea:privacyidea');
 
         // Error if no serviceAccount or servicePass
-        if (false === $this->pi->serviceAccountAvailable()) {
+        if ($this->pi->serviceAccountAvailable() === false) {
             Logger::error('privacyIDEA: service account for token enrollment is not set!');
         } else {
             $genkey = 1;
@@ -244,7 +245,7 @@ class PrivacyideaAuthProc extends ProcessingFilter
      */
     private function matchIP($clientIP, $excludeClientIPs)
     {
-        assert('string' === gettype($clientIP));
+        assert(gettype($clientIP) === 'string');
         $clientIP = ip2long($clientIP);
 
         $match = false;
@@ -353,7 +354,7 @@ class PrivacyideaAuthProc extends ProcessingFilter
         $retArr = [];
 
         foreach ($reg_arr as $reg) {
-            if ('/' !== $reg[0]) {
+            if ($reg[0] !== '/') {
                 $reg = '/' . $reg . '/';
             }
             Logger::debug('privacyidea:checkEntityID: test regexp ' . $reg . ' against the string ' . $str);
diff --git a/lib/Auth/Source/PrivacyideaAuthSource.php b/lib/Auth/Source/PrivacyideaAuthSource.php
index 6e08b96b647b550814c3fd77ab02edafe60ceba5..d0168a48990e875b1e330d9d222d4654dd3c8e0c 100644
--- a/lib/Auth/Source/PrivacyideaAuthSource.php
+++ b/lib/Auth/Source/PrivacyideaAuthSource.php
@@ -40,8 +40,8 @@ class PrivacyideaAuthSource extends UserPassBase
      */
     public function __construct(array $info, array $config)
     {
-        assert('array' === gettype($info));
-        assert('array' === gettype($config));
+        assert(gettype($info) === 'array');
+        assert(gettype($config) === 'array');
 
         parent::__construct($info, $config);
 
@@ -57,7 +57,7 @@ class PrivacyideaAuthSource extends UserPassBase
 
         $this->authSourceConfig = $config;
         $this->pi = Utils::createPrivacyIDEAInstance($this->authSourceConfig);
-        if (null === $this->pi) {
+        if ($this->pi === null) {
             throw new ConfigurationError('privacyIDEA: Initialization failed.');
         }
     }
@@ -71,12 +71,12 @@ class PrivacyideaAuthSource extends UserPassBase
      */
     public function authenticate(&$state)
     {
-        assert('array' === gettype($state));
+        assert(gettype($state) === 'array');
         Logger::debug('privacyIDEA AuthSource authenticate');
 
         // SSO check if authentication should be skipped
         if (array_key_exists('SSO', $this->authSourceConfig) &&
-            true === $this->authSourceConfig['SSO'] &&
+            $this->authSourceConfig['SSO'] === true &&
             Utils::checkForValidSSO($state)) {
             $session = Session::getSessionFromRequest();
             $attributes = $session->getData('privacyidea:privacyidea', 'attributes');
@@ -121,8 +121,8 @@ class PrivacyideaAuthSource extends UserPassBase
      */
     public static function authSourceLogin($stateId, $formParams)
     {
-        assert('array' === gettype($stateId));
-        assert('array' === gettype($formParams));
+        assert(gettype($stateId) === 'array');
+        assert(gettype($formParams) === 'array');
 
         $state = State::loadState($stateId, 'privacyidea:privacyidea');
         $step = $state['privacyidea:privacyidea:ui']['step'];
@@ -140,12 +140,12 @@ class PrivacyideaAuthSource extends UserPassBase
         }
 
         $response = null;
-        if (1 === $step) {
+        if ($step === 1) {
             $state['privacyidea:privacyidea']['username'] = $username;
             $stateId = State::saveState($state, 'privacyidea:privacyidea');
 
             if (array_key_exists('doTriggerChallenge', $source->authSourceConfig)
-                && true === $source->authSourceConfig['doTriggerChallenge']) {
+                && $source->authSourceConfig['doTriggerChallenge'] === true) {
                 if (!empty($username) && $source->pi->serviceAccountAvailable()) {
                     try {
                         $response = $source->pi->triggerChallenge($username);
@@ -154,7 +154,7 @@ class PrivacyideaAuthSource extends UserPassBase
                     }
                 }
             } elseif (array_key_exists('doSendPassword', $source->authSourceConfig)
-                && true === $source->authSourceConfig['doSendPassword']) {
+                && $source->authSourceConfig['doSendPassword'] === true) {
                 if (!empty($username)) {
                     try {
                         $response = $source->pi->validateCheck($username, $password);
@@ -176,7 +176,7 @@ class PrivacyideaAuthSource extends UserPassBase
             Logger::error('privacyIDEA: UNDEFINED STEP: ' . $step);
         }
 
-        if (null !== $response) {
+        if ($response !== null) {
             $stateId = Utils::processPIResponse($stateId, $response, $source->authSourceConfig);
         }
 
@@ -215,7 +215,7 @@ class PrivacyideaAuthSource extends UserPassBase
             $completeAttributes = self::mergeAttributes($userAttributes, $detailAttributes, $authSourceConfig);
             $state['Attributes'] = $completeAttributes;
 
-            if (array_key_exists('SSO', $authSourceConfig) && true === $authSourceConfig['SSO']) {
+            if (array_key_exists('SSO', $authSourceConfig) && $authSourceConfig['SSO'] === true) {
                 /*
                  * In order to be able to register a logout handler for the session (mandatory for SSO to work),
                  * the authority is required in the session's authData.
@@ -345,7 +345,7 @@ class PrivacyideaAuthSource extends UserPassBase
     private static function checkIdLegality($id)
     {
         $sid = State::parseStateID($id);
-        if (null !== $sid['url']) {
+        if ($sid['url'] !== null) {
             HTTP::checkURLAllowed($sid['url']);
         }
     }
diff --git a/lib/Auth/Utils.php b/lib/Auth/Utils.php
index 4c935fde5e0137c395df5f8a17f64394b4be571a..43ceb5b71baac783774d92409e5e02fcd134402d 100644
--- a/lib/Auth/Utils.php
+++ b/lib/Auth/Utils.php
@@ -24,15 +24,15 @@ class Utils
      */
     public static function authenticatePI(array &$state, array $formParams)
     {
-        assert('array' === gettype($state));
-        assert('array' === gettype($formParams));
+        assert(gettype($state) === 'array');
+        assert(gettype($formParams) === 'array');
 
         Logger::debug("privacyIDEA: Utils::authenticatePI with form data:\n" . http_build_query($formParams, '', ', '));
 
         $state['privacyidea:privacyidea:ui']['mode'] = $formParams['mode'];
 
         // If the mode was changed, do not make any requests
-        if (true === $formParams['modeChanged']) {
+        if ($formParams['modeChanged'] === true) {
             $state['privacyidea:privacyidea:ui']['loadCounter'] = 1;
 
             return null;
@@ -42,7 +42,7 @@ class Utils
 
         // Get the username from elsewhere if it is not in the form
         if (empty($formParams['username'])) {
-            if ('authsource' === $state['privacyidea:privacyidea']['authenticationMethod']) {
+            if ($state['privacyidea:privacyidea']['authenticationMethod'] === 'authsource') {
                 $username = $state['privacyidea:privacyidea']['username'];
             } else {
                 $username = $state['Attributes'][$serverConfig['uidKey']][0];
@@ -52,7 +52,7 @@ class Utils
         }
 
         $pi = self::createPrivacyIDEAInstance($serverConfig);
-        if (null === $pi) {
+        if ($pi === null) {
             throw new \Exception('Unable to initialize privacyIDEA');
         }
 
@@ -63,7 +63,7 @@ class Utils
         }
 
         // Send a request according to the mode
-        if ('push' === $formParams['mode']) {
+        if ($formParams['mode'] === 'push') {
             try {
                 if ($pi->pollTransaction($transactionID)) {
                     // If the authentication has been confirmed on the phone, the authentication has to be finalized with a
@@ -74,7 +74,7 @@ class Utils
             } catch (\Exception $e) {
                 self::handlePrivacyIDEAException($e, $state);
             }
-        } elseif ('u2f' === $formParams['mode']) {
+        } elseif ($formParams['mode'] === 'u2f') {
             $u2fSignResponse = $formParams['u2fSignResponse'];
 
             if (empty($u2fSignResponse)) {
@@ -86,7 +86,7 @@ class Utils
                     self::handlePrivacyIDEAException($e, $state);
                 }
             }
-        } elseif ('webauthn' === $formParams['mode']) {
+        } elseif ($formParams['mode'] === 'webauthn') {
             $origin = $formParams['origin'];
             $webAuthnSignResponse = $formParams['webAuthnSignResponse'];
 
@@ -210,11 +210,11 @@ class Utils
             }
 
             if (array_key_exists('sslVerifyHost', $config) && !empty($config['sslVerifyHost'])) {
-                $pi->sslVerifyHost = false !== $config['sslVerifyHost'];
+                $pi->sslVerifyHost = $config['sslVerifyHost'] !== false;
             }
 
             if (array_key_exists('sslVerifyPeer', $config) && !empty($config['sslVerifyPeer'])) {
-                $pi->sslVerifyPeer = false !== $config['sslVerifyPeer'];
+                $pi->sslVerifyPeer = $config['sslVerifyPeer'] !== false;
             }
 
             if (array_key_exists('serviceAccount', $config) && !empty($config['serviceAccount'])) {
@@ -253,7 +253,7 @@ class Utils
      */
     public static function processPIResponse($stateId, PIResponse $response)
     {
-        assert('string' === gettype($stateId));
+        assert(gettype($stateId) === 'string');
         $state = State::loadState($stateId, 'privacyidea:privacyidea');
 
         $config = $state['privacyidea:privacyidea'];
@@ -263,7 +263,7 @@ class Utils
             // Authentication not complete, new challenges where triggered. Prepare the state for the next step
             $triggeredToken = $response->triggeredTokenTypes();
             // Preferred token type
-            if (null !== $config && array_key_exists('preferredTokenType', $config)) {
+            if ($config !== null && array_key_exists('preferredTokenType', $config)) {
                 $preferred = $config['preferredTokenType'];
                 if (!empty($preferred)) {
                     if (in_array($preferred, $triggeredToken, true)) {
@@ -291,15 +291,15 @@ class Utils
             Logger::debug('privacyIDEA: User authenticated successfully!');
 
             // Complete the authentication depending on method
-            if ('authprocess' === $state['privacyidea:privacyidea']['authenticationMethod']) {
+            if ($state['privacyidea:privacyidea']['authenticationMethod'] === 'authprocess') {
                 // Write data for SSO if enabled
-                if (array_key_exists('SSO', $config) && true === $config['SSO']) {
+                if (array_key_exists('SSO', $config) && $config['SSO'] === true) {
                     self::tryWriteSSO();
                 }
 
                 State::saveState($state, 'privacyidea:privacyidea');
                 ProcessingChain::resumeProcessing($state);
-            } elseif ('authsource' === $state['privacyidea:privacyidea']['authenticationMethod']) {
+            } elseif ($state['privacyidea:privacyidea']['authenticationMethod'] === 'authsource') {
                 // For AuthSource, the attributes required by saml need to be present, so check for that before completing
                 PrivacyideaAuthSource::checkAuthenticationComplete($state, $response, $config);
             }
@@ -343,10 +343,10 @@ class Utils
      */
     public static function checkUidKey(array $config, array $state)
     {
-        assert('array' === gettype($config));
-        assert('array' === gettype($state));
+        assert(gettype($config) === 'array');
+        assert(gettype($state) === 'array');
 
-        if ('array' === gettype($config['uidKey']) && !empty($config['uidKey'])) {
+        if (gettype($config['uidKey']) === 'array' && !empty($config['uidKey'])) {
             foreach ($config['uidKey'] as $i) {
                 if (isset($state['Attributes'][$i][0])) {
                     $config['uidKey'] = $i;
diff --git a/templates/LoginForm.php b/templates/LoginForm.php
index 47ce3cabf0600f4e9a16d2f6bf75a520e7a84131..e247003e98dcf1f96db3e176636777ddb0cf6f9a 100644
--- a/templates/LoginForm.php
+++ b/templates/LoginForm.php
@@ -2,47 +2,8 @@
 
 use SimpleSAML\Module;
 
-$this->data['u2fAvailable'] = !empty($this->data['u2fSignRequest']);
-$this->data['webauthnAvailable'] = !empty($this->data['webAuthnSignRequest']);
-$this->data['mode'] = ($this->data['mode'] ?? null) ?: 'otp';
-$this->data['noAlternatives'] = true;
-foreach (['otp', 'push', 'u2f', 'webauthn'] as $mode) {
-    if ($mode !== $this->data['mode'] && $this->data[$mode . 'Available']) {
-        $this->data['noAlternatives'] = false;
-        break;
-    }
-}
-
-// Set default scenario if isn't set
-if (!empty($this->data['authProcFilterScenario'])) {
-    if (empty($this->data['username'])) {
-        $this->data['username'] = '';
-    }
-} else {
-    $this->data['authProcFilterScenario'] = 0;
-}
-
-// Set the right text shown in otp/pass field(s)
-if (isset($this->data['otpFieldHint'])) {
-    $otpHint = $this->data['otpFieldHint'];
-} else {
-    $otpHint = $this->t('{privacyidea:privacyidea:otp}');
-}
-if (isset($this->data['passFieldHint'])) {
-    $passHint = $this->data['passFieldHint'];
-} else {
-    $passHint = $this->t('{privacyidea:privacyidea:password}');
-}
-
 $this->data['header'] = $this->t('{privacyidea:privacyidea:header}');
 
-// Prepare next settings
-if (!empty($this->data['username'])) {
-    $this->data['autofocus'] = 'password';
-} else {
-    $this->data['autofocus'] = 'username';
-}
-
 $this->data['head'] .= '<link rel="stylesheet" href="'
     . htmlspecialchars(Module::getModuleUrl('privacyidea/css/loginform.css'), ENT_QUOTES)
     . '" media="screen" />';
@@ -50,7 +11,7 @@ $this->data['head'] .= '<link rel="stylesheet" href="'
 $this->includeAtTemplateBase('includes/header.php');
 
 // Prepare error case to show it in UI if needed
-if (null !== $this->data['errorCode']) {
+if ($this->data['errorCode'] !== null) {
     ?>
 
     <div class="error-dialog">
@@ -85,7 +46,7 @@ if (null !== $this->data['errorCode']) {
             } elseif ($this->data['step'] < 2) {
                 echo '<h2>' . htmlspecialchars($this->t('{privacyidea:privacyidea:login_title}')) . '</h2>';
             }
-            ?>
+?>
 
             <form action="FormReceiver.php" method="POST" id="piLoginForm" name="piLoginForm" class="loginForm">
                 <div class="form-panel first valid" id="gaia_firstform">
@@ -93,17 +54,17 @@ if (null !== $this->data['errorCode']) {
                         <div class="input-wrapper focused">
                             <div class="identifier-shown">
                                 <?php
-                                if ($this->data['forceUsername']) {
-                                    if (!empty($this->data['username'])) {
-                                        ?>
+                    if ($this->data['forceUsername']) {
+                        if (!empty($this->data['username'])) {
+                            ?>
                                         <h3><?php echo htmlspecialchars($this->data['username']); ?></h3>
                                     <?php
-                                    } ?>
+                        } ?>
                                     <input type="hidden" id="username" name="username"
                                            value="<?php echo htmlspecialchars($this->data['username'] ?? '', ENT_QUOTES); ?>"/>
                                     <?php
-                                } elseif ($this->data['step'] <= 1) {
-                                    ?>
+                    } elseif ($this->data['step'] <= 1) {
+                        ?>
                                     <p>
                                         <label for="username" class="sr-only">
                                             <?php echo $this->t('{login:username}'); ?>
@@ -114,33 +75,33 @@ if (null !== $this->data['errorCode']) {
                                         />
                                     </p>
                                     <?php
-                                }
-
-                                // Remember username in authproc
-                                if (!$this->data['authProcFilterScenario']) {
-                                    if ($this->data['rememberUsernameEnabled'] || $this->data['rememberMeEnabled']) {
-                                        $rowspan = 1;
-                                    } elseif (array_key_exists('organizations', $this->data)) {
-                                        $rowspan = 3;
-                                    } else {
-                                        $rowspan = 2;
-                                    }
-                                    if ($this->data['rememberUsernameEnabled'] || $this->data['rememberMeEnabled']) {
-                                        if ($this->data['rememberUsernameEnabled']) {
-                                            echo str_repeat("\t", 4);
-                                            echo '<input type="checkbox" id="rememberUsername" tabindex="4" name="rememberUsername"
+                    }
+
+                    // Remember username in authproc
+                    if (!$this->data['authProcFilterScenario']) {
+                        if ($this->data['rememberUsernameEnabled'] || $this->data['rememberMeEnabled']) {
+                            $rowspan = 1;
+                        } elseif (array_key_exists('organizations', $this->data)) {
+                            $rowspan = 3;
+                        } else {
+                            $rowspan = 2;
+                        }
+                        if ($this->data['rememberUsernameEnabled'] || $this->data['rememberMeEnabled']) {
+                            if ($this->data['rememberUsernameEnabled']) {
+                                echo str_repeat("\t", 4);
+                                echo '<input type="checkbox" id="rememberUsername" tabindex="4" name="rememberUsername"
                                          value="Yes" ';
-                                            echo $this->data['rememberUsernameChecked'] ? 'checked="Yes" /> ' : '/> ';
-                                            echo htmlspecialchars($this->t('{login:remember_username}'));
-                                        }
-                                        if ($this->data['rememberMeEnabled']) {
-                                            echo str_repeat("\t", 4);
-                                            echo '<input type="checkbox" id="rememberMe" tabindex="4" name="rememberMe" value="Yes" ';
-                                            echo $this->data['rememberMeChecked'] ? 'checked="Yes" /> ' : '/> ';
-                                            echo htmlspecialchars($this->t('{login:remember_me}'));
-                                        }
-                                    }
-                                } ?>
+                                echo $this->data['rememberUsernameChecked'] ? 'checked="Yes" /> ' : '/> ';
+                                echo htmlspecialchars($this->t('{login:remember_username}'));
+                            }
+                            if ($this->data['rememberMeEnabled']) {
+                                echo str_repeat("\t", 4);
+                                echo '<input type="checkbox" id="rememberMe" tabindex="4" name="rememberMe" value="Yes" ';
+                                echo $this->data['rememberMeChecked'] ? 'checked="Yes" /> ' : '/> ';
+                                echo htmlspecialchars($this->t('{login:remember_me}'));
+                            }
+                        }
+                    } ?>
 
                                 <!-- Pass and OTP fields -->
                                 <?php if (!$this->data['authProcFilterScenario']) { ?>
@@ -148,13 +109,13 @@ if (null !== $this->data['errorCode']) {
                                     <?php echo $this->t('{privacyidea:privacyidea:password}'); ?>
                                 </label>
                                 <input id="password" name="password" tabindex="1" type="password" value="" class="text"
-                                       placeholder="<?php echo htmlspecialchars($passHint, ENT_QUOTES); ?>"/>
+                                       placeholder="<?php echo htmlspecialchars($this->data['passHint'], ENT_QUOTES); ?>"/>
                                 <?php } ?>
 
                                 <?php if ($this->data['step'] > 1) { ?>
                                 <p id="message" role="alert"><?php
-                                    $messageOverride = $this->data['messageOverride'] ?? null;
-                                    if (null === $messageOverride || is_string($messageOverride)) {
+                        $messageOverride = $this->data['messageOverride'] ?? null;
+                                    if ($messageOverride === null || is_string($messageOverride)) {
                                         echo htmlspecialchars(
                                             $messageOverride ?? $this->data['message'] ?? '',
                                             ENT_QUOTES
@@ -162,7 +123,7 @@ if (null !== $this->data['errorCode']) {
                                     } elseif (is_callable($messageOverride)) {
                                         echo call_user_func($messageOverride, $this->data['message'] ?? '');
                                     }
-                                ?></p>
+                                    ?></p>
                                 <?php } ?>
 
                                 <?php if ($this->data['step'] > 1) { ?>
@@ -170,10 +131,10 @@ if (null !== $this->data['errorCode']) {
                                     <label for="otp" class="sr-only">
                                         <?php echo $this->t('{privacyidea:privacyidea:otp}'); ?>
                                     </label>
-                                    <input id="otp" name="otp" type="password" placeholder="<?php echo htmlspecialchars($otpHint, ENT_QUOTES); ?>"
+                                    <input id="otp" name="otp" type="password" placeholder="<?php echo htmlspecialchars($this->data['otpHint'], ENT_QUOTES); ?>"
                                     <?php if (($this->data['otpAvailable'] ?? true) && $this->data['noAlternatives']) {
-                                    echo ' autofocus';
-                                } ?>>
+                                        echo ' autofocus';
+                                    } ?>>
                                 </p>
                                 <?php } ?>
 
@@ -214,15 +175,15 @@ if (null !== $this->data['errorCode']) {
                                        value="<?php echo htmlspecialchars($this->data['message'] ?? '', ENT_QUOTES); ?>"/>
 
                                 <?php
-                                // If enrollToken load QR Code
-                                if (isset($this->data['tokenQR'])) {
-                                    echo htmlspecialchars($this->t('{privacyidea:privacyidea:scan_token_qr}')); ?>
+                                    // If enrollToken load QR Code
+                                    if (isset($this->data['tokenQR'])) {
+                                        echo htmlspecialchars($this->t('{privacyidea:privacyidea:scan_token_qr}')); ?>
                                     <div class="tokenQR">
                                         <?php echo '<img src="' . $this->data['tokenQR'] . '" />'; ?>
                                     </div>
                                     <?php
-                                }
-                                ?>
+                                    }
+?>
                             </div>
 
                             <?php
@@ -267,22 +228,22 @@ if (null !== $this->data['errorCode']) {
                 <div id="AlternateLoginOptions" class="groupMargin hidden js-show">
                     <h3><?php echo $this->t('{privacyidea:privacyidea:alternate_login_options}'); ?></h3>
                     <!-- Alternate Login Options-->
-                    <?php if (($this->data['webauthnAvailable'] ?? false) && 'webauthn' !== $this->data['mode']) { ?>
+                    <?php if (($this->data['webauthnAvailable'] ?? false) && $this->data['mode'] !== 'webauthn') { ?>
                     <button id="useWebAuthnButton" name="useWebAuthnButton" type="button">
                         <span><?php echo $this->t('{privacyidea:privacyidea:webauthn}'); ?></span>
                     </button>
                     <?php } ?>
-                    <?php if (($this->data['pushAvailable'] ?? false) && 'push' !== $this->data['mode']) { ?>
+                    <?php if (($this->data['pushAvailable'] ?? false) && $this->data['mode'] !== 'push') { ?>
                     <button id="usePushButton" name="usePushButton" type="button">
                         <span><?php echo $this->t('{privacyidea:privacyidea:push}'); ?></span>
                     </button>
                     <?php } ?>
-                    <?php if (($this->data['otpAvailable'] ?? true) && 'otp' !== $this->data['mode']) { ?>
+                    <?php if (($this->data['otpAvailable'] ?? true) && $this->data['mode'] !== 'otp') { ?>
                     <button id="useOTPButton" name="useOTPButton" type="button">
                         <span><?php echo $this->t('{privacyidea:privacyidea:otp}'); ?></span>
                     </button>
                     <?php } ?>
-                    <?php if (($this->data['u2fAvailable'] ?? false) && 'u2f' !== $this->data['mode']) { ?>
+                    <?php if (($this->data['u2fAvailable'] ?? false) && $this->data['mode'] !== 'u2f') { ?>
                     <button id="useU2FButton" name="useU2FButton" type="button">
                         <span><?php echo $this->t('{privacyidea:privacyidea:u2f}'); ?></span>
                     </button>
@@ -303,14 +264,14 @@ if (null !== $this->data['errorCode']) {
 
 <?php
 if (!empty($this->data['links'])) {
-                echo '<ul class="links">';
-                foreach ($this->data['links'] as $l) {
-                    echo '<li><a href="' . htmlspecialchars($l['href'], ENT_QUOTES) . '">' . htmlspecialchars(
-                        $this->t($l['text'])
-                    ) . '</a></li>';
-                }
-                echo '</ul>';
-            }
+    echo '<ul class="links">';
+    foreach ($this->data['links'] as $l) {
+        echo '<li><a href="' . htmlspecialchars($l['href'], ENT_QUOTES) . '">' . htmlspecialchars(
+            $this->t($l['text'])
+        ) . '</a></li>';
+    }
+    echo '</ul>';
+}
 ?>
 
     <script src="<?php echo htmlspecialchars(Module::getModuleUrl('privacyidea/js/pi-webauthn.js'), ENT_QUOTES); ?>">
@@ -321,29 +282,7 @@ if (!empty($this->data['links'])) {
 
     <meta id="privacyidea-step" name="privacyidea-step" content="<?php echo $this->data['step']; ?>">
 
-    <meta id="privacyidea-translations" name="privacyidea-translations" content="<?php
-    $translations = [];
-    $translation_keys = [
-        'webauthn_insecure_context',
-        'webauthn_library_unavailable',
-        'webauthn_AbortError',
-        'webauthn_InvalidStateError',
-        'webauthn_NotAllowedError',
-        'webauthn_NotSupportedError',
-        'webauthn_TypeError',
-        'webauthn_other_error',
-        'webauthn_in_progress',
-        'webauthn_success',
-        'u2f_insecure_context',
-        'u2f_unavailable',
-        'u2f_sign_request_error',
-        'try_again',
-    ];
-    foreach ($translation_keys as $translation_key) {
-        $translations[$translation_key] = $this->t(sprintf('{privacyidea:privacyidea:%s}', $translation_key));
-    }
-    echo htmlspecialchars(json_encode($translations));
-    ?>">
+    <meta id="privacyidea-translations" name="privacyidea-translations" content="<?php echo htmlspecialchars(json_encode($this->data['translations'])); ?>">
 
     <script src="<?php echo htmlspecialchars(Module::getModuleUrl('privacyidea/js/loginform.js'), ENT_QUOTES); ?>">
     </script>
diff --git a/templates/LoginForm.twig b/templates/LoginForm.twig
new file mode 100644
index 0000000000000000000000000000000000000000..87094355e199cdb70526e8afb4e4cbf34f47418a
--- /dev/null
+++ b/templates/LoginForm.twig
@@ -0,0 +1,192 @@
+{% set pagetitle = '{privacyidea:privacyidea:header}'|trans %}
+{% extends "base.twig" %}
+
+{% block preload %}
+<link rel="stylesheet" href="/{{ baseurlpath }}module.php/privacyidea/css/loginform.css" media="screen">
+{% endblock %}
+
+{% block content %}
+{% if errorCode %}
+    <div class="error-dialog">
+        <img src="/{{ baseurlpath }}resources/icons/experience/gtk-dialog-error.48x48.png"
+             class="float-l erroricon" alt="gtk-dialog-error"/>
+        <h2>{{ '{login:error_header}'|trans }}</h2>
+        <p>
+            <strong>{{ '{privacyidea:privacyidea:error}'|trans }}{% if errorCode %} {{ errorCode }}{% endif %}: {{ errorMessage }}</strong>
+        </p>
+    </div>
+{% endif %}
+
+    <div class="container">
+        <div class="login">
+            {% if authProcFilterScenario %}
+                <h2>{{ '{privacyidea:privacyidea:login_title_challenge}'|trans }}</h2>
+            {% elseif step < 2 %}
+                <h2>{{ '{privacyidea:privacyidea:login_title}'|trans }}</h2>
+            {% endif %}
+
+            <form action="FormReceiver.php" method="POST" id="piLoginForm" name="piLoginForm" class="loginForm">
+                <div class="form-panel first valid" id="gaia_firstform">
+                    <div class="slide-out">
+                        <div class="input-wrapper focused">
+                            <div class="identifier-shown">
+                                {% if forceUsername %}
+                                    {% if username %}
+                                        <h3>{{ username }}</h3>
+                                    {% endif %}
+                                    <input type="hidden" id="username" name="username" value="{{ username }}"/>
+                                {% elseif step <= 1 %}
+                                    <p>
+                                        <label for="username" class="sr-only">{{ '{login:username}'|trans }}</label>
+                                        <input type="text" id="username" tabindex="1" name="username" autofocus value="{{ username }}" placeholder="{{ '{login:username}'|trans }}" />
+                                    </p>
+                                {% endif %}
+
+                                {% if not authProcFilterScenario %}
+                                    {% if rememberUsernameEnabled or rememberMeEnabled %}
+                                        {% set rowspan = 1 %}
+                                    {% elseif organizations is defined %}
+                                        {% set rowspan = 3 %}
+                                    {% else %}
+                                        {% set rowspan = 2 %}
+                                    {% endif %}
+                                    {% if rememberUsernameEnabled %}
+                                        <input type="checkbox" id="rememberUsername" tabindex="4" name="rememberUsername"
+                                         value="Yes" {% if rememberUsernameChecked %}checked="Yes" {% endif %}/> {{ '{login:remember_username}'|trans }}
+                                    {% endif %}
+                                    {% if rememberMeEnabled %}
+                                        <input type="checkbox" id="rememberMe" tabindex="4" name="rememberMe" value="Yes" {% if rememberMeChecked %}checked="Yes" {% endif %}/> {{ '{login:remember_me}'|trans }}
+                                    {% endif %}
+                                {% endif %}
+
+                                {# Pass and OTP fields #}
+                                {% if not authProcFilterScenario %}
+                                <label for="password" class="sr-only">{{ '{privacyidea:privacyidea:password}'|trans }}</label>
+                                <input id="password" name="password" tabindex="1" type="password" value="" class="text" placeholder="{{ passHint }}"/>
+                                {% endif %}
+
+                                {% if step > 1 %}
+                                <p id="message" role="alert">{{ messageOverride }}</p>
+                                {% endif %}
+
+                                {% if step > 1 %}
+                                <p>
+                                    <label for="otp" class="sr-only">{{ '{privacyidea:privacyidea:otp}'|trans }}</label>
+                                    <input id="otp" name="otp" type="password" placeholder="{{ otpHint }}"{% if otpAvailable is defined and otpAvailable and noAlternatives %} autofocus{% endif %}>
+                                </p>
+                                {% endif %}
+
+                                <p>
+                                    <button id="submitButton" tabindex="1" class="rc-button rc-button-submit" type="submit" name="Submit" value="1">
+                                        {{ '{login:login_button}'|trans }}
+                                    </button>
+                                </p>
+
+                                {# Undefined index is suppressed and the default is used for these values #}
+                                <input id="mode" type="hidden" name="mode" value="otp" data-preferred="{{ mode }}"/>
+
+                                <input id="pushAvailable" type="hidden" name="pushAvailable" value="{% if pushAvailable %}true{% endif %}"/>
+
+                                <input id="otpAvailable" type="hidden" name="otpAvailable" value="{% if otpAvailable %}true{% endif %}"/>
+
+                                <input id="webAuthnSignRequest" type="hidden" name="webAuthnSignRequest"
+                                       value='{% if webAuthnSignRequest is defined %}{{ webAuthnSignRequest }}{% endif %}'/>
+
+                                <input id="u2fSignRequest" type="hidden" name="u2fSignRequest"
+                                       value='{% if u2fSignRequest is defined %}{{ u2fSignRequest }}{% endif %}'/>
+
+                                <input id="modeChanged" type="hidden" name="modeChanged" value=""/>
+                                <input id="step" type="hidden" name="step"
+                                       value="{% if step is defined and step %}{{ step }}{% else %}2{% endif %}"/>
+
+                                <input id="webAuthnSignResponse" type="hidden" name="webAuthnSignResponse" value=""/>
+                                <input id="u2fSignResponse" type="hidden" name="u2fSignResponse" value=""/>
+                                <input id="origin" type="hidden" name="origin" value=""/>
+                                <input id="loadCounter" type="hidden" name="loadCounter"
+                                       value="{% if loadCounter is defined and loadCounter %}{{ loadCounter }}{% else %}1{% endif %}"/>
+
+                                {# Additional input to persist the message #}
+                                <input type="hidden" name="message"
+                                       value="{% if message is defined %}{{ message }}{% endif %}"/>
+
+                                {# If enrollToken load QR Code #}
+                                {% if tokenQR is defined %}
+                                    {{ '{privacyidea:privacyidea:scan_token_qr}'|trans }}
+                                    <div class="tokenQR">
+                                        <img src="{{ tokenQR }}" />
+                                    </div>
+                                {% endif %}
+                            </div>
+
+                            {# Organizations #}
+                            {% if organizations is defined %}
+                                <div class="identifier-shown">
+                                    <label for="organization">{{ '{login:organization}'|trans }}</label>
+                                    <select id="organization" name="organization" tabindex="3">
+                                        {% for orgId, orgDesc in organizations %}
+                                            <option {% if selectedOrg is defined and orgId == selectedOrg %}selected {% endif %}value="{{ orgId }}">
+                                                {{ orgDesc|trans }}
+                                            </option>
+                                        {% endfor %}                                    
+                                    </select>
+                                </div>
+                            {% endif %}
+                        </div> <!-- focused -->
+                    </div> <!-- slide-out-->
+                </div> <!-- form-panel -->
+
+                {% if not noAlternatives and step > 1 %}
+                <div id="AlternateLoginOptions" class="groupMargin hidden js-show">
+                    <h3>{{ '{privacyidea:privacyidea:alternate_login_options}'|trans }}</h3>
+                    {# Alternate Login Options #}
+                    {% if webauthnAvailable and mode !== 'webauthn' %}
+                    <button id="useWebAuthnButton" name="useWebAuthnButton" type="button">
+                        <span>{{ '{privacyidea:privacyidea:webauthn}'|trans }}</span>
+                    </button>
+                    {% endif %}
+                    {% if pushAvailable and mode !== 'push' %}
+                    <button id="usePushButton" name="usePushButton" type="button">
+                        <span>{{ '{privacyidea:privacyidea:push}'|trans }}</span>
+                    </button>
+                    {% endif %}
+                    {% if otpAvailable and mode !== 'otp' %}
+                    <button id="useOTPButton" name="useOTPButton" type="button">
+                        <span>{{ '{privacyidea:privacyidea:otp}'|trans }}</span>
+                    </button>
+                    {% endif %}
+                    {% if u2fAvailable and mode !== 'u2f' %}
+                    <button id="useU2FButton" name="useU2FButton" type="button">
+                        <span>{{ '{privacyidea:privacyidea:u2f}'|trans }}</span>
+                    </button>
+                    {% endif %}
+                </div>
+                {% endif %}
+            </form>
+
+            {# Logout #}
+            {% if showLogout is defined and showLogout and LogoutURL is defined %}
+                <p>
+                    <a href="{{ LogoutURL }}">{{ '{status:logout}'|trans }}</a>
+                </p>
+            <?php } ?>
+        </div>  <!-- End of login -->
+    </div>  <!-- End of container -->
+
+{% if links %}
+    <ul class="links">
+        {% for l in links %}
+            <li><a href="{{ l['href'] }}">{{ l['text']|trans }}</a></li>
+        {% endfor %}
+    </ul>
+{% endif %}
+
+    <script src="{{ baseurl }}module.php/privacyidea/js/pi-webauthn.js"></script>
+
+    <script src="{{ baseurl }}module.php/privacyidea/js/u2f-api.js"></script>
+
+    <meta id="privacyidea-step" name="privacyidea-step" content="{{ step }}">
+
+    <meta id="privacyidea-translations" name="privacyidea-translations" content="{{ translations | json_encode | raw }}">
+
+    <script src="{{ baseurl }}module.php/privacyidea/js/loginform.js"></script>
+{% endblock %}
diff --git a/www/FormBuilder.php b/www/FormBuilder.php
index 3ab4af02d06aadeb83fc8728d3a2ca9a22bbd466..79011b6201b0d5de3884a43ed89a02e230846d28 100644
--- a/www/FormBuilder.php
+++ b/www/FormBuilder.php
@@ -47,7 +47,7 @@ if (!empty($state['privacyidea:privacyidea']['errorCode']) || !empty($state['pri
 }
 
 // AuthProc
-if ('authprocess' === $state['privacyidea:privacyidea']['authenticationMethod']) {
+if ($state['privacyidea:privacyidea']['authenticationMethod'] === 'authprocess') {
     $tpl->data['authProcFilterScenario'] = true;
     $tpl->data['rememberUsernameEnabled'] = true;
     $tpl->data['rememberUsernameChecked'] = true;
@@ -59,11 +59,11 @@ if ('authprocess' === $state['privacyidea:privacyidea']['authenticationMethod'])
     } else {
         $tpl->data['tokenQR'] = null;
     }
-} elseif ('authsource' === $state['privacyidea:privacyidea']['authenticationMethod']) {
+} elseif ($state['privacyidea:privacyidea']['authenticationMethod'] === 'authsource') {
     // AuthSource
     $source = Source::getById($state['privacyidea:privacyidea']['AuthId']);
 
-    if (null === $source) {
+    if ($source === null) {
         Logger::error('Could not find authentication source with ID ' . $state['privacyidea:privacyidea']['AuthId']);
     }
 
@@ -101,11 +101,83 @@ if (empty($_REQUEST['loadCounter'])) {
     $tpl->data['loadCounter'] = 1;
 }
 
-if ('authprocess' === $state['privacyidea:privacyidea']['authenticationMethod']) {
+if ($state['privacyidea:privacyidea']['authenticationMethod'] === 'authprocess') {
     $tpl->data['LogoutURL'] = Module::getModuleURL('core/authenticate.php', [
         'as' => $state['Source']['auth'],
     ]) . '&logout';
 }
 
+$translator = $t->getTranslator();
+
+$tpl->data['otpAvailable'] = true; // FIXME
+$tpl->data['u2fAvailable'] = !empty($tpl->data['u2fSignRequest']);
+$tpl->data['webauthnAvailable'] = !empty($tpl->data['webAuthnSignRequest']);
+$tpl->data['pushAvailable'] = false; // FIXME
+$tpl->data['mode'] = ($tpl->data['mode'] ?? null) ?: 'otp';
+$tpl->data['noAlternatives'] = true;
+foreach (['otp', 'push', 'u2f', 'webauthn'] as $mode) {
+    if ($mode !== $tpl->data['mode'] && $tpl->data[$mode . 'Available']) {
+        $tpl->data['noAlternatives'] = false;
+        break;
+    }
+}
+
+// Set default scenario if isn't set
+if (!empty($tpl->data['authProcFilterScenario'])) {
+    if (empty($tpl->data['username'])) {
+        $tpl->data['username'] = '';
+    }
+} else {
+    $tpl->data['authProcFilterScenario'] = 0;
+}
+
+// Set the right text shown in otp/pass field(s)
+if (isset($tpl->data['otpFieldHint'])) {
+    $tpl->data['otpHint'] = $tpl->data['otpFieldHint'];
+} else {
+    $tpl->data['otpHint'] = $translator->t('{privacyidea:privacyidea:otp}');
+}
+if (isset($tpl->data['passFieldHint'])) {
+    $tpl->data['passHint'] = $tpl->data['passFieldHint'];
+} else {
+    $tpl->data['passHint'] = $translator->t('{privacyidea:privacyidea:password}');
+}
+
+// Prepare next settings
+if (!empty($this->data['username'])) {
+    $tpl->data['autofocus'] = 'password';
+} else {
+    $tpl->data['autofocus'] = 'username';
+}
+
+$messageOverride = $this->data['messageOverride'] ?? null;
+if ($messageOverride === null || is_string($messageOverride)) {
+    $tpl->data['messageOverride'] = $messageOverride ?? $this->data['message'] ?? '';
+} elseif (is_callable($messageOverride)) {
+    $tpl->data['messageOverride'] = call_user_func($messageOverride, $this->data['message'] ?? '');
+}
+
+$translations = [];
+$translation_keys = [
+    'webauthn_insecure_context',
+    'webauthn_library_unavailable',
+    'webauthn_AbortError',
+    'webauthn_InvalidStateError',
+    'webauthn_NotAllowedError',
+    'webauthn_NotSupportedError',
+    'webauthn_TypeError',
+    'webauthn_other_error',
+    'webauthn_in_progress',
+    'webauthn_success',
+    'u2f_insecure_context',
+    'u2f_unavailable',
+    'u2f_sign_request_error',
+    'try_again',
+];
+foreach ($translation_keys as $translation_key) {
+    $translations[$translation_key] = $this->t(sprintf('{privacyidea:privacyidea:%s}', $translation_key));
+}
+$tpl->data['translations'] = $translations;
+
 Session::getSessionFromRequest()->setData('privacyidea:privacyidea', 'stateId', $stateId);
 $tpl->show();
diff --git a/www/FormReceiver.php b/www/FormReceiver.php
index 507ccef25f2e4ffb0957958317f3853bb2848e5f..41a91cafd687ceb3ebb6accce694ae2d63bf3bef 100644
--- a/www/FormReceiver.php
+++ b/www/FormReceiver.php
@@ -54,7 +54,7 @@ $formParams = [
     'loadCounter' => array_key_exists('loadCounter', $_REQUEST) ? $_REQUEST['loadCounter'] : 1,
 ];
 
-if ('authprocess' === $state['privacyidea:privacyidea']['authenticationMethod']) {
+if ($state['privacyidea:privacyidea']['authenticationMethod'] === 'authprocess') {
     // Auth Proc
     try {
         $response = Utils::authenticatePI($state, $formParams);
@@ -79,12 +79,12 @@ if ('authprocess' === $state['privacyidea:privacyidea']['authenticationMethod'])
         $params = $sessionHandler->getCookieParams();
 
         $params['expire'] = time();
-        $params['expire'] += (isset($_REQUEST['rememberUsername']) && 'Yes' === $_REQUEST['rememberUsername'] ? 31536000 : -300);
+        $params['expire'] += (isset($_REQUEST['rememberUsername']) && $_REQUEST['rememberUsername'] === 'Yes' ? 31536000 : -300);
         HTTP::setCookie($source->getAuthId() . '-username', $username, $params, false);
     }
 
     if ($source->isRememberMeEnabled()) {
-        if (array_key_exists('rememberMe', $_REQUEST) && 'Yes' === $_REQUEST['rememberMe']) {
+        if (array_key_exists('rememberMe', $_REQUEST) && $_REQUEST['rememberMe'] === 'Yes') {
             $state['RememberMe'] = true;
             $stateId = State::saveState($state, UserPassBase::STAGEID);
         }