diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ab448556cc6009a00c2a58e79383ed0d833100a6..e4eeb4c5f8c14c8c3a0120ce7caeec1f38ba3afa 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -35,7 +35,7 @@ jobs:
   test-latest:
     runs-on: ubuntu-latest
     container:
-      image: cicnavi/dap:08
+      image: cicnavi/dap:81
     steps:
       - uses: actions/checkout@v3
       - name: Validate composer.json and composer.lock
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e50b5fbcf24142aed3b06bad6f59e1e0f93cefe2..36e6cd3690fc6dda60ce5f2f437dafe18764e240 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,10 +20,10 @@ test-74:
     - composer install --prefer-dist --no-progress --no-suggest
     - composer run-script pre-commit
 
-# PHP latest
-test-08:
+# PHP v8.1
+test-81:
   stage: test
-  image: cicnavi/dap:08
+  image: cicnavi/dap:81
   script:
     - composer install --prefer-dist --no-progress --no-suggest
     - composer run-script pre-commit
diff --git a/composer.json b/composer.json
index 4c2e7fc0585800dcd5ef6d4b985dd873ceb8f2c9..f4af26fc1e71c85834a4a8dab99b5b084dd78814 100644
--- a/composer.json
+++ b/composer.json
@@ -28,6 +28,7 @@
         "php": "^7.4 || ^8.0",
         "ext-pdo": "*",
         "ext-pdo_sqlite": "*",
+        "composer-runtime-api": "^2.0",
         "doctrine/dbal": "^3",
         "psr/log": "^1|^2|^3",
         "simplesamlphp/composer-module-installer": "^1",
@@ -37,8 +38,9 @@
         "vimeo/psalm": "^5",
         "phpunit/phpunit": "^9",
         "squizlabs/php_codesniffer": "^3",
-        "simplesamlphp/simplesamlphp": "^2@beta",
-        "simplesamlphp/simplesamlphp-test-framework": "^1"
+        "simplesamlphp/simplesamlphp": "^2",
+        "simplesamlphp/simplesamlphp-test-framework": "^1",
+        "simplesamlphp/simplesamlphp-module-oidc": "^3"
     },
     "suggest": {
         "ext-pcntl": "Enables job runner to gracefully respond to SIGTERM signal.",
diff --git a/composer.lock b/composer.lock
index 64d9ba629b02045077fc80ed0583d518673f4f11..76ddc7a1a19e4007287036be7a8c1e191051092a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "fe21f8863239731b2f1746d3e887dff7",
+    "content-hash": "3bee36e7c2158fe267b7704bbd22ad26",
     "packages": [
         {
             "name": "cicnavi/simple-file-cache-php",
@@ -154,16 +154,16 @@
         },
         {
             "name": "doctrine/dbal",
-            "version": "3.6.0",
+            "version": "3.6.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/dbal.git",
-                "reference": "85b98cb23c8af471a67abfe14485da696bcabc2e"
+                "reference": "57815c7bbcda3cd18871d253c1dd8cbe56f8526e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/85b98cb23c8af471a67abfe14485da696bcabc2e",
-                "reference": "85b98cb23c8af471a67abfe14485da696bcabc2e",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/57815c7bbcda3cd18871d253c1dd8cbe56f8526e",
+                "reference": "57815c7bbcda3cd18871d253c1dd8cbe56f8526e",
                 "shasum": ""
             },
             "require": {
@@ -179,11 +179,11 @@
                 "doctrine/coding-standard": "11.1.0",
                 "fig/log-test": "^1",
                 "jetbrains/phpstorm-stubs": "2022.3",
-                "phpstan/phpstan": "1.9.14",
-                "phpstan/phpstan-strict-rules": "^1.4",
-                "phpunit/phpunit": "9.6.3",
+                "phpstan/phpstan": "1.10.3",
+                "phpstan/phpstan-strict-rules": "^1.5",
+                "phpunit/phpunit": "9.6.4",
                 "psalm/plugin-phpunit": "0.18.4",
-                "squizlabs/php_codesniffer": "3.7.1",
+                "squizlabs/php_codesniffer": "3.7.2",
                 "symfony/cache": "^5.4|^6.0",
                 "symfony/console": "^4.4|^5.4|^6.0",
                 "vimeo/psalm": "4.30.0"
@@ -246,7 +246,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/dbal/issues",
-                "source": "https://github.com/doctrine/dbal/tree/3.6.0"
+                "source": "https://github.com/doctrine/dbal/tree/3.6.1"
             },
             "funding": [
                 {
@@ -262,7 +262,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-07T22:52:03+00:00"
+            "time": "2023-03-02T19:26:24+00:00"
         },
         {
             "name": "doctrine/deprecations",
@@ -605,22 +605,22 @@
         },
         {
             "name": "simplesamlphp/composer-module-installer",
-            "version": "v1.3.3",
+            "version": "v1.3.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/composer-module-installer.git",
-                "reference": "ad700e45b1813cd7bfb067bcf66c78c5b410125f"
+                "reference": "36508ed9580a30c4d5ab0bb3c25c00d0b5d42946"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/composer-module-installer/zipball/ad700e45b1813cd7bfb067bcf66c78c5b410125f",
-                "reference": "ad700e45b1813cd7bfb067bcf66c78c5b410125f",
+                "url": "https://api.github.com/repos/simplesamlphp/composer-module-installer/zipball/36508ed9580a30c4d5ab0bb3c25c00d0b5d42946",
+                "reference": "36508ed9580a30c4d5ab0bb3c25c00d0b5d42946",
                 "shasum": ""
             },
             "require": {
                 "composer-plugin-api": "^1.1 || ^2.0",
                 "php": "^7.4 || ^8.0",
-                "simplesamlphp/assert": "^0.8.0"
+                "simplesamlphp/assert": "^0.8.0 || ^1.0"
             },
             "require-dev": {
                 "composer/composer": "^2.4",
@@ -642,9 +642,9 @@
             "description": "A Composer plugin that allows installing SimpleSAMLphp modules through Composer.",
             "support": {
                 "issues": "https://github.com/simplesamlphp/composer-module-installer/issues",
-                "source": "https://github.com/simplesamlphp/composer-module-installer/tree/v1.3.3"
+                "source": "https://github.com/simplesamlphp/composer-module-installer/tree/v1.3.4"
             },
-            "time": "2023-01-31T09:51:44+00:00"
+            "time": "2023-03-08T20:58:22+00:00"
         },
         {
             "name": "webmozart/assert",
@@ -872,6 +872,66 @@
             ],
             "time": "2021-03-30T17:13:30+00:00"
         },
+        {
+            "name": "brick/math",
+            "version": "0.9.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/brick/math.git",
+                "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae",
+                "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.2",
+                "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0",
+                "vimeo/psalm": "4.9.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Brick\\Math\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Arbitrary-precision arithmetic library",
+            "keywords": [
+                "Arbitrary-precision",
+                "BigInteger",
+                "BigRational",
+                "arithmetic",
+                "bigdecimal",
+                "bignum",
+                "brick",
+                "math"
+            ],
+            "support": {
+                "issues": "https://github.com/brick/math/issues",
+                "source": "https://github.com/brick/math/tree/0.9.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/BenMorel",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/brick/math",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-08-15T20:50:18+00:00"
+        },
         {
             "name": "composer/ca-bundle",
             "version": "1.3.5",
@@ -1023,16 +1083,16 @@
         },
         {
             "name": "composer/composer",
-            "version": "2.5.4",
+            "version": "2.5.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/composer.git",
-                "reference": "6b67eeea4d72051c369ccdbfb2423a56e2ab51a9"
+                "reference": "c7cffaad16a60636a776017eac5bd8cd0095c32f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/composer/zipball/6b67eeea4d72051c369ccdbfb2423a56e2ab51a9",
-                "reference": "6b67eeea4d72051c369ccdbfb2423a56e2ab51a9",
+                "url": "https://api.github.com/repos/composer/composer/zipball/c7cffaad16a60636a776017eac5bd8cd0095c32f",
+                "reference": "c7cffaad16a60636a776017eac5bd8cd0095c32f",
                 "shasum": ""
             },
             "require": {
@@ -1116,7 +1176,7 @@
             "support": {
                 "irc": "ircs://irc.libera.chat:6697/composer",
                 "issues": "https://github.com/composer/composer/issues",
-                "source": "https://github.com/composer/composer/tree/2.5.4"
+                "source": "https://github.com/composer/composer/tree/2.5.5"
             },
             "funding": [
                 {
@@ -1132,7 +1192,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-15T12:10:06+00:00"
+            "time": "2023-03-21T10:50:05+00:00"
         },
         {
             "name": "composer/metadata-minifier",
@@ -1203,79 +1263,6 @@
             ],
             "time": "2021-04-07T13:37:33+00:00"
         },
-        {
-            "name": "composer/package-versions-deprecated",
-            "version": "1.11.99.5",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/composer/package-versions-deprecated.git",
-                "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d",
-                "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d",
-                "shasum": ""
-            },
-            "require": {
-                "composer-plugin-api": "^1.1.0 || ^2.0",
-                "php": "^7 || ^8"
-            },
-            "replace": {
-                "ocramius/package-versions": "1.11.99"
-            },
-            "require-dev": {
-                "composer/composer": "^1.9.3 || ^2.0@dev",
-                "ext-zip": "^1.13",
-                "phpunit/phpunit": "^6.5 || ^7"
-            },
-            "type": "composer-plugin",
-            "extra": {
-                "class": "PackageVersions\\Installer",
-                "branch-alias": {
-                    "dev-master": "1.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "PackageVersions\\": "src/PackageVersions"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Marco Pivetta",
-                    "email": "ocramius@gmail.com"
-                },
-                {
-                    "name": "Jordi Boggiano",
-                    "email": "j.boggiano@seld.be"
-                }
-            ],
-            "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
-            "support": {
-                "issues": "https://github.com/composer/package-versions-deprecated/issues",
-                "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5"
-            },
-            "funding": [
-                {
-                    "url": "https://packagist.com",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/composer",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2022-01-17T14:14:24+00:00"
-        },
         {
             "name": "composer/pcre",
             "version": "3.1.0",
@@ -1574,6 +1561,72 @@
             ],
             "time": "2022-02-25T21:32:43+00:00"
         },
+        {
+            "name": "defuse/php-encryption",
+            "version": "v2.3.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/defuse/php-encryption.git",
+                "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/defuse/php-encryption/zipball/77880488b9954b7884c25555c2a0ea9e7053f9d2",
+                "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2",
+                "shasum": ""
+            },
+            "require": {
+                "ext-openssl": "*",
+                "paragonie/random_compat": ">= 2",
+                "php": ">=5.6.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4|^5|^6|^7|^8|^9"
+            },
+            "bin": [
+                "bin/generate-defuse-key"
+            ],
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Defuse\\Crypto\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Hornby",
+                    "email": "taylor@defuse.ca",
+                    "homepage": "https://defuse.ca/"
+                },
+                {
+                    "name": "Scott Arciszewski",
+                    "email": "info@paragonie.com",
+                    "homepage": "https://paragonie.com"
+                }
+            ],
+            "description": "Secure PHP Encryption Library",
+            "keywords": [
+                "aes",
+                "authenticated encryption",
+                "cipher",
+                "crypto",
+                "cryptography",
+                "encrypt",
+                "encryption",
+                "openssl",
+                "security",
+                "symmetric key cryptography"
+            ],
+            "support": {
+                "issues": "https://github.com/defuse/php-encryption/issues",
+                "source": "https://github.com/defuse/php-encryption/tree/v2.3.1"
+            },
+            "time": "2021-04-09T23:57:26+00:00"
+        },
         {
             "name": "dnoegel/php-xdg-base-dir",
             "version": "v0.1.1",
@@ -1782,6 +1835,82 @@
             },
             "time": "2022-03-02T22:36:06+00:00"
         },
+        {
+            "name": "fgrosse/phpasn1",
+            "version": "v2.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/fgrosse/PHPASN1.git",
+                "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/42060ed45344789fb9f21f9f1864fc47b9e3507b",
+                "reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "~2.0",
+                "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
+            },
+            "suggest": {
+                "ext-bcmath": "BCmath is the fallback extension for big integer calculations",
+                "ext-curl": "For loading OID information from the web if they have not bee defined statically",
+                "ext-gmp": "GMP is the preferred extension for big integer calculations",
+                "phpseclib/bcmath_compat": "BCmath polyfill for servers where neither GMP nor BCmath is available"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "FG\\": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Friedrich Große",
+                    "email": "friedrich.grosse@gmail.com",
+                    "homepage": "https://github.com/FGrosse",
+                    "role": "Author"
+                },
+                {
+                    "name": "All contributors",
+                    "homepage": "https://github.com/FGrosse/PHPASN1/contributors"
+                }
+            ],
+            "description": "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.",
+            "homepage": "https://github.com/FGrosse/PHPASN1",
+            "keywords": [
+                "DER",
+                "asn.1",
+                "asn1",
+                "ber",
+                "binary",
+                "decoding",
+                "encoding",
+                "x.509",
+                "x.690",
+                "x509",
+                "x690"
+            ],
+            "support": {
+                "issues": "https://github.com/fgrosse/PHPASN1/issues",
+                "source": "https://github.com/fgrosse/PHPASN1/tree/v2.5.0"
+            },
+            "abandoned": true,
+            "time": "2022-12-19T11:08:26+00:00"
+        },
         {
             "name": "fidry/cpu-core-counter",
             "version": "0.5.1",
@@ -2066,39 +2195,58 @@
             "time": "2022-02-23T20:29:40+00:00"
         },
         {
-            "name": "justinrainbow/json-schema",
-            "version": "5.2.12",
+            "name": "guzzlehttp/guzzle",
+            "version": "7.5.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/justinrainbow/json-schema.git",
-                "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60"
+                "url": "https://github.com/guzzle/guzzle.git",
+                "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60",
-                "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba",
+                "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.3"
+                "ext-json": "*",
+                "guzzlehttp/promises": "^1.5",
+                "guzzlehttp/psr7": "^1.9 || ^2.4",
+                "php": "^7.2.5 || ^8.0",
+                "psr/http-client": "^1.0",
+                "symfony/deprecation-contracts": "^2.2 || ^3.0"
+            },
+            "provide": {
+                "psr/http-client-implementation": "1.0"
             },
             "require-dev": {
-                "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
-                "json-schema/json-schema-test-suite": "1.2.0",
-                "phpunit/phpunit": "^4.8.35"
+                "bamarni/composer-bin-plugin": "^1.8.1",
+                "ext-curl": "*",
+                "php-http/client-integration-tests": "^3.0",
+                "phpunit/phpunit": "^8.5.29 || ^9.5.23",
+                "psr/log": "^1.1 || ^2.0 || ^3.0"
+            },
+            "suggest": {
+                "ext-curl": "Required for CURL handler support",
+                "ext-intl": "Required for Internationalized Domain Name (IDN) support",
+                "psr/log": "Required for using the Log middleware"
             },
-            "bin": [
-                "bin/validate-json"
-            ],
             "type": "library",
             "extra": {
+                "bamarni-bin": {
+                    "bin-links": true,
+                    "forward-command": false
+                },
                 "branch-alias": {
-                    "dev-master": "5.0.x-dev"
+                    "dev-master": "7.5-dev"
                 }
             },
             "autoload": {
+                "files": [
+                    "src/functions_include.php"
+                ],
                 "psr-4": {
-                    "JsonSchema\\": "src/JsonSchema/"
+                    "GuzzleHttp\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -2107,76 +2255,1065 @@
             ],
             "authors": [
                 {
-                    "name": "Bruno Prieto Reis",
-                    "email": "bruno.p.reis@gmail.com"
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
                 },
                 {
-                    "name": "Justin Rainbow",
-                    "email": "justin.rainbow@gmail.com"
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
                 },
                 {
-                    "name": "Igor Wiedler",
-                    "email": "igor@wiedler.ch"
+                    "name": "Jeremy Lindblom",
+                    "email": "jeremeamia@gmail.com",
+                    "homepage": "https://github.com/jeremeamia"
                 },
                 {
-                    "name": "Robert Schönthal",
-                    "email": "seroscho@googlemail.com"
+                    "name": "George Mponos",
+                    "email": "gmponos@gmail.com",
+                    "homepage": "https://github.com/gmponos"
+                },
+                {
+                    "name": "Tobias Nyholm",
+                    "email": "tobias.nyholm@gmail.com",
+                    "homepage": "https://github.com/Nyholm"
+                },
+                {
+                    "name": "Márk Sági-Kazár",
+                    "email": "mark.sagikazar@gmail.com",
+                    "homepage": "https://github.com/sagikazarmark"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "email": "webmaster@tubo-world.de",
+                    "homepage": "https://github.com/Tobion"
                 }
             ],
-            "description": "A library to validate a json schema.",
-            "homepage": "https://github.com/justinrainbow/json-schema",
+            "description": "Guzzle is a PHP HTTP client library",
             "keywords": [
-                "json",
-                "schema"
+                "client",
+                "curl",
+                "framework",
+                "http",
+                "http client",
+                "psr-18",
+                "psr-7",
+                "rest",
+                "web service"
             ],
             "support": {
-                "issues": "https://github.com/justinrainbow/json-schema/issues",
-                "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12"
+                "issues": "https://github.com/guzzle/guzzle/issues",
+                "source": "https://github.com/guzzle/guzzle/tree/7.5.0"
             },
-            "time": "2022-04-13T08:02:27+00:00"
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/Nyholm",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-08-28T15:39:27+00:00"
         },
         {
-            "name": "myclabs/deep-copy",
-            "version": "1.11.0",
+            "name": "guzzlehttp/promises",
+            "version": "1.5.2",
             "source": {
                 "type": "git",
-                "url": "https://github.com/myclabs/DeepCopy.git",
-                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
+                "url": "https://github.com/guzzle/promises.git",
+                "reference": "b94b2807d85443f9719887892882d0329d1e2598"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
-                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598",
+                "reference": "b94b2807d85443f9719887892882d0329d1e2598",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.1 || ^8.0"
-            },
-            "conflict": {
-                "doctrine/collections": "<1.6.8",
-                "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+                "php": ">=5.5"
             },
             "require-dev": {
-                "doctrine/collections": "^1.6.8",
-                "doctrine/common": "^2.13.3 || ^3.2.2",
-                "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
+                "symfony/phpunit-bridge": "^4.4 || ^5.1"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.5-dev"
+                }
+            },
             "autoload": {
                 "files": [
-                    "src/DeepCopy/deep_copy.php"
+                    "src/functions_include.php"
                 ],
                 "psr-4": {
-                    "DeepCopy\\": "src/DeepCopy/"
+                    "GuzzleHttp\\Promise\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
-            "description": "Create deep copies (clones) of your objects",
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "Tobias Nyholm",
+                    "email": "tobias.nyholm@gmail.com",
+                    "homepage": "https://github.com/Nyholm"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "email": "webmaster@tubo-world.de",
+                    "homepage": "https://github.com/Tobion"
+                }
+            ],
+            "description": "Guzzle promises library",
             "keywords": [
-                "clone",
+                "promise"
+            ],
+            "support": {
+                "issues": "https://github.com/guzzle/promises/issues",
+                "source": "https://github.com/guzzle/promises/tree/1.5.2"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/Nyholm",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-08-28T14:55:35+00:00"
+        },
+        {
+            "name": "guzzlehttp/psr7",
+            "version": "2.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/psr7.git",
+                "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
+                "reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5 || ^8.0",
+                "psr/http-factory": "^1.0",
+                "psr/http-message": "^1.0",
+                "ralouphie/getallheaders": "^3.0"
+            },
+            "provide": {
+                "psr/http-factory-implementation": "1.0",
+                "psr/http-message-implementation": "1.0"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.8.1",
+                "http-interop/http-factory-tests": "^0.9",
+                "phpunit/phpunit": "^8.5.29 || ^9.5.23"
+            },
+            "suggest": {
+                "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
+            },
+            "type": "library",
+            "extra": {
+                "bamarni-bin": {
+                    "bin-links": true,
+                    "forward-command": false
+                },
+                "branch-alias": {
+                    "dev-master": "2.4-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\Psr7\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "George Mponos",
+                    "email": "gmponos@gmail.com",
+                    "homepage": "https://github.com/gmponos"
+                },
+                {
+                    "name": "Tobias Nyholm",
+                    "email": "tobias.nyholm@gmail.com",
+                    "homepage": "https://github.com/Nyholm"
+                },
+                {
+                    "name": "Márk Sági-Kazár",
+                    "email": "mark.sagikazar@gmail.com",
+                    "homepage": "https://github.com/sagikazarmark"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "email": "webmaster@tubo-world.de",
+                    "homepage": "https://github.com/Tobion"
+                },
+                {
+                    "name": "Márk Sági-Kazár",
+                    "email": "mark.sagikazar@gmail.com",
+                    "homepage": "https://sagikazarmark.hu"
+                }
+            ],
+            "description": "PSR-7 message implementation that also provides common utility methods",
+            "keywords": [
+                "http",
+                "message",
+                "psr-7",
+                "request",
+                "response",
+                "stream",
+                "uri",
+                "url"
+            ],
+            "support": {
+                "issues": "https://github.com/guzzle/psr7/issues",
+                "source": "https://github.com/guzzle/psr7/tree/2.4.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/Nyholm",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2023-03-09T13:19:02+00:00"
+        },
+        {
+            "name": "justinrainbow/json-schema",
+            "version": "5.2.12",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/justinrainbow/json-schema.git",
+                "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60",
+                "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
+                "json-schema/json-schema-test-suite": "1.2.0",
+                "phpunit/phpunit": "^4.8.35"
+            },
+            "bin": [
+                "bin/validate-json"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "JsonSchema\\": "src/JsonSchema/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Bruno Prieto Reis",
+                    "email": "bruno.p.reis@gmail.com"
+                },
+                {
+                    "name": "Justin Rainbow",
+                    "email": "justin.rainbow@gmail.com"
+                },
+                {
+                    "name": "Igor Wiedler",
+                    "email": "igor@wiedler.ch"
+                },
+                {
+                    "name": "Robert Schönthal",
+                    "email": "seroscho@googlemail.com"
+                }
+            ],
+            "description": "A library to validate a json schema.",
+            "homepage": "https://github.com/justinrainbow/json-schema",
+            "keywords": [
+                "json",
+                "schema"
+            ],
+            "support": {
+                "issues": "https://github.com/justinrainbow/json-schema/issues",
+                "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12"
+            },
+            "time": "2022-04-13T08:02:27+00:00"
+        },
+        {
+            "name": "laminas/laminas-diactoros",
+            "version": "2.17.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laminas/laminas-diactoros.git",
+                "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5",
+                "reference": "5b32597aa46b83c8b85bb1cf9a6ed4fe7dd980c5",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.4 || ~8.0.0 || ~8.1.0",
+                "psr/http-factory": "^1.0",
+                "psr/http-message": "^1.0"
+            },
+            "conflict": {
+                "zendframework/zend-diactoros": "*"
+            },
+            "provide": {
+                "psr/http-factory-implementation": "1.0",
+                "psr/http-message-implementation": "1.0"
+            },
+            "require-dev": {
+                "ext-curl": "*",
+                "ext-dom": "*",
+                "ext-gd": "*",
+                "ext-libxml": "*",
+                "http-interop/http-factory-tests": "^0.9.0",
+                "laminas/laminas-coding-standard": "^2.4.0",
+                "php-http/psr7-integration-tests": "^1.1.1",
+                "phpunit/phpunit": "^9.5.23",
+                "psalm/plugin-phpunit": "^0.17.0",
+                "vimeo/psalm": "^4.24.0"
+            },
+            "type": "library",
+            "extra": {
+                "laminas": {
+                    "config-provider": "Laminas\\Diactoros\\ConfigProvider",
+                    "module": "Laminas\\Diactoros"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/functions/create_uploaded_file.php",
+                    "src/functions/marshal_headers_from_sapi.php",
+                    "src/functions/marshal_method_from_sapi.php",
+                    "src/functions/marshal_protocol_version_from_sapi.php",
+                    "src/functions/marshal_uri_from_sapi.php",
+                    "src/functions/normalize_server.php",
+                    "src/functions/normalize_uploaded_files.php",
+                    "src/functions/parse_cookie_header.php",
+                    "src/functions/create_uploaded_file.legacy.php",
+                    "src/functions/marshal_headers_from_sapi.legacy.php",
+                    "src/functions/marshal_method_from_sapi.legacy.php",
+                    "src/functions/marshal_protocol_version_from_sapi.legacy.php",
+                    "src/functions/marshal_uri_from_sapi.legacy.php",
+                    "src/functions/normalize_server.legacy.php",
+                    "src/functions/normalize_uploaded_files.legacy.php",
+                    "src/functions/parse_cookie_header.legacy.php"
+                ],
+                "psr-4": {
+                    "Laminas\\Diactoros\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "description": "PSR HTTP Message implementations",
+            "homepage": "https://laminas.dev",
+            "keywords": [
+                "http",
+                "laminas",
+                "psr",
+                "psr-17",
+                "psr-7"
+            ],
+            "support": {
+                "chat": "https://laminas.dev/chat",
+                "docs": "https://docs.laminas.dev/laminas-diactoros/",
+                "forum": "https://discourse.laminas.dev",
+                "issues": "https://github.com/laminas/laminas-diactoros/issues",
+                "rss": "https://github.com/laminas/laminas-diactoros/releases.atom",
+                "source": "https://github.com/laminas/laminas-diactoros"
+            },
+            "funding": [
+                {
+                    "url": "https://funding.communitybridge.org/projects/laminas-project",
+                    "type": "community_bridge"
+                }
+            ],
+            "time": "2022-08-30T17:01:46+00:00"
+        },
+        {
+            "name": "laminas/laminas-httphandlerrunner",
+            "version": "1.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laminas/laminas-httphandlerrunner.git",
+                "reference": "5f94e55d93f756e8ad07b9049aeb3d6d84582d0e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laminas/laminas-httphandlerrunner/zipball/5f94e55d93f756e8ad07b9049aeb3d6d84582d0e",
+                "reference": "5f94e55d93f756e8ad07b9049aeb3d6d84582d0e",
+                "shasum": ""
+            },
+            "require": {
+                "laminas/laminas-zendframework-bridge": "^1.0",
+                "php": "^7.3 || ~8.0.0 || ~8.1.0",
+                "psr/http-message": "^1.0",
+                "psr/http-message-implementation": "^1.0",
+                "psr/http-server-handler": "^1.0"
+            },
+            "replace": {
+                "zendframework/zend-httphandlerrunner": "^1.1.0"
+            },
+            "require-dev": {
+                "laminas/laminas-coding-standard": "~1.0.0",
+                "laminas/laminas-diactoros": "^2.8.0",
+                "phpunit/phpunit": "^9.5.9",
+                "psalm/plugin-phpunit": "^0.16.1",
+                "vimeo/psalm": "^4.10.0"
+            },
+            "type": "library",
+            "extra": {
+                "laminas": {
+                    "config-provider": "Laminas\\HttpHandlerRunner\\ConfigProvider"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Laminas\\HttpHandlerRunner\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "description": "Execute PSR-15 RequestHandlerInterface instances and emit responses they generate.",
+            "homepage": "https://laminas.dev",
+            "keywords": [
+                "components",
+                "laminas",
+                "mezzio",
+                "psr-15",
+                "psr-7"
+            ],
+            "support": {
+                "chat": "https://laminas.dev/chat",
+                "docs": "https://docs.laminas.dev/laminas-httphandlerrunner/",
+                "forum": "https://discourse.laminas.dev",
+                "issues": "https://github.com/laminas/laminas-httphandlerrunner/issues",
+                "rss": "https://github.com/laminas/laminas-httphandlerrunner/releases.atom",
+                "source": "https://github.com/laminas/laminas-httphandlerrunner"
+            },
+            "funding": [
+                {
+                    "url": "https://funding.communitybridge.org/projects/laminas-project",
+                    "type": "community_bridge"
+                }
+            ],
+            "time": "2021-09-22T09:17:54+00:00"
+        },
+        {
+            "name": "laminas/laminas-zendframework-bridge",
+            "version": "1.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laminas/laminas-zendframework-bridge.git",
+                "reference": "e112dd2c099f4f6142c16fc65fda89a638e06885"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/e112dd2c099f4f6142c16fc65fda89a638e06885",
+                "reference": "e112dd2c099f4f6142c16fc65fda89a638e06885",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.4, <8.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5.14",
+                "psalm/plugin-phpunit": "^0.15.2",
+                "squizlabs/php_codesniffer": "^3.6.2",
+                "vimeo/psalm": "^4.21.0"
+            },
+            "type": "library",
+            "extra": {
+                "laminas": {
+                    "module": "Laminas\\ZendFrameworkBridge"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/autoload.php"
+                ],
+                "psr-4": {
+                    "Laminas\\ZendFrameworkBridge\\": "src//"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "description": "Alias legacy ZF class names to Laminas Project equivalents.",
+            "keywords": [
+                "ZendFramework",
+                "autoloading",
+                "laminas",
+                "zf"
+            ],
+            "support": {
+                "forum": "https://discourse.laminas.dev/",
+                "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues",
+                "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom",
+                "source": "https://github.com/laminas/laminas-zendframework-bridge"
+            },
+            "funding": [
+                {
+                    "url": "https://funding.communitybridge.org/projects/laminas-project",
+                    "type": "community_bridge"
+                }
+            ],
+            "time": "2022-07-29T13:28:29+00:00"
+        },
+        {
+            "name": "lcobucci/clock",
+            "version": "2.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/lcobucci/clock.git",
+                "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/lcobucci/clock/zipball/353d83fe2e6ae95745b16b3d911813df6a05bfb3",
+                "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.4 || ^8.0"
+            },
+            "require-dev": {
+                "infection/infection": "^0.17",
+                "lcobucci/coding-standard": "^6.0",
+                "phpstan/extension-installer": "^1.0",
+                "phpstan/phpstan": "^0.12",
+                "phpstan/phpstan-deprecation-rules": "^0.12",
+                "phpstan/phpstan-phpunit": "^0.12",
+                "phpstan/phpstan-strict-rules": "^0.12",
+                "phpunit/php-code-coverage": "9.1.4",
+                "phpunit/phpunit": "9.3.7"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Lcobucci\\Clock\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Luís Cobucci",
+                    "email": "lcobucci@gmail.com"
+                }
+            ],
+            "description": "Yet another clock abstraction",
+            "support": {
+                "issues": "https://github.com/lcobucci/clock/issues",
+                "source": "https://github.com/lcobucci/clock/tree/2.0.x"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/lcobucci",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/lcobucci",
+                    "type": "patreon"
+                }
+            ],
+            "time": "2020-08-27T18:56:02+00:00"
+        },
+        {
+            "name": "lcobucci/jwt",
+            "version": "4.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/lcobucci/jwt.git",
+                "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/lcobucci/jwt/zipball/4d7de2fe0d51a96418c0d04004986e410e87f6b4",
+                "reference": "4d7de2fe0d51a96418c0d04004986e410e87f6b4",
+                "shasum": ""
+            },
+            "require": {
+                "ext-hash": "*",
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "ext-openssl": "*",
+                "ext-sodium": "*",
+                "lcobucci/clock": "^2.0 || ^3.0",
+                "php": "^7.4 || ^8.0"
+            },
+            "require-dev": {
+                "infection/infection": "^0.21",
+                "lcobucci/coding-standard": "^6.0",
+                "mikey179/vfsstream": "^1.6.7",
+                "phpbench/phpbench": "^1.2",
+                "phpstan/extension-installer": "^1.0",
+                "phpstan/phpstan": "^1.4",
+                "phpstan/phpstan-deprecation-rules": "^1.0",
+                "phpstan/phpstan-phpunit": "^1.0",
+                "phpstan/phpstan-strict-rules": "^1.0",
+                "phpunit/php-invoker": "^3.1",
+                "phpunit/phpunit": "^9.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Lcobucci\\JWT\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Luís Cobucci",
+                    "email": "lcobucci@gmail.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A simple library to work with JSON Web Token and JSON Web Signature",
+            "keywords": [
+                "JWS",
+                "jwt"
+            ],
+            "support": {
+                "issues": "https://github.com/lcobucci/jwt/issues",
+                "source": "https://github.com/lcobucci/jwt/tree/4.3.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/lcobucci",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/lcobucci",
+                    "type": "patreon"
+                }
+            ],
+            "time": "2023-01-02T13:28:00+00:00"
+        },
+        {
+            "name": "league/event",
+            "version": "2.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/event.git",
+                "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/event/zipball/d2cc124cf9a3fab2bb4ff963307f60361ce4d119",
+                "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4.0"
+            },
+            "require-dev": {
+                "henrikbjorn/phpspec-code-coverage": "~1.0.1",
+                "phpspec/phpspec": "^2.2"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.2-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "League\\Event\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Frank de Jonge",
+                    "email": "info@frenky.net"
+                }
+            ],
+            "description": "Event package",
+            "keywords": [
+                "emitter",
+                "event",
+                "listener"
+            ],
+            "support": {
+                "issues": "https://github.com/thephpleague/event/issues",
+                "source": "https://github.com/thephpleague/event/tree/master"
+            },
+            "time": "2018-11-26T11:52:41+00:00"
+        },
+        {
+            "name": "league/oauth2-server",
+            "version": "8.4.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/oauth2-server.git",
+                "reference": "eed31d86d8cc8e6e9c9f58fbb2113494f8b41e24"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/eed31d86d8cc8e6e9c9f58fbb2113494f8b41e24",
+                "reference": "eed31d86d8cc8e6e9c9f58fbb2113494f8b41e24",
+                "shasum": ""
+            },
+            "require": {
+                "defuse/php-encryption": "^2.2.1",
+                "ext-json": "*",
+                "ext-openssl": "*",
+                "lcobucci/jwt": "^3.4.6 || ^4.0.4",
+                "league/event": "^2.2",
+                "league/uri": "^6.4",
+                "php": "^7.2 || ^8.0",
+                "psr/http-message": "^1.0.1"
+            },
+            "replace": {
+                "league/oauth2server": "*",
+                "lncd/oauth2": "*"
+            },
+            "require-dev": {
+                "laminas/laminas-diactoros": "^2.4.1",
+                "phpstan/phpstan": "^0.12.57",
+                "phpstan/phpstan-phpunit": "^0.12.16",
+                "phpunit/phpunit": "^8.5.13",
+                "roave/security-advisories": "dev-master"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "League\\OAuth2\\Server\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Alex Bilbie",
+                    "email": "hello@alexbilbie.com",
+                    "homepage": "http://www.alexbilbie.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Andy Millington",
+                    "email": "andrew@noexceptions.io",
+                    "homepage": "https://www.noexceptions.io",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.",
+            "homepage": "https://oauth2.thephpleague.com/",
+            "keywords": [
+                "Authentication",
+                "api",
+                "auth",
+                "authorisation",
+                "authorization",
+                "oauth",
+                "oauth 2",
+                "oauth 2.0",
+                "oauth2",
+                "protect",
+                "resource",
+                "secure",
+                "server"
+            ],
+            "support": {
+                "issues": "https://github.com/thephpleague/oauth2-server/issues",
+                "source": "https://github.com/thephpleague/oauth2-server/tree/8.4.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sephster",
+                    "type": "github"
+                }
+            ],
+            "time": "2023-03-22T11:47:53+00:00"
+        },
+        {
+            "name": "league/uri",
+            "version": "6.7.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/uri.git",
+                "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/uri/zipball/d3b50812dd51f3fbf176344cc2981db03d10fe06",
+                "reference": "d3b50812dd51f3fbf176344cc2981db03d10fe06",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "league/uri-interfaces": "^2.3",
+                "php": "^7.4 || ^8.0",
+                "psr/http-message": "^1.0"
+            },
+            "conflict": {
+                "league/uri-schemes": "^1.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^v3.3.2",
+                "nyholm/psr7": "^1.5",
+                "php-http/psr7-integration-tests": "^1.1",
+                "phpstan/phpstan": "^1.2.0",
+                "phpstan/phpstan-deprecation-rules": "^1.0",
+                "phpstan/phpstan-phpunit": "^1.0.0",
+                "phpstan/phpstan-strict-rules": "^1.1.0",
+                "phpunit/phpunit": "^9.5.10",
+                "psr/http-factory": "^1.0"
+            },
+            "suggest": {
+                "ext-fileinfo": "Needed to create Data URI from a filepath",
+                "ext-intl": "Needed to improve host validation",
+                "league/uri-components": "Needed to easily manipulate URI objects",
+                "psr/http-factory": "Needed to use the URI factory"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "League\\Uri\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ignace Nyamagana Butera",
+                    "email": "nyamsprod@gmail.com",
+                    "homepage": "https://nyamsprod.com"
+                }
+            ],
+            "description": "URI manipulation library",
+            "homepage": "https://uri.thephpleague.com",
+            "keywords": [
+                "data-uri",
+                "file-uri",
+                "ftp",
+                "hostname",
+                "http",
+                "https",
+                "middleware",
+                "parse_str",
+                "parse_url",
+                "psr-7",
+                "query-string",
+                "querystring",
+                "rfc3986",
+                "rfc3987",
+                "rfc6570",
+                "uri",
+                "uri-template",
+                "url",
+                "ws"
+            ],
+            "support": {
+                "docs": "https://uri.thephpleague.com",
+                "forum": "https://thephpleague.slack.com",
+                "issues": "https://github.com/thephpleague/uri/issues",
+                "source": "https://github.com/thephpleague/uri/tree/6.7.2"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/nyamsprod",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-09-13T19:50:42+00:00"
+        },
+        {
+            "name": "league/uri-interfaces",
+            "version": "2.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/uri-interfaces.git",
+                "reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/00e7e2943f76d8cb50c7dfdc2f6dee356e15e383",
+                "reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^2.19",
+                "phpstan/phpstan": "^0.12.90",
+                "phpstan/phpstan-phpunit": "^0.12.19",
+                "phpstan/phpstan-strict-rules": "^0.12.9",
+                "phpunit/phpunit": "^8.5.15 || ^9.5"
+            },
+            "suggest": {
+                "ext-intl": "to use the IDNA feature",
+                "symfony/intl": "to use the IDNA feature via Symfony Polyfill"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "League\\Uri\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ignace Nyamagana Butera",
+                    "email": "nyamsprod@gmail.com",
+                    "homepage": "https://nyamsprod.com"
+                }
+            ],
+            "description": "Common interface for URI representation",
+            "homepage": "http://github.com/thephpleague/uri-interfaces",
+            "keywords": [
+                "rfc3986",
+                "rfc3987",
+                "uri",
+                "url"
+            ],
+            "support": {
+                "issues": "https://github.com/thephpleague/uri-interfaces/issues",
+                "source": "https://github.com/thephpleague/uri-interfaces/tree/2.3.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/nyamsprod",
+                    "type": "github"
+                }
+            ],
+            "time": "2021-06-28T04:27:21+00:00"
+        },
+        {
+            "name": "myclabs/deep-copy",
+            "version": "1.11.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/myclabs/DeepCopy.git",
+                "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+                "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "conflict": {
+                "doctrine/collections": "<1.6.8",
+                "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+            },
+            "require-dev": {
+                "doctrine/collections": "^1.6.8",
+                "doctrine/common": "^2.13.3 || ^3.2.2",
+                "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/DeepCopy/deep_copy.php"
+                ],
+                "psr-4": {
+                    "DeepCopy\\": "src/DeepCopy/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Create deep copies (clones) of your objects",
+            "keywords": [
+                "clone",
                 "copy",
                 "duplicate",
                 "object",
@@ -2184,7 +3321,7 @@
             ],
             "support": {
                 "issues": "https://github.com/myclabs/DeepCopy/issues",
-                "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
+                "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
             },
             "funding": [
                 {
@@ -2192,7 +3329,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-03-03T13:19:32+00:00"
+            "time": "2023-03-08T13:26:56+00:00"
         },
         {
             "name": "netresearch/jsonmapper",
@@ -2245,18 +3382,318 @@
             },
             "time": "2022-12-08T20:46:14+00:00"
         },
+        {
+            "name": "nette/component-model",
+            "version": "v3.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nette/component-model.git",
+                "reference": "9d97c0e1916bbf8e306283ab187834501fd4b1f5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nette/component-model/zipball/9d97c0e1916bbf8e306283ab187834501fd4b1f5",
+                "reference": "9d97c0e1916bbf8e306283ab187834501fd4b1f5",
+                "shasum": ""
+            },
+            "require": {
+                "nette/utils": "^2.5 || ^3.0 || ~4.0.0",
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "nette/tester": "^2.0",
+                "phpstan/phpstan": "^0.12",
+                "tracy/tracy": "^2.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause",
+                "GPL-2.0-only",
+                "GPL-3.0-only"
+            ],
+            "authors": [
+                {
+                    "name": "David Grudl",
+                    "homepage": "https://davidgrudl.com"
+                },
+                {
+                    "name": "Nette Community",
+                    "homepage": "https://nette.org/contributors"
+                }
+            ],
+            "description": "⚛ Nette Component Model",
+            "homepage": "https://nette.org",
+            "keywords": [
+                "components",
+                "nette"
+            ],
+            "support": {
+                "issues": "https://github.com/nette/component-model/issues",
+                "source": "https://github.com/nette/component-model/tree/v3.0.3"
+            },
+            "time": "2023-01-09T20:16:05+00:00"
+        },
+        {
+            "name": "nette/forms",
+            "version": "v3.1.11",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nette/forms.git",
+                "reference": "64cdc2d6796a8fe1265bb21a6ee5e9ff93e2b3a4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nette/forms/zipball/64cdc2d6796a8fe1265bb21a6ee5e9ff93e2b3a4",
+                "reference": "64cdc2d6796a8fe1265bb21a6ee5e9ff93e2b3a4",
+                "shasum": ""
+            },
+            "require": {
+                "nette/component-model": "^3.0",
+                "nette/http": "^3.1",
+                "nette/utils": "^3.2.5 || ~4.0.0",
+                "php": ">=7.2 <8.3"
+            },
+            "conflict": {
+                "latte/latte": ">=3.1"
+            },
+            "require-dev": {
+                "latte/latte": "^2.10.2 || ^3.0.3",
+                "nette/application": "^3.0",
+                "nette/di": "^3.0",
+                "nette/tester": "^2.4",
+                "phpstan/phpstan-nette": "^1",
+                "tracy/tracy": "^2.9"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause",
+                "GPL-2.0-only",
+                "GPL-3.0-only"
+            ],
+            "authors": [
+                {
+                    "name": "David Grudl",
+                    "homepage": "https://davidgrudl.com"
+                },
+                {
+                    "name": "Nette Community",
+                    "homepage": "https://nette.org/contributors"
+                }
+            ],
+            "description": "📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server & client side validation and mature design.",
+            "homepage": "https://nette.org",
+            "keywords": [
+                "Forms",
+                "bootstrap",
+                "csrf",
+                "javascript",
+                "nette",
+                "validation"
+            ],
+            "support": {
+                "issues": "https://github.com/nette/forms/issues",
+                "source": "https://github.com/nette/forms/tree/v3.1.11"
+            },
+            "time": "2023-03-08T23:56:24+00:00"
+        },
+        {
+            "name": "nette/http",
+            "version": "v3.2.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nette/http.git",
+                "reference": "9105c26de3dd47da5e7cf6b4132b5d871f835e25"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nette/http/zipball/9105c26de3dd47da5e7cf6b4132b5d871f835e25",
+                "reference": "9105c26de3dd47da5e7cf6b4132b5d871f835e25",
+                "shasum": ""
+            },
+            "require": {
+                "nette/utils": "^3.2.1 || ~4.0.0",
+                "php": ">=7.2 <8.3"
+            },
+            "conflict": {
+                "nette/di": "<3.0.3",
+                "nette/schema": "<1.2"
+            },
+            "require-dev": {
+                "nette/di": "^3.0",
+                "nette/security": "^3.0",
+                "nette/tester": "^2.4",
+                "phpstan/phpstan": "^1.0",
+                "tracy/tracy": "^2.8"
+            },
+            "suggest": {
+                "ext-fileinfo": "to detect type of uploaded files"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.2-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause",
+                "GPL-2.0-only",
+                "GPL-3.0-only"
+            ],
+            "authors": [
+                {
+                    "name": "David Grudl",
+                    "homepage": "https://davidgrudl.com"
+                },
+                {
+                    "name": "Nette Community",
+                    "homepage": "https://nette.org/contributors"
+                }
+            ],
+            "description": "🌐 Nette Http: abstraction for HTTP request, response and session. Provides careful data sanitization and utility for URL and cookies manipulation.",
+            "homepage": "https://nette.org",
+            "keywords": [
+                "cookies",
+                "http",
+                "nette",
+                "proxy",
+                "request",
+                "response",
+                "security",
+                "session",
+                "url"
+            ],
+            "support": {
+                "issues": "https://github.com/nette/http/issues",
+                "source": "https://github.com/nette/http/tree/v3.2.2"
+            },
+            "time": "2023-03-18T14:55:56+00:00"
+        },
+        {
+            "name": "nette/utils",
+            "version": "v3.2.9",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nette/utils.git",
+                "reference": "c91bac3470c34b2ecd5400f6e6fdf0b64a836a5c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nette/utils/zipball/c91bac3470c34b2ecd5400f6e6fdf0b64a836a5c",
+                "reference": "c91bac3470c34b2ecd5400f6e6fdf0b64a836a5c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2 <8.3"
+            },
+            "conflict": {
+                "nette/di": "<3.0.6"
+            },
+            "require-dev": {
+                "jetbrains/phpstorm-attributes": "dev-master",
+                "nette/tester": "~2.0",
+                "phpstan/phpstan": "^1.0",
+                "tracy/tracy": "^2.3"
+            },
+            "suggest": {
+                "ext-gd": "to use Image",
+                "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
+                "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
+                "ext-json": "to use Nette\\Utils\\Json",
+                "ext-mbstring": "to use Strings::lower() etc...",
+                "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()",
+                "ext-xml": "to use Strings::length() etc. when mbstring is not available"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.2-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause",
+                "GPL-2.0-only",
+                "GPL-3.0-only"
+            ],
+            "authors": [
+                {
+                    "name": "David Grudl",
+                    "homepage": "https://davidgrudl.com"
+                },
+                {
+                    "name": "Nette Community",
+                    "homepage": "https://nette.org/contributors"
+                }
+            ],
+            "description": "🛠  Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
+            "homepage": "https://nette.org",
+            "keywords": [
+                "array",
+                "core",
+                "datetime",
+                "images",
+                "json",
+                "nette",
+                "paginator",
+                "password",
+                "slugify",
+                "string",
+                "unicode",
+                "utf-8",
+                "utility",
+                "validation"
+            ],
+            "support": {
+                "issues": "https://github.com/nette/utils/issues",
+                "source": "https://github.com/nette/utils/tree/v3.2.9"
+            },
+            "time": "2023-01-18T03:26:20+00:00"
+        },
         {
             "name": "nikic/php-parser",
-            "version": "v4.15.3",
+            "version": "v4.15.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039"
+                "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039",
-                "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
+                "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
                 "shasum": ""
             },
             "require": {
@@ -2297,9 +3734,59 @@
             ],
             "support": {
                 "issues": "https://github.com/nikic/PHP-Parser/issues",
-                "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.3"
+                "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4"
+            },
+            "time": "2023-03-05T19:49:14+00:00"
+        },
+        {
+            "name": "paragonie/random_compat",
+            "version": "v9.99.100",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/paragonie/random_compat.git",
+                "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
+                "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">= 7"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "4.*|5.*",
+                "vimeo/psalm": "^1"
+            },
+            "suggest": {
+                "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+            },
+            "type": "library",
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Paragon Initiative Enterprises",
+                    "email": "security@paragonie.com",
+                    "homepage": "https://paragonie.com"
+                }
+            ],
+            "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+            "keywords": [
+                "csprng",
+                "polyfill",
+                "pseudorandom",
+                "random"
+            ],
+            "support": {
+                "email": "info@paragonie.com",
+                "issues": "https://github.com/paragonie/random_compat/issues",
+                "source": "https://github.com/paragonie/random_compat"
             },
-            "time": "2023-01-16T22:05:37+00:00"
+            "time": "2020-10-15T08:29:30+00:00"
         },
         {
             "name": "phar-io/manifest",
@@ -2524,24 +4011,27 @@
         },
         {
             "name": "phpdocumentor/type-resolver",
-            "version": "1.6.2",
+            "version": "1.7.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d"
+                "reference": "dfc078e8af9c99210337325ff5aa152872c98714"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d",
-                "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/dfc078e8af9c99210337325ff5aa152872c98714",
+                "reference": "dfc078e8af9c99210337325ff5aa152872c98714",
                 "shasum": ""
             },
             "require": {
+                "doctrine/deprecations": "^1.0",
                 "php": "^7.4 || ^8.0",
-                "phpdocumentor/reflection-common": "^2.0"
+                "phpdocumentor/reflection-common": "^2.0",
+                "phpstan/phpdoc-parser": "^1.13"
             },
             "require-dev": {
                 "ext-tokenizer": "*",
+                "phpbench/phpbench": "^1.2",
                 "phpstan/extension-installer": "^1.1",
                 "phpstan/phpstan": "^1.8",
                 "phpstan/phpstan-phpunit": "^1.1",
@@ -2573,22 +4063,22 @@
             "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
             "support": {
                 "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
-                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2"
+                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.1"
             },
-            "time": "2022-10-14T12:47:21+00:00"
+            "time": "2023-03-27T19:02:04+00:00"
         },
         {
             "name": "phpmailer/phpmailer",
-            "version": "v6.7.1",
+            "version": "v6.8.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHPMailer/PHPMailer.git",
-                "reference": "49cd7ea3d2563f028d7811f06864a53b1f15ff55"
+                "reference": "df16b615e371d81fb79e506277faea67a1be18f1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/49cd7ea3d2563f028d7811f06864a53b1f15ff55",
-                "reference": "49cd7ea3d2563f028d7811f06864a53b1f15ff55",
+                "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/df16b615e371d81fb79e506277faea67a1be18f1",
+                "reference": "df16b615e371d81fb79e506277faea67a1be18f1",
                 "shasum": ""
             },
             "require": {
@@ -2625,57 +4115,102 @@
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "LGPL-2.1-only"
-            ],
-            "authors": [
-                {
-                    "name": "Marcus Bointon",
-                    "email": "phpmailer@synchromedia.co.uk"
-                },
-                {
-                    "name": "Jim Jagielski",
-                    "email": "jimjag@gmail.com"
-                },
-                {
-                    "name": "Andy Prevost",
-                    "email": "codeworxtech@users.sourceforge.net"
-                },
-                {
-                    "name": "Brent R. Matzelle"
-                }
+                "LGPL-2.1-only"
+            ],
+            "authors": [
+                {
+                    "name": "Marcus Bointon",
+                    "email": "phpmailer@synchromedia.co.uk"
+                },
+                {
+                    "name": "Jim Jagielski",
+                    "email": "jimjag@gmail.com"
+                },
+                {
+                    "name": "Andy Prevost",
+                    "email": "codeworxtech@users.sourceforge.net"
+                },
+                {
+                    "name": "Brent R. Matzelle"
+                }
+            ],
+            "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.8.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/Synchro",
+                    "type": "github"
+                }
+            ],
+            "time": "2023-03-06T14:43:22+00:00"
+        },
+        {
+            "name": "phpstan/phpdoc-parser",
+            "version": "1.17.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpstan/phpdoc-parser.git",
+                "reference": "d3753fcb3abc6f78f5de6f72153d4b9c99c72dee"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/d3753fcb3abc6f78f5de6f72153d4b9c99c72dee",
+                "reference": "d3753fcb3abc6f78f5de6f72153d4b9c99c72dee",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpstan/extension-installer": "^1.0",
+                "phpstan/phpstan": "^1.5",
+                "phpstan/phpstan-phpunit": "^1.1",
+                "phpstan/phpstan-strict-rules": "^1.0",
+                "phpunit/phpunit": "^9.5",
+                "symfony/process": "^5.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "PHPStan\\PhpDocParser\\": [
+                        "src/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
             ],
-            "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
+            "description": "PHPDoc parser with support for nullable, intersection and generic types",
             "support": {
-                "issues": "https://github.com/PHPMailer/PHPMailer/issues",
-                "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.7.1"
+                "issues": "https://github.com/phpstan/phpdoc-parser/issues",
+                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.17.1"
             },
-            "funding": [
-                {
-                    "url": "https://github.com/Synchro",
-                    "type": "github"
-                }
-            ],
-            "time": "2022-12-08T13:30:06+00:00"
+            "time": "2023-04-04T11:11:22+00:00"
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "9.2.24",
+            "version": "9.2.26",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed"
+                "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed",
-                "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",
+                "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-libxml": "*",
                 "ext-xmlwriter": "*",
-                "nikic/php-parser": "^4.14",
+                "nikic/php-parser": "^4.15",
                 "php": ">=7.3",
                 "phpunit/php-file-iterator": "^3.0.3",
                 "phpunit/php-text-template": "^2.0.2",
@@ -2690,8 +4225,8 @@
                 "phpunit/phpunit": "^9.3"
             },
             "suggest": {
-                "ext-pcov": "*",
-                "ext-xdebug": "*"
+                "ext-pcov": "PHP extension that provides line coverage",
+                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
             },
             "type": "library",
             "extra": {
@@ -2724,7 +4259,7 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
-                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24"
+                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26"
             },
             "funding": [
                 {
@@ -2732,7 +4267,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-01-26T08:26:55+00:00"
+            "time": "2023-03-06T12:58:08+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
@@ -2977,16 +4512,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "9.6.3",
+            "version": "9.6.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555"
+                "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7b1615e3e887d6c719121c6d4a44b0ab9645555",
-                "reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b65d59a059d3004a040c16a82e07bbdf6cfdd115",
+                "reference": "b65d59a059d3004a040c16a82e07bbdf6cfdd115",
                 "shasum": ""
             },
             "require": {
@@ -3019,8 +4554,8 @@
                 "sebastian/version": "^3.0.2"
             },
             "suggest": {
-                "ext-soap": "*",
-                "ext-xdebug": "*"
+                "ext-soap": "To be able to generate mocks based on WSDL files",
+                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
             },
             "bin": [
                 "phpunit"
@@ -3059,7 +4594,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.3"
+                "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.6"
             },
             "funding": [
                 {
@@ -3075,7 +4611,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-04T13:37:15+00:00"
+            "time": "2023-03-27T11:43:46+00:00"
         },
         {
             "name": "psr/container",
@@ -3175,6 +4711,267 @@
             },
             "time": "2019-01-08T18:20:26+00:00"
         },
+        {
+            "name": "psr/http-client",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-client.git",
+                "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+                "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0 || ^8.0",
+                "psr/http-message": "^1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Client\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP clients",
+            "homepage": "https://github.com/php-fig/http-client",
+            "keywords": [
+                "http",
+                "http-client",
+                "psr",
+                "psr-18"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/http-client/tree/master"
+            },
+            "time": "2020-06-29T06:28:15+00:00"
+        },
+        {
+            "name": "psr/http-factory",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-factory.git",
+                "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+                "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0.0",
+                "psr/http-message": "^1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Message\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interfaces for PSR-7 HTTP message factories",
+            "keywords": [
+                "factory",
+                "http",
+                "message",
+                "psr",
+                "psr-17",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/http-factory/tree/master"
+            },
+            "time": "2019-04-30T12:38:16+00:00"
+        },
+        {
+            "name": "psr/http-message",
+            "version": "1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-message.git",
+                "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
+                "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Message\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP messages",
+            "homepage": "https://github.com/php-fig/http-message",
+            "keywords": [
+                "http",
+                "http-message",
+                "psr",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/http-message/tree/1.1"
+            },
+            "time": "2023-04-04T09:50:52+00:00"
+        },
+        {
+            "name": "psr/http-server-handler",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-server-handler.git",
+                "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
+                "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0",
+                "psr/http-message": "^1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Server\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP server-side request handler",
+            "keywords": [
+                "handler",
+                "http",
+                "http-interop",
+                "psr",
+                "psr-15",
+                "psr-7",
+                "request",
+                "response",
+                "server"
+            ],
+            "support": {
+                "issues": "https://github.com/php-fig/http-server-handler/issues",
+                "source": "https://github.com/php-fig/http-server-handler/tree/master"
+            },
+            "time": "2018-10-30T16:46:14+00:00"
+        },
+        {
+            "name": "ralouphie/getallheaders",
+            "version": "3.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ralouphie/getallheaders.git",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.1",
+                "phpunit/phpunit": "^5 || ^6.5"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/getallheaders.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ralph Khattar",
+                    "email": "ralph.khattar@gmail.com"
+                }
+            ],
+            "description": "A polyfill for getallheaders.",
+            "support": {
+                "issues": "https://github.com/ralouphie/getallheaders/issues",
+                "source": "https://github.com/ralouphie/getallheaders/tree/develop"
+            },
+            "time": "2019-03-08T08:55:37+00:00"
+        },
         {
             "name": "react/promise",
             "version": "v2.9.0",
@@ -4432,16 +6229,16 @@
         },
         {
             "name": "simplesamlphp/saml2",
-            "version": "v4.6.5",
+            "version": "v4.6.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/saml2.git",
-                "reference": "35e4cac48ef97d454d25a92eb24c85cadf96de9d"
+                "reference": "717c0adc4877ebd58428637e5626345e59fa0109"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/35e4cac48ef97d454d25a92eb24c85cadf96de9d",
-                "reference": "35e4cac48ef97d454d25a92eb24c85cadf96de9d",
+                "url": "https://api.github.com/repos/simplesamlphp/saml2/zipball/717c0adc4877ebd58428637e5626345e59fa0109",
+                "reference": "717c0adc4877ebd58428637e5626345e59fa0109",
                 "shasum": ""
             },
             "require": {
@@ -4484,22 +6281,22 @@
             "description": "SAML2 PHP library from SimpleSAMLphp",
             "support": {
                 "issues": "https://github.com/simplesamlphp/saml2/issues",
-                "source": "https://github.com/simplesamlphp/saml2/tree/v4.6.5"
+                "source": "https://github.com/simplesamlphp/saml2/tree/v4.6.6"
             },
-            "time": "2022-11-23T12:50:43+00:00"
+            "time": "2023-03-08T19:32:49+00:00"
         },
         {
             "name": "simplesamlphp/simplesamlphp",
-            "version": "v2.0.0-rc3",
+            "version": "2.0.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/simplesamlphp.git",
-                "reference": "052359245640b596e459599a6d25e9f4be97b198"
+                "reference": "de912366cb73087889c580dca354582e8ef560e0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp/zipball/052359245640b596e459599a6d25e9f4be97b198",
-                "reference": "052359245640b596e459599a6d25e9f4be97b198",
+                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp/zipball/de912366cb73087889c580dca354582e8ef560e0",
+                "reference": "de912366cb73087889c580dca354582e8ef560e0",
                 "shasum": ""
             },
             "require": {
@@ -4521,7 +6318,7 @@
                 "simplesamlphp/assert": "^0.8.0",
                 "simplesamlphp/composer-module-installer": "^1.3.0",
                 "simplesamlphp/saml2": "^4.6",
-                "simplesamlphp/simplesamlphp-assets-base": "^2.0.0",
+                "simplesamlphp/simplesamlphp-assets-base": "^2.0",
                 "symfony/cache": "^5.4",
                 "symfony/config": "^5.4",
                 "symfony/console": "^5.4",
@@ -4591,7 +6388,7 @@
                 }
             ],
             "description": "A PHP implementation of a SAML 2.0 service provider and identity provider.",
-            "homepage": "http://simplesamlphp.org",
+            "homepage": "https://simplesamlphp.org",
             "keywords": [
                 "SAML2",
                 "idp",
@@ -4604,20 +6401,20 @@
                 "issues": "https://github.com/simplesamlphp/simplesamlphp/issues",
                 "source": "https://github.com/simplesamlphp/simplesamlphp"
             },
-            "time": "2023-01-31T12:11:10+00:00"
+            "time": "2023-03-29T20:24:27+00:00"
         },
         {
             "name": "simplesamlphp/simplesamlphp-assets-base",
-            "version": "v2.0.3",
+            "version": "v2.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/simplesamlphp-assets-base.git",
-                "reference": "dcc7c7e485a6e6f03e6b2ff7abf64a2149a2fdd0"
+                "reference": "d2aed5063349880897515b71fca85300e5fad2c9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-assets-base/zipball/dcc7c7e485a6e6f03e6b2ff7abf64a2149a2fdd0",
-                "reference": "dcc7c7e485a6e6f03e6b2ff7abf64a2149a2fdd0",
+                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-assets-base/zipball/d2aed5063349880897515b71fca85300e5fad2c9",
+                "reference": "d2aed5063349880897515b71fca85300e5fad2c9",
                 "shasum": ""
             },
             "require": {
@@ -4638,41 +6435,117 @@
             "description": "Assets for the SimpleSAMLphp main repository",
             "support": {
                 "issues": "https://github.com/simplesamlphp/simplesamlphp-assets-base/issues",
-                "source": "https://github.com/simplesamlphp/simplesamlphp-assets-base/tree/v2.0.3"
+                "source": "https://github.com/simplesamlphp/simplesamlphp-assets-base/tree/v2.0.4"
+            },
+            "time": "2023-02-27T17:17:05+00:00"
+        },
+        {
+            "name": "simplesamlphp/simplesamlphp-module-oidc",
+            "version": "v3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/simplesamlphp/simplesamlphp-module-oidc.git",
+                "reference": "28679773dbc795756d7980006b58e2599701ad53"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-module-oidc/zipball/28679773dbc795756d7980006b58e2599701ad53",
+                "reference": "28679773dbc795756d7980006b58e2599701ad53",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": ">=7.4",
+                "ext-json": "*",
+                "ext-openssl": "*",
+                "ext-pdo": "*",
+                "guzzlehttp/guzzle": "^7.0",
+                "laminas/laminas-diactoros": "^2.2.1",
+                "laminas/laminas-httphandlerrunner": "^1.1.0",
+                "lcobucci/jwt": "^4.1",
+                "league/oauth2-server": "^8.1.0",
+                "nette/forms": "^3",
+                "php": ">=7.4",
+                "psr/container": "^1.0",
+                "psr/log": "^1.1",
+                "simplesamlphp/composer-module-installer": "^1.2",
+                "spomky-labs/base64url": "^2.0",
+                "steverhoades/oauth2-openid-connect-server": "^2.0",
+                "web-token/jwt-framework": "^2.1"
             },
-            "time": "2023-02-22T12:34:35+00:00"
+            "require-dev": {
+                "friends-of-phpspec/phpspec-code-coverage": "^6.1",
+                "friendsofphp/php-cs-fixer": "^3",
+                "phpspec/phpspec": "^7.1.0",
+                "phpunit/php-code-coverage": "^9.0.0",
+                "phpunit/phpcov": "^8.2.0",
+                "phpunit/phpunit": "^9.0.0",
+                "simplesamlphp/simplesamlphp": "^v2.0.0",
+                "simplesamlphp/simplesamlphp-test-framework": "^1.2.1",
+                "squizlabs/php_codesniffer": "^3.7",
+                "vimeo/psalm": "^5.8"
+            },
+            "type": "simplesamlphp-module",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "SimpleSAML\\Module\\oidc\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Spanish Research and Academic Network"
+                },
+                {
+                    "name": "University of Córdoba"
+                },
+                {
+                    "name": "Sergio Gómez",
+                    "email": "sergio@uco.es"
+                }
+            ],
+            "description": "A SimpleSAMLphp module adding support for the OpenID Connect protocol",
+            "keywords": [
+                "OpenID Connect",
+                "OpenId",
+                "connect",
+                "oauth2",
+                "oidc"
+            ],
+            "support": {
+                "issues": "https://github.com/simplesamlphp/simplesamlphp-module-oidc/issues",
+                "source": "https://github.com/simplesamlphp/simplesamlphp-module-oidc/tree/v3.0.0"
+            },
+            "time": "2023-03-22T08:49:10+00:00"
         },
         {
             "name": "simplesamlphp/simplesamlphp-test-framework",
-            "version": "v1.2.2",
+            "version": "v1.5.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/simplesamlphp/simplesamlphp-test-framework.git",
-                "reference": "9e39e7ed40da8324c901e997bae7c749621b2859"
+                "reference": "b627dd12d1d5bb50cef5336b9726f3a2d1b4969e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-test-framework/zipball/9e39e7ed40da8324c901e997bae7c749621b2859",
-                "reference": "9e39e7ed40da8324c901e997bae7c749621b2859",
+                "url": "https://api.github.com/repos/simplesamlphp/simplesamlphp-test-framework/zipball/b627dd12d1d5bb50cef5336b9726f3a2d1b4969e",
+                "reference": "b627dd12d1d5bb50cef5336b9726f3a2d1b4969e",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.4|^8.0",
-                "phpunit/phpunit": "^8.5|^9.5",
-                "squizlabs/php_codesniffer": "^3.6",
-                "symfony/phpunit-bridge": "^6.0",
-                "vimeo/psalm": "^4.20|^5.0.0-beta1"
+                "phpunit/phpunit": "^9.6 || ^10.0"
             },
             "require-dev": {
                 "ext-curl": "*",
-                "simplesamlphp/simplesamlphp": "dev-master"
+                "simplesamlphp/simplesamlphp": "^2.0.0"
             },
-            "bin": [
-                "bin/check-syntax-json.sh",
-                "bin/check-syntax-php.sh",
-                "bin/check-syntax-xml.sh",
-                "bin/check-syntax-yaml.sh"
-            ],
             "type": "project",
             "autoload": {
                 "psr-4": {
@@ -4697,7 +6570,7 @@
                 "issues": "https://github.com/simplesamlphp/simplesamlphp-test-framework/issues",
                 "source": "https://github.com/simplesamlphp/simplesamlphp-test-framework"
             },
-            "time": "2023-01-12T16:20:27+00:00"
+            "time": "2023-03-16T20:42:22+00:00"
         },
         {
             "name": "spatie/array-to-xml",
@@ -4763,18 +6636,153 @@
             ],
             "time": "2022-12-26T08:22:07+00:00"
         },
+        {
+            "name": "spomky-labs/aes-key-wrap",
+            "version": "v6.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Spomky-Labs/aes-key-wrap.git",
+                "reference": "97388255a37ad6fb1ed332d07e61fa2b7bb62e0d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Spomky-Labs/aes-key-wrap/zipball/97388255a37ad6fb1ed332d07e61fa2b7bb62e0d",
+                "reference": "97388255a37ad6fb1ed332d07e61fa2b7bb62e0d",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "lib-openssl": "*",
+                "php": ">=7.2",
+                "thecodingmachine/safe": "^1.1"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.0",
+                "phpstan/phpstan": "^0.12",
+                "phpstan/phpstan-beberlei-assert": "^0.12",
+                "phpstan/phpstan-deprecation-rules": "^0.12",
+                "phpstan/phpstan-phpunit": "^0.12",
+                "phpstan/phpstan-strict-rules": "^0.12",
+                "phpunit/phpunit": "^7.0|^8.0|^9.0",
+                "thecodingmachine/phpstan-safe-rule": "^1.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "AESKW\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Florent Morselli",
+                    "homepage": "https://github.com/Spomky-Labs/aes-key-wrap/contributors"
+                }
+            ],
+            "description": "AES Key Wrap for PHP.",
+            "homepage": "https://github.com/Spomky-Labs/aes-key-wrap",
+            "keywords": [
+                "A128KW",
+                "A192KW",
+                "A256KW",
+                "RFC3394",
+                "RFC5649",
+                "aes",
+                "key",
+                "padding",
+                "wrap"
+            ],
+            "support": {
+                "issues": "https://github.com/Spomky-Labs/aes-key-wrap/issues",
+                "source": "https://github.com/Spomky-Labs/aes-key-wrap/tree/v6.0.0"
+            },
+            "time": "2020-08-01T14:07:55+00:00"
+        },
+        {
+            "name": "spomky-labs/base64url",
+            "version": "v2.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Spomky-Labs/base64url.git",
+                "reference": "7752ce931ec285da4ed1f4c5aa27e45e097be61d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Spomky-Labs/base64url/zipball/7752ce931ec285da4ed1f4c5aa27e45e097be61d",
+                "reference": "7752ce931ec285da4ed1f4c5aa27e45e097be61d",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpstan/extension-installer": "^1.0",
+                "phpstan/phpstan": "^0.11|^0.12",
+                "phpstan/phpstan-beberlei-assert": "^0.11|^0.12",
+                "phpstan/phpstan-deprecation-rules": "^0.11|^0.12",
+                "phpstan/phpstan-phpunit": "^0.11|^0.12",
+                "phpstan/phpstan-strict-rules": "^0.11|^0.12"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Base64Url\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Florent Morselli",
+                    "homepage": "https://github.com/Spomky-Labs/base64url/contributors"
+                }
+            ],
+            "description": "Base 64 URL Safe Encoding/Decoding PHP Library",
+            "homepage": "https://github.com/Spomky-Labs/base64url",
+            "keywords": [
+                "base64",
+                "rfc4648",
+                "safe",
+                "url"
+            ],
+            "support": {
+                "issues": "https://github.com/Spomky-Labs/base64url/issues",
+                "source": "https://github.com/Spomky-Labs/base64url/tree/v2.0.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/Spomky",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/FlorentMorselli",
+                    "type": "patreon"
+                }
+            ],
+            "time": "2020-11-03T09:10:25+00:00"
+        },
         {
             "name": "squizlabs/php_codesniffer",
-            "version": "3.7.1",
+            "version": "3.7.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
-                "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619"
+                "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619",
-                "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619",
+                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
+                "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
                 "shasum": ""
             },
             "require": {
@@ -4810,27 +6818,73 @@
             "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
             "keywords": [
                 "phpcs",
-                "standards"
+                "standards",
+                "static analysis"
             ],
             "support": {
                 "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
                 "source": "https://github.com/squizlabs/PHP_CodeSniffer",
                 "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
             },
-            "time": "2022-06-18T07:21:10+00:00"
+            "time": "2023-02-22T23:07:41+00:00"
+        },
+        {
+            "name": "steverhoades/oauth2-openid-connect-server",
+            "version": "v2.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/steverhoades/oauth2-openid-connect-server.git",
+                "reference": "23381585ebb410ffa11ca9eb0fdba3895fb23119"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/steverhoades/oauth2-openid-connect-server/zipball/23381585ebb410ffa11ca9eb0fdba3895fb23119",
+                "reference": "23381585ebb410ffa11ca9eb0fdba3895fb23119",
+                "shasum": ""
+            },
+            "require": {
+                "lcobucci/jwt": "4.1.5|^4.2",
+                "league/oauth2-server": "^5.1|^6.0|^7.0|^8.0"
+            },
+            "require-dev": {
+                "laminas/laminas-diactoros": "^1.3.2",
+                "phpunit/phpunit": "^5.0|^9.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "OpenIDConnectServer\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Steve Rhoades",
+                    "email": "sedonami@gmail.com"
+                }
+            ],
+            "description": "An OpenID Connect Server that sites on The PHP League's OAuth2 Server",
+            "support": {
+                "issues": "https://github.com/steverhoades/oauth2-openid-connect-server/issues",
+                "source": "https://github.com/steverhoades/oauth2-openid-connect-server/tree/v2.5.0"
+            },
+            "time": "2023-01-19T16:49:09+00:00"
         },
         {
             "name": "symfony/cache",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/cache.git",
-                "reference": "e9147c89fdfdc5d5ef798bb7193f23726ad609f5"
+                "reference": "5ed986c4ef65f0dea5e9753630b5cb1f07f847d6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/cache/zipball/e9147c89fdfdc5d5ef798bb7193f23726ad609f5",
-                "reference": "e9147c89fdfdc5d5ef798bb7193f23726ad609f5",
+                "url": "https://api.github.com/repos/symfony/cache/zipball/5ed986c4ef65f0dea5e9753630b5cb1f07f847d6",
+                "reference": "5ed986c4ef65f0dea5e9753630b5cb1f07f847d6",
                 "shasum": ""
             },
             "require": {
@@ -4898,7 +6952,7 @@
                 "psr6"
             ],
             "support": {
-                "source": "https://github.com/symfony/cache/tree/v5.4.19"
+                "source": "https://github.com/symfony/cache/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -4914,7 +6968,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-19T09:49:58+00:00"
+            "time": "2023-03-29T20:01:08+00:00"
         },
         {
             "name": "symfony/cache-contracts",
@@ -4997,16 +7051,16 @@
         },
         {
             "name": "symfony/config",
-            "version": "v5.4.19",
+            "version": "v5.4.21",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git",
-                "reference": "9bd60843443cda9638efdca7c41eb82ed0026179"
+                "reference": "2a6b1111d038adfa15d52c0871e540f3b352d1e4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/config/zipball/9bd60843443cda9638efdca7c41eb82ed0026179",
-                "reference": "9bd60843443cda9638efdca7c41eb82ed0026179",
+                "url": "https://api.github.com/repos/symfony/config/zipball/2a6b1111d038adfa15d52c0871e540f3b352d1e4",
+                "reference": "2a6b1111d038adfa15d52c0871e540f3b352d1e4",
                 "shasum": ""
             },
             "require": {
@@ -5056,7 +7110,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.19"
+                "source": "https://github.com/symfony/config/tree/v5.4.21"
             },
             "funding": [
                 {
@@ -5072,20 +7126,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-08T13:23:55+00:00"
+            "time": "2023-02-14T08:03:56+00:00"
         },
         {
             "name": "symfony/console",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "dccb8d251a9017d5994c988b034d3e18aaabf740"
+                "reference": "3cd51fd2e6c461ca678f84d419461281bd87a0a8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/dccb8d251a9017d5994c988b034d3e18aaabf740",
-                "reference": "dccb8d251a9017d5994c988b034d3e18aaabf740",
+                "url": "https://api.github.com/repos/symfony/console/zipball/3cd51fd2e6c461ca678f84d419461281bd87a0a8",
+                "reference": "3cd51fd2e6c461ca678f84d419461281bd87a0a8",
                 "shasum": ""
             },
             "require": {
@@ -5150,12 +7204,12 @@
             "homepage": "https://symfony.com",
             "keywords": [
                 "cli",
-                "command line",
+                "command-line",
                 "console",
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v5.4.19"
+                "source": "https://github.com/symfony/console/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -5171,20 +7225,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-01T08:32:19+00:00"
+            "time": "2023-03-25T09:27:28+00:00"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v5.4.20",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git",
-                "reference": "8185ed0df129005a26715902f1a53bad0fe67102"
+                "reference": "e1b7c1432efb4ad1dd89d62906187271e2601ed9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/8185ed0df129005a26715902f1a53bad0fe67102",
-                "reference": "8185ed0df129005a26715902f1a53bad0fe67102",
+                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e1b7c1432efb4ad1dd89d62906187271e2601ed9",
+                "reference": "e1b7c1432efb4ad1dd89d62906187271e2601ed9",
                 "shasum": ""
             },
             "require": {
@@ -5244,7 +7298,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.20"
+                "source": "https://github.com/symfony/dependency-injection/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -5260,7 +7314,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-27T11:08:11+00:00"
+            "time": "2023-03-10T10:02:45+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
@@ -5331,16 +7385,16 @@
         },
         {
             "name": "symfony/error-handler",
-            "version": "v5.4.19",
+            "version": "v5.4.21",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/error-handler.git",
-                "reference": "438ef3e5e6481244785da3ce8cf8f4e74e7f2822"
+                "reference": "56a94aa8cb5a5fbc411551d8d014a296b5456549"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/error-handler/zipball/438ef3e5e6481244785da3ce8cf8f4e74e7f2822",
-                "reference": "438ef3e5e6481244785da3ce8cf8f4e74e7f2822",
+                "url": "https://api.github.com/repos/symfony/error-handler/zipball/56a94aa8cb5a5fbc411551d8d014a296b5456549",
+                "reference": "56a94aa8cb5a5fbc411551d8d014a296b5456549",
                 "shasum": ""
             },
             "require": {
@@ -5382,7 +7436,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.19"
+                "source": "https://github.com/symfony/error-handler/tree/v5.4.21"
             },
             "funding": [
                 {
@@ -5398,20 +7452,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-01T08:32:19+00:00"
+            "time": "2023-02-14T08:03:56+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "abf49cc084c087d94b4cb939c3f3672971784e0c"
+                "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/abf49cc084c087d94b4cb939c3f3672971784e0c",
-                "reference": "abf49cc084c087d94b4cb939c3f3672971784e0c",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1df20e45d56da29a4b1d8259dd6e950acbf1b13f",
+                "reference": "1df20e45d56da29a4b1d8259dd6e950acbf1b13f",
                 "shasum": ""
             },
             "require": {
@@ -5467,7 +7521,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.19"
+                "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -5483,7 +7537,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-01T08:32:19+00:00"
+            "time": "2023-03-17T11:31:58+00:00"
         },
         {
             "name": "symfony/event-dispatcher-contracts",
@@ -5566,16 +7620,16 @@
         },
         {
             "name": "symfony/filesystem",
-            "version": "v5.4.19",
+            "version": "v5.4.21",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "648bfaca6a494f3e22378123bcee2894045dc9d8"
+                "reference": "e75960b1bbfd2b8c9e483e0d74811d555ca3de9f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/648bfaca6a494f3e22378123bcee2894045dc9d8",
-                "reference": "648bfaca6a494f3e22378123bcee2894045dc9d8",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/e75960b1bbfd2b8c9e483e0d74811d555ca3de9f",
+                "reference": "e75960b1bbfd2b8c9e483e0d74811d555ca3de9f",
                 "shasum": ""
             },
             "require": {
@@ -5610,7 +7664,7 @@
             "description": "Provides basic utilities for the filesystem",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/filesystem/tree/v5.4.19"
+                "source": "https://github.com/symfony/filesystem/tree/v5.4.21"
             },
             "funding": [
                 {
@@ -5626,20 +7680,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-14T19:14:44+00:00"
+            "time": "2023-02-14T08:03:56+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v5.4.19",
+            "version": "v5.4.21",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "6071aebf810ad13fe8200c224f36103abb37cf1f"
+                "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/6071aebf810ad13fe8200c224f36103abb37cf1f",
-                "reference": "6071aebf810ad13fe8200c224f36103abb37cf1f",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19",
+                "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19",
                 "shasum": ""
             },
             "require": {
@@ -5673,7 +7727,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.19"
+                "source": "https://github.com/symfony/finder/tree/v5.4.21"
             },
             "funding": [
                 {
@@ -5689,20 +7743,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-14T19:14:44+00:00"
+            "time": "2023-02-16T09:33:00+00:00"
         },
         {
             "name": "symfony/framework-bundle",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/framework-bundle.git",
-                "reference": "a208ee578000f9dedcb50a9784ec7ff8706a7bf1"
+                "reference": "6cb4f6aed4bd7fbf7b2ee74c231184a07f3d00c1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/a208ee578000f9dedcb50a9784ec7ff8706a7bf1",
-                "reference": "a208ee578000f9dedcb50a9784ec7ff8706a7bf1",
+                "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/6cb4f6aed4bd7fbf7b2ee74c231184a07f3d00c1",
+                "reference": "6cb4f6aed4bd7fbf7b2ee74c231184a07f3d00c1",
                 "shasum": ""
             },
             "require": {
@@ -5824,7 +7878,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.19"
+                "source": "https://github.com/symfony/framework-bundle/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -5840,20 +7894,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-10T17:40:25+00:00"
+            "time": "2023-03-31T08:25:44+00:00"
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v5.4.20",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "d0435363362a47c14e9cf50663cb8ffbf491875a"
+                "reference": "05cd1acdd0e3ce8473aaba1d86c188321d85f313"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d0435363362a47c14e9cf50663cb8ffbf491875a",
-                "reference": "d0435363362a47c14e9cf50663cb8ffbf491875a",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/05cd1acdd0e3ce8473aaba1d86c188321d85f313",
+                "reference": "05cd1acdd0e3ce8473aaba1d86c188321d85f313",
                 "shasum": ""
             },
             "require": {
@@ -5900,7 +7954,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.20"
+                "source": "https://github.com/symfony/http-foundation/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -5916,20 +7970,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-29T11:11:52+00:00"
+            "time": "2023-03-28T07:28:17+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v5.4.20",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "aaeec341582d3c160cc9ecfa8b2419ba6c69954e"
+                "reference": "2d3a8be2c756353627398827c409af6f126c096d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/aaeec341582d3c160cc9ecfa8b2419ba6c69954e",
-                "reference": "aaeec341582d3c160cc9ecfa8b2419ba6c69954e",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2d3a8be2c756353627398827c409af6f126c096d",
+                "reference": "2d3a8be2c756353627398827c409af6f126c096d",
                 "shasum": ""
             },
             "require": {
@@ -5938,7 +7992,7 @@
                 "symfony/deprecation-contracts": "^2.1|^3",
                 "symfony/error-handler": "^4.4|^5.0|^6.0",
                 "symfony/event-dispatcher": "^5.0|^6.0",
-                "symfony/http-foundation": "^5.3.7|^6.0",
+                "symfony/http-foundation": "^5.4.21|^6.2.7",
                 "symfony/polyfill-ctype": "^1.8",
                 "symfony/polyfill-php73": "^1.9",
                 "symfony/polyfill-php80": "^1.16"
@@ -6012,7 +8066,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.20"
+                "source": "https://github.com/symfony/http-kernel/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -6028,20 +8082,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-02-01T08:18:48+00:00"
+            "time": "2023-03-31T11:54:37+00:00"
         },
         {
             "name": "symfony/intl",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/intl.git",
-                "reference": "f378eb62448dfea67071f9f43529d3a6ad7e0bc8"
+                "reference": "8afe56b8472888d749ef8955acdc9d38578775d7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/intl/zipball/f378eb62448dfea67071f9f43529d3a6ad7e0bc8",
-                "reference": "f378eb62448dfea67071f9f43529d3a6ad7e0bc8",
+                "url": "https://api.github.com/repos/symfony/intl/zipball/8afe56b8472888d749ef8955acdc9d38578775d7",
+                "reference": "8afe56b8472888d749ef8955acdc9d38578775d7",
                 "shasum": ""
             },
             "require": {
@@ -6100,90 +8154,7 @@
                 "localization"
             ],
             "support": {
-                "source": "https://github.com/symfony/intl/tree/v5.4.19"
-            },
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2023-01-11T13:51:47+00:00"
-        },
-        {
-            "name": "symfony/phpunit-bridge",
-            "version": "v6.2.5",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/phpunit-bridge.git",
-                "reference": "d759e5372de414bef53a688c7aa7e240e4fd8aa2"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/d759e5372de414bef53a688c7aa7e240e4fd8aa2",
-                "reference": "d759e5372de414bef53a688c7aa7e240e4fd8aa2",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=7.1.3"
-            },
-            "conflict": {
-                "phpunit/phpunit": "<7.5|9.1.2"
-            },
-            "require-dev": {
-                "symfony/deprecation-contracts": "^2.1|^3.0",
-                "symfony/error-handler": "^5.4|^6.0"
-            },
-            "suggest": {
-                "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
-            },
-            "bin": [
-                "bin/simple-phpunit"
-            ],
-            "type": "symfony-bridge",
-            "extra": {
-                "thanks": {
-                    "name": "phpunit/phpunit",
-                    "url": "https://github.com/sebastianbergmann/phpunit"
-                }
-            },
-            "autoload": {
-                "files": [
-                    "bootstrap.php"
-                ],
-                "psr-4": {
-                    "Symfony\\Bridge\\PhpUnit\\": ""
-                },
-                "exclude-from-classmap": [
-                    "/Tests/"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nicolas Grekas",
-                    "email": "p@tchwork.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Provides utilities for PHPUnit, especially user deprecation notices management",
-            "homepage": "https://symfony.com",
-            "support": {
-                "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.5"
+                "source": "https://github.com/symfony/intl/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -6199,7 +8170,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-01T08:38:09+00:00"
+            "time": "2023-03-10T09:58:14+00:00"
         },
         {
             "name": "symfony/polyfill-ctype",
@@ -6774,16 +8745,16 @@
         },
         {
             "name": "symfony/process",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "c5ba874c9b636dbccf761e22ce750e88ec3f55e1"
+                "reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/c5ba874c9b636dbccf761e22ce750e88ec3f55e1",
-                "reference": "c5ba874c9b636dbccf761e22ce750e88ec3f55e1",
+                "url": "https://api.github.com/repos/symfony/process/zipball/4b850da0cc3a2a9181c1ed407adbca4733dc839b",
+                "reference": "4b850da0cc3a2a9181c1ed407adbca4733dc839b",
                 "shasum": ""
             },
             "require": {
@@ -6816,7 +8787,7 @@
             "description": "Executes commands in sub-processes",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/process/tree/v5.4.19"
+                "source": "https://github.com/symfony/process/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -6832,20 +8803,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-01T08:32:19+00:00"
+            "time": "2023-03-06T21:29:33+00:00"
         },
         {
             "name": "symfony/routing",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "df1b28f37c8e78912213c58ef6ab2f2037bbfdc5"
+                "reference": "c2ac11eb34947999b7c38fb4c835a57306907e6d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/df1b28f37c8e78912213c58ef6ab2f2037bbfdc5",
-                "reference": "df1b28f37c8e78912213c58ef6ab2f2037bbfdc5",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/c2ac11eb34947999b7c38fb4c835a57306907e6d",
+                "reference": "c2ac11eb34947999b7c38fb4c835a57306907e6d",
                 "shasum": ""
             },
             "require": {
@@ -6906,7 +8877,7 @@
                 "url"
             ],
             "support": {
-                "source": "https://github.com/symfony/routing/tree/v5.4.19"
+                "source": "https://github.com/symfony/routing/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -6922,7 +8893,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-01T08:32:19+00:00"
+            "time": "2023-03-14T14:59:20+00:00"
         },
         {
             "name": "symfony/service-contracts",
@@ -7009,16 +8980,16 @@
         },
         {
             "name": "symfony/string",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "0a01071610fd861cc160dfb7e2682ceec66064cb"
+                "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/0a01071610fd861cc160dfb7e2682ceec66064cb",
-                "reference": "0a01071610fd861cc160dfb7e2682ceec66064cb",
+                "url": "https://api.github.com/repos/symfony/string/zipball/8036a4c76c0dd29e60b6a7cafcacc50cf088ea62",
+                "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62",
                 "shasum": ""
             },
             "require": {
@@ -7075,7 +9046,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v5.4.19"
+                "source": "https://github.com/symfony/string/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -7091,7 +9062,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-01T08:32:19+00:00"
+            "time": "2023-03-14T06:11:53+00:00"
         },
         {
             "name": "symfony/translation-contracts",
@@ -7173,16 +9144,16 @@
         },
         {
             "name": "symfony/twig-bridge",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/twig-bridge.git",
-                "reference": "0526188cb886be64351454826fecc6d35356eaf1"
+                "reference": "e5b174464f68be6876046db3ad6e217d9a7dbbac"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/0526188cb886be64351454826fecc6d35356eaf1",
-                "reference": "0526188cb886be64351454826fecc6d35356eaf1",
+                "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/e5b174464f68be6876046db3ad6e217d9a7dbbac",
+                "reference": "e5b174464f68be6876046db3ad6e217d9a7dbbac",
                 "shasum": ""
             },
             "require": {
@@ -7195,7 +9166,7 @@
                 "phpdocumentor/reflection-docblock": "<3.2.2",
                 "phpdocumentor/type-resolver": "<1.4.0",
                 "symfony/console": "<5.3",
-                "symfony/form": "<5.3",
+                "symfony/form": "<5.4.21|>=6,<6.2.7",
                 "symfony/http-foundation": "<5.3",
                 "symfony/http-kernel": "<4.4",
                 "symfony/translation": "<5.2",
@@ -7210,7 +9181,7 @@
                 "symfony/dependency-injection": "^4.4|^5.0|^6.0",
                 "symfony/expression-language": "^4.4|^5.0|^6.0",
                 "symfony/finder": "^4.4|^5.0|^6.0",
-                "symfony/form": "^5.3|^6.0",
+                "symfony/form": "^5.4.21|^6.2.7",
                 "symfony/http-foundation": "^5.3|^6.0",
                 "symfony/http-kernel": "^4.4|^5.0|^6.0",
                 "symfony/intl": "^4.4|^5.0|^6.0",
@@ -7274,7 +9245,7 @@
             "description": "Provides integration for Twig with various Symfony components",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/twig-bridge/tree/v5.4.19"
+                "source": "https://github.com/symfony/twig-bridge/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -7290,20 +9261,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-09T05:43:46+00:00"
+            "time": "2023-03-31T08:28:44+00:00"
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v5.4.19",
+            "version": "v5.4.22",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "2944bbc23f5f8da2b962fbcbf7c4a6109b2f4b7b"
+                "reference": "e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2944bbc23f5f8da2b962fbcbf7c4a6109b2f4b7b",
-                "reference": "2944bbc23f5f8da2b962fbcbf7c4a6109b2f4b7b",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4",
+                "reference": "e2edac9ce47e6df07e38143c7cfa6bdbc1a6dcc4",
                 "shasum": ""
             },
             "require": {
@@ -7363,7 +9334,7 @@
                 "dump"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-dumper/tree/v5.4.19"
+                "source": "https://github.com/symfony/var-dumper/tree/v5.4.22"
             },
             "funding": [
                 {
@@ -7379,20 +9350,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-16T10:52:33+00:00"
+            "time": "2023-03-25T09:27:28+00:00"
         },
         {
             "name": "symfony/var-exporter",
-            "version": "v5.4.19",
+            "version": "v5.4.21",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-exporter.git",
-                "reference": "2a1d06fcf2b30829d6c01dae8e6e188424d1f8f6"
+                "reference": "be74908a6942fdd331554b3cec27ff41b45ccad4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-exporter/zipball/2a1d06fcf2b30829d6c01dae8e6e188424d1f8f6",
-                "reference": "2a1d06fcf2b30829d6c01dae8e6e188424d1f8f6",
+                "url": "https://api.github.com/repos/symfony/var-exporter/zipball/be74908a6942fdd331554b3cec27ff41b45ccad4",
+                "reference": "be74908a6942fdd331554b3cec27ff41b45ccad4",
                 "shasum": ""
             },
             "require": {
@@ -7436,7 +9407,7 @@
                 "serialize"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-exporter/tree/v5.4.19"
+                "source": "https://github.com/symfony/var-exporter/tree/v5.4.21"
             },
             "funding": [
                 {
@@ -7452,20 +9423,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-12T16:39:29+00:00"
+            "time": "2023-02-21T19:46:44+00:00"
         },
         {
             "name": "symfony/yaml",
-            "version": "v5.4.19",
+            "version": "v5.4.21",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "71c05db20cb9b54d381a28255f17580e2b7e36a5"
+                "reference": "3713e20d93e46e681e51605d213027e48dab3469"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/71c05db20cb9b54d381a28255f17580e2b7e36a5",
-                "reference": "71c05db20cb9b54d381a28255f17580e2b7e36a5",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/3713e20d93e46e681e51605d213027e48dab3469",
+                "reference": "3713e20d93e46e681e51605d213027e48dab3469",
                 "shasum": ""
             },
             "require": {
@@ -7511,7 +9482,7 @@
             "description": "Loads and dumps YAML files",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/yaml/tree/v5.4.19"
+                "source": "https://github.com/symfony/yaml/tree/v5.4.21"
             },
             "funding": [
                 {
@@ -7527,7 +9498,146 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-01-10T18:51:14+00:00"
+            "time": "2023-02-21T19:46:44+00:00"
+        },
+        {
+            "name": "thecodingmachine/safe",
+            "version": "v1.3.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thecodingmachine/safe.git",
+                "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/a8ab0876305a4cdaef31b2350fcb9811b5608dbc",
+                "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^0.12",
+                "squizlabs/php_codesniffer": "^3.2",
+                "thecodingmachine/phpstan-strict-rules": "^0.12"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "0.1-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "deprecated/apc.php",
+                    "deprecated/libevent.php",
+                    "deprecated/mssql.php",
+                    "deprecated/stats.php",
+                    "lib/special_cases.php",
+                    "generated/apache.php",
+                    "generated/apcu.php",
+                    "generated/array.php",
+                    "generated/bzip2.php",
+                    "generated/calendar.php",
+                    "generated/classobj.php",
+                    "generated/com.php",
+                    "generated/cubrid.php",
+                    "generated/curl.php",
+                    "generated/datetime.php",
+                    "generated/dir.php",
+                    "generated/eio.php",
+                    "generated/errorfunc.php",
+                    "generated/exec.php",
+                    "generated/fileinfo.php",
+                    "generated/filesystem.php",
+                    "generated/filter.php",
+                    "generated/fpm.php",
+                    "generated/ftp.php",
+                    "generated/funchand.php",
+                    "generated/gmp.php",
+                    "generated/gnupg.php",
+                    "generated/hash.php",
+                    "generated/ibase.php",
+                    "generated/ibmDb2.php",
+                    "generated/iconv.php",
+                    "generated/image.php",
+                    "generated/imap.php",
+                    "generated/info.php",
+                    "generated/ingres-ii.php",
+                    "generated/inotify.php",
+                    "generated/json.php",
+                    "generated/ldap.php",
+                    "generated/libxml.php",
+                    "generated/lzf.php",
+                    "generated/mailparse.php",
+                    "generated/mbstring.php",
+                    "generated/misc.php",
+                    "generated/msql.php",
+                    "generated/mysql.php",
+                    "generated/mysqli.php",
+                    "generated/mysqlndMs.php",
+                    "generated/mysqlndQc.php",
+                    "generated/network.php",
+                    "generated/oci8.php",
+                    "generated/opcache.php",
+                    "generated/openssl.php",
+                    "generated/outcontrol.php",
+                    "generated/password.php",
+                    "generated/pcntl.php",
+                    "generated/pcre.php",
+                    "generated/pdf.php",
+                    "generated/pgsql.php",
+                    "generated/posix.php",
+                    "generated/ps.php",
+                    "generated/pspell.php",
+                    "generated/readline.php",
+                    "generated/rpminfo.php",
+                    "generated/rrd.php",
+                    "generated/sem.php",
+                    "generated/session.php",
+                    "generated/shmop.php",
+                    "generated/simplexml.php",
+                    "generated/sockets.php",
+                    "generated/sodium.php",
+                    "generated/solr.php",
+                    "generated/spl.php",
+                    "generated/sqlsrv.php",
+                    "generated/ssdeep.php",
+                    "generated/ssh2.php",
+                    "generated/stream.php",
+                    "generated/strings.php",
+                    "generated/swoole.php",
+                    "generated/uodbc.php",
+                    "generated/uopz.php",
+                    "generated/url.php",
+                    "generated/var.php",
+                    "generated/xdiff.php",
+                    "generated/xml.php",
+                    "generated/xmlrpc.php",
+                    "generated/yaml.php",
+                    "generated/yaz.php",
+                    "generated/zip.php",
+                    "generated/zlib.php"
+                ],
+                "psr-4": {
+                    "Safe\\": [
+                        "lib/",
+                        "deprecated/",
+                        "generated/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "PHP core functions that throw exceptions instead of returning FALSE on error",
+            "support": {
+                "issues": "https://github.com/thecodingmachine/safe/issues",
+                "source": "https://github.com/thecodingmachine/safe/tree/v1.3.3"
+            },
+            "time": "2020-10-28T17:51:34+00:00"
         },
         {
             "name": "theseer/tokenizer",
@@ -7726,22 +9836,22 @@
         },
         {
             "name": "vimeo/psalm",
-            "version": "5.7.5",
+            "version": "5.9.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/vimeo/psalm.git",
-                "reference": "5390c212bab06ee230c8720c2e9c54b823db00c8"
+                "reference": "8b9ad1eb9e8b7d3101f949291da2b9f7767cd163"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/vimeo/psalm/zipball/5390c212bab06ee230c8720c2e9c54b823db00c8",
-                "reference": "5390c212bab06ee230c8720c2e9c54b823db00c8",
+                "url": "https://api.github.com/repos/vimeo/psalm/zipball/8b9ad1eb9e8b7d3101f949291da2b9f7767cd163",
+                "reference": "8b9ad1eb9e8b7d3101f949291da2b9f7767cd163",
                 "shasum": ""
             },
             "require": {
                 "amphp/amp": "^2.4.2",
                 "amphp/byte-stream": "^1.5",
-                "composer/package-versions-deprecated": "^1.10.0",
+                "composer-runtime-api": "^2",
                 "composer/semver": "^1.4 || ^2.0 || ^3.0",
                 "composer/xdebug-handler": "^2.0 || ^3.0",
                 "dnoegel/php-xdg-base-dir": "^0.1.1",
@@ -7756,7 +9866,7 @@
                 "felixfbecker/language-server-protocol": "^1.5.2",
                 "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1",
                 "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
-                "nikic/php-parser": "^4.13",
+                "nikic/php-parser": "^4.14",
                 "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0",
                 "sebastian/diff": "^4.0 || ^5.0",
                 "spatie/array-to-xml": "^2.17.0 || ^3.0",
@@ -7767,6 +9877,7 @@
                 "psalm/psalm": "self.version"
             },
             "require-dev": {
+                "amphp/phpunit-util": "^2.0",
                 "bamarni/composer-bin-plugin": "^1.4",
                 "brianium/paratest": "^6.9",
                 "ext-curl": "*",
@@ -7825,22 +9936,198 @@
             ],
             "support": {
                 "issues": "https://github.com/vimeo/psalm/issues",
-                "source": "https://github.com/vimeo/psalm/tree/5.7.5"
+                "source": "https://github.com/vimeo/psalm/tree/5.9.0"
+            },
+            "time": "2023-03-29T21:38:21+00:00"
+        },
+        {
+            "name": "web-token/jwt-framework",
+            "version": "v2.2.11",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/web-token/jwt-framework.git",
+                "reference": "643cced197e32471418bd89e7a44b69fd04eb9de"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/web-token/jwt-framework/zipball/643cced197e32471418bd89e7a44b69fd04eb9de",
+                "reference": "643cced197e32471418bd89e7a44b69fd04eb9de",
+                "shasum": ""
+            },
+            "require": {
+                "brick/math": "^0.8.17|^0.9",
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "ext-openssl": "*",
+                "ext-sodium": "*",
+                "fgrosse/phpasn1": "^2.0",
+                "php": ">=7.2",
+                "psr/event-dispatcher": "^1.0",
+                "psr/http-client": "^1.0",
+                "psr/http-factory": "^1.0",
+                "spomky-labs/aes-key-wrap": "^5.0|^6.0",
+                "spomky-labs/base64url": "^1.0|^2.0",
+                "symfony/config": "^4.2|^5.0",
+                "symfony/console": "^4.2|^5.0",
+                "symfony/dependency-injection": "^4.2|^5.0",
+                "symfony/event-dispatcher": "^4.2|^5.0",
+                "symfony/http-kernel": "^4.2|^5.0",
+                "symfony/polyfill-mbstring": "^1.12"
+            },
+            "conflict": {
+                "spomky-labs/jose": "*"
+            },
+            "replace": {
+                "web-token/encryption-pack": "self.version",
+                "web-token/jwt-bundle": "self.version",
+                "web-token/jwt-checker": "self.version",
+                "web-token/jwt-console": "self.version",
+                "web-token/jwt-core": "self.version",
+                "web-token/jwt-easy": "self.version",
+                "web-token/jwt-encryption": "self.version",
+                "web-token/jwt-encryption-algorithm-aescbc": "self.version",
+                "web-token/jwt-encryption-algorithm-aesgcm": "self.version",
+                "web-token/jwt-encryption-algorithm-aesgcmkw": "self.version",
+                "web-token/jwt-encryption-algorithm-aeskw": "self.version",
+                "web-token/jwt-encryption-algorithm-dir": "self.version",
+                "web-token/jwt-encryption-algorithm-ecdh-es": "self.version",
+                "web-token/jwt-encryption-algorithm-experimental": "self.version",
+                "web-token/jwt-encryption-algorithm-pbes2": "self.version",
+                "web-token/jwt-encryption-algorithm-rsa": "self.version",
+                "web-token/jwt-key-mgmt": "self.version",
+                "web-token/jwt-nested-token": "self.version",
+                "web-token/jwt-signature": "self.version",
+                "web-token/jwt-signature-algorithm-ecdsa": "self.version",
+                "web-token/jwt-signature-algorithm-eddsa": "self.version",
+                "web-token/jwt-signature-algorithm-experimental": "self.version",
+                "web-token/jwt-signature-algorithm-hmac": "self.version",
+                "web-token/jwt-signature-algorithm-none": "self.version",
+                "web-token/jwt-signature-algorithm-rsa": "self.version",
+                "web-token/jwt-util-ecc": "self.version",
+                "web-token/signature-pack": "self.version"
+            },
+            "require-dev": {
+                "bjeavons/zxcvbn-php": "^1.0",
+                "blackfire/php-sdk": "^1.14",
+                "ext-curl": "*",
+                "ext-gmp": "*",
+                "friendsofphp/php-cs-fixer": "^2.16",
+                "infection/infection": "^0.15|^0.16|^0.17|^0.18|^0.19|^0.20",
+                "matthiasnoback/symfony-config-test": "^3.1|^4.0",
+                "nyholm/psr7": "^1.3",
+                "php-coveralls/php-coveralls": "^2.0",
+                "php-http/mock-client": "^1.0",
+                "phpstan/phpstan": "^0.12",
+                "phpstan/phpstan-deprecation-rules": "^0.12",
+                "phpstan/phpstan-phpunit": "^0.12",
+                "phpstan/phpstan-strict-rules": "^0.12",
+                "phpunit/phpunit": "^8.0|^9.0",
+                "symfony/browser-kit": "^4.2|^5.0",
+                "symfony/finder": "^4.2|^5.0",
+                "symfony/framework-bundle": "^4.2|^5.0",
+                "symfony/http-client": "^5.2",
+                "symfony/phpunit-bridge": "^4.2|^5.0",
+                "symfony/serializer": "^4.2|^5.0",
+                "symfony/var-dumper": "^4.2|^5.0"
+            },
+            "suggest": {
+                "bjeavons/zxcvbn-php": "Adds key quality check for oct keys.",
+                "ext-sodium": "Sodium is required for OKP key creation, EdDSA signature algorithm and ECDH-ES key encryption with OKP keys",
+                "php-http/httplug": "To enable JKU/X5U support.",
+                "php-http/httplug-bundle": "To enable JKU/X5U support.",
+                "php-http/message-factory": "To enable JKU/X5U support.",
+                "symfony/serializer": "Use the Symfony serializer to serialize/unserialize JWS and JWE tokens.",
+                "symfony/var-dumper": "Used to show data on the debug toolbar."
+            },
+            "type": "symfony-bundle",
+            "autoload": {
+                "psr-4": {
+                    "Jose\\": "src/",
+                    "Jose\\Component\\Core\\Util\\Ecc\\": [
+                        "src/Ecc"
+                    ],
+                    "Jose\\Component\\Signature\\Algorithm\\": [
+                        "src/SignatureAlgorithm/ECDSA",
+                        "src/SignatureAlgorithm/EdDSA",
+                        "src/SignatureAlgorithm/HMAC",
+                        "src/SignatureAlgorithm/None",
+                        "src/SignatureAlgorithm/RSA",
+                        "src/SignatureAlgorithm/Experimental"
+                    ],
+                    "Jose\\Component\\Encryption\\Algorithm\\": [
+                        "src/EncryptionAlgorithm/Experimental"
+                    ],
+                    "Jose\\Component\\Encryption\\Algorithm\\KeyEncryption\\": [
+                        "src/EncryptionAlgorithm/KeyEncryption/AESGCMKW",
+                        "src/EncryptionAlgorithm/KeyEncryption/AESKW",
+                        "src/EncryptionAlgorithm/KeyEncryption/Direct",
+                        "src/EncryptionAlgorithm/KeyEncryption/ECDHES",
+                        "src/EncryptionAlgorithm/KeyEncryption/PBES2",
+                        "src/EncryptionAlgorithm/KeyEncryption/RSA"
+                    ],
+                    "Jose\\Component\\Encryption\\Algorithm\\ContentEncryption\\": [
+                        "src/EncryptionAlgorithm/ContentEncryption/AESGCM",
+                        "src/EncryptionAlgorithm/ContentEncryption/AESCBC"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Florent Morselli",
+                    "homepage": "https://github.com/Spomky"
+                },
+                {
+                    "name": "All contributors",
+                    "homepage": "https://github.com/web-token/jwt-framework/contributors"
+                }
+            ],
+            "description": "JSON Object Signing and Encryption library for PHP and Symfony Bundle.",
+            "homepage": "https://github.com/web-token/jwt-framework",
+            "keywords": [
+                "JOSE",
+                "JWE",
+                "JWK",
+                "JWKSet",
+                "JWS",
+                "Jot",
+                "RFC7515",
+                "RFC7516",
+                "RFC7517",
+                "RFC7518",
+                "RFC7519",
+                "RFC7520",
+                "bundle",
+                "jwa",
+                "jwt",
+                "symfony"
+            ],
+            "support": {
+                "issues": "https://github.com/web-token/jwt-framework/issues",
+                "source": "https://github.com/web-token/jwt-framework/tree/v2.2.11"
             },
-            "time": "2023-02-21T16:02:51+00:00"
+            "funding": [
+                {
+                    "url": "https://github.com/Spomky",
+                    "type": "github"
+                }
+            ],
+            "time": "2021-06-25T15:59:52+00:00"
         }
     ],
     "aliases": [],
     "minimum-stability": "stable",
-    "stability-flags": {
-        "simplesamlphp/simplesamlphp": 10
-    },
+    "stability-flags": [],
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
         "php": "^7.4 || ^8.0",
         "ext-pdo": "*",
-        "ext-pdo_sqlite": "*"
+        "ext-pdo_sqlite": "*",
+        "composer-runtime-api": "^2.0"
     },
     "platform-dev": [],
     "plugin-api-version": "2.3.0"
diff --git a/hooks/hook_adminmenu.php b/hooks/hook_adminmenu.php
index 1df9352a58fc8bb241ec3ac4768ff707c8c94f65..8fffd991289b7b44306ceeb6a806618b4c30d220 100644
--- a/hooks/hook_adminmenu.php
+++ b/hooks/hook_adminmenu.php
@@ -3,7 +3,7 @@
 declare(strict_types=1);
 
 use SimpleSAML\Locale\Translate;
-use SimpleSAML\Module\accounting\Helpers\ModuleRoutes;
+use SimpleSAML\Module\accounting\Helpers\Routes;
 use SimpleSAML\Module\accounting\ModuleConfiguration;
 use SimpleSAML\XHTML\Template;
 
@@ -12,11 +12,11 @@ function accounting_hook_adminmenu(Template &$template): void
 {
     $menuKey = 'menu';
 
-    $moduleRoutesHelper = new ModuleRoutes();
+    $moduleRoutesHelper = new Routes();
 
     $profilePageEntry = [
         ModuleConfiguration::MODULE_NAME => [
-            'url' => $moduleRoutesHelper->getUrl(ModuleRoutes::PATH_USER_PERSONAL_DATA),
+            'url' => $moduleRoutesHelper->getUrl(Routes::PATH_USER_PERSONAL_DATA),
             'name' => Translate::noop('Profile Page'),
         ],
     ];
diff --git a/hooks/hook_configpage.php b/hooks/hook_configpage.php
index 93edf9374e23dbd0252d646c71db1d6e8fcb58be..68aa8efee9bb73427831e0b2a57afc29b49b8cba 100644
--- a/hooks/hook_configpage.php
+++ b/hooks/hook_configpage.php
@@ -3,14 +3,14 @@
 declare(strict_types=1);
 
 use SimpleSAML\Locale\Translate;
-use SimpleSAML\Module\accounting\Helpers\ModuleRoutes;
+use SimpleSAML\Module\accounting\Helpers\Routes;
 use SimpleSAML\Module\accounting\ModuleConfiguration;
 use SimpleSAML\XHTML\Template;
 
 /** @noinspection PhpParameterByRefIsNotUsedAsReferenceInspection Reference is used by SimpleSAMLphp */
 function accounting_hook_configpage(Template &$template): void
 {
-    $moduleRoutesHelper = new ModuleRoutes();
+    $moduleRoutesHelper = new Routes();
 
     $dataLinksKey = 'links';
 
@@ -19,7 +19,7 @@ function accounting_hook_configpage(Template &$template): void
     }
 
     $template->data[$dataLinksKey][] = [
-        'href' => $moduleRoutesHelper->getUrl(ModuleRoutes::PATH_ADMIN_CONFIGURATION_STATUS),
+        'href' => $moduleRoutesHelper->getUrl(Routes::PATH_ADMIN_CONFIGURATION_STATUS),
         'text' => Translate::noop('Accounting configuration status'),
     ];
 
diff --git a/public/assets/css/src/custom.css b/public/assets/css/src/custom.css
index cb8acd7af26be658c0754190f87531e2f12e9fce..808e4647b265de25b020a0e416640bab3dc60529 100644
--- a/public/assets/css/src/custom.css
+++ b/public/assets/css/src/custom.css
@@ -39,4 +39,4 @@
     max-height: 0;
     overflow: hidden;
     transition: max-height 0.2s ease-out;
-}
\ No newline at end of file
+}
diff --git a/public/assets/css/src/default.css b/public/assets/css/src/default.css
index 114cfffff67917249119d19540ae8d227a54440a..22f17b95949fc2e243781baa76507faecaca8e30 100644
--- a/public/assets/css/src/default.css
+++ b/public/assets/css/src/default.css
@@ -458,4 +458,30 @@
         display: none;
     }
   
-  }
\ No newline at end of file
+  }
+
+
+/** Alerts */
+
+/* The alert message box */
+.alerts .alert {
+  padding: 20px;
+  margin-bottom: 15px;
+}
+
+/* The close button */
+.close-btn {
+  margin-left: 15px;
+  color: white;
+  font-weight: bold;
+  float: right;
+  font-size: 22px;
+  line-height: 20px;
+  cursor: pointer;
+  transition: 0.3s;
+}
+
+/* When moving the mouse over the close button */
+.close-btn:hover {
+  color: black;
+}
diff --git a/routing/routes/routes.yml b/routing/routes/routes.yml
index a44a2bd3adf0ddbd1e660269e2b409f56950cdf8..1d2d429e693ff02b3564bab9426e50b047603859 100644
--- a/routing/routes/routes.yml
+++ b/routing/routes/routes.yml
@@ -1,23 +1,37 @@
 
 accounting-admin-configuration-status:
     path:       /admin/configuration/status
-    defaults:   { _controller: 'SimpleSAML\Module\accounting\Http\Controllers\Admin\Configuration::status' }
+    controller: SimpleSAML\Module\accounting\Http\Controllers\Admin\Configuration::status
 
 accounting-user-personal-data:
     path: /user/personal-data
-    defaults:   { _controller: 'SimpleSAML\Module\accounting\Http\Controllers\User\Profile::personalData' }
+    controller: SimpleSAML\Module\accounting\Http\Controllers\User\Profile::personalData
 
 accounting-user-connected-organizations:
     path: /user/connected-organizations
-    defaults:   { _controller: 'SimpleSAML\Module\accounting\Http\Controllers\User\Profile::connectedOrganizations' }
+    controller: SimpleSAML\Module\accounting\Http\Controllers\User\Profile::connectedOrganizations
 
 accounting-user-activity:
     path: /user/activity
-    defaults:   { _controller: 'SimpleSAML\Module\accounting\Http\Controllers\User\Profile::activity' }
+    controller: SimpleSAML\Module\accounting\Http\Controllers\User\Profile::activity
+
+accounting-user-oidc-tokens:
+    path: /user/oidc-tokens
+    controller: SimpleSAML\Module\accounting\Http\Controllers\User\Profile::oidcTokens
+
+accounting-user-oidc-token-revoke:
+    path: /user/oidc-tokens/revoke
+    controller: SimpleSAML\Module\accounting\Http\Controllers\User\Profile::oidcTokenRevoke
+    methods: POST
+
+accounting-user-oidc-token-revoke-xhr:
+    path: /user/oidc-tokens/revoke-xhr
+    controller: SimpleSAML\Module\accounting\Http\Controllers\User\Profile::oidcTokenRevokeXhr
+    methods: POST
 
 accounting-user-logout:
     path: /user/logout
+    controller: SimpleSAML\Module\accounting\Http\Controllers\User\Profile::logout
     methods:
         - GET
         - POST
-    defaults:   { _controller: 'SimpleSAML\Module\accounting\Http\Controllers\User\Profile::logout' }
diff --git a/src/Entities/Bases/AbstractProvider.php b/src/Entities/Bases/AbstractProvider.php
index f3833d57ff43681b38b684efa183f6cb80ae1bbb..9e63abde92dc28fc928e623ea3be29f2794de2fb 100644
--- a/src/Entities/Bases/AbstractProvider.php
+++ b/src/Entities/Bases/AbstractProvider.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\accounting\Entities\Bases;
 
+use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
 use SimpleSAML\Module\accounting\Entities\Interfaces\ProviderInterface;
 
 abstract class AbstractProvider implements ProviderInterface
@@ -52,4 +53,5 @@ abstract class AbstractProvider implements ProviderInterface
     abstract public function getName(string $locale = 'en'): ?string;
     abstract public function getDescription(string $locale = 'en'): ?string;
     abstract protected function resolveEntityId(): string;
+    abstract public function getProtocol(): AuthenticationProtocolInterface;
 }
diff --git a/src/Entities/Bases/AbstractState.php b/src/Entities/Bases/AbstractState.php
index a2d5cd9115aad7708959318a767564ab99c399f7..02a9e10dab21f928d399087c944d1d445ddfb22f 100644
--- a/src/Entities/Bases/AbstractState.php
+++ b/src/Entities/Bases/AbstractState.php
@@ -9,10 +9,13 @@ use SimpleSAML\Module\accounting\Entities\Interfaces\StateInterface;
 use SimpleSAML\Module\accounting\Exceptions\UnexpectedValueException;
 use SimpleSAML\Module\accounting\Services\HelpersManager;
 use DateTimeImmutable;
+use SimpleSAML\Module\accounting\Traits\HasUserAttributesTrait;
 use Throwable;
 
 abstract class AbstractState implements StateInterface
 {
+    use HasUserAttributesTrait;
+
     public const KEY_ATTRIBUTES = 'Attributes';
     public const KEY_ACCOUNTING = 'accounting';
     public const ACCOUNTING_KEY_CLIENT_IP_ADDRESS = 'client_ip_address';
@@ -20,7 +23,6 @@ abstract class AbstractState implements StateInterface
 
     protected string $identityProviderEntityId;
     protected string $serviceProviderEntityId;
-    protected array $attributes;
     protected DateTimeImmutable $createdAt;
     protected ?DateTimeImmutable $authenticationInstant;
     protected array $identityProviderMetadata;
@@ -99,29 +101,6 @@ abstract class AbstractState implements StateInterface
         return $this->serviceProviderEntityId;
     }
 
-    public function getAttributes(): array
-    {
-        return $this->attributes;
-    }
-
-    public function getFirstAttributeValue(string $attributeName): ?string
-    {
-        if (($value = $this->getAttributeValue($attributeName)) !== null) {
-            return (string)reset($value);
-        }
-
-        return null;
-    }
-
-    public function getAttributeValue(string $attributeName): ?array
-    {
-        if (!empty($this->attributes[$attributeName]) && is_array($this->attributes[$attributeName])) {
-            return $this->attributes[$attributeName];
-        }
-
-        return null;
-    }
-
     public function getCreatedAt(): DateTimeImmutable
     {
         return $this->createdAt;
diff --git a/src/Entities/Interfaces/ProviderInterface.php b/src/Entities/Interfaces/ProviderInterface.php
index 30971b67f0141276f5e5fe4c021679efee988cc1..c82a1792698873b1ba3e295addba031708832ca4 100644
--- a/src/Entities/Interfaces/ProviderInterface.php
+++ b/src/Entities/Interfaces/ProviderInterface.php
@@ -13,4 +13,5 @@ interface ProviderInterface
     public function getName(string $locale = 'en'): ?string;
     public function getEntityId(): string;
     public function getDescription(string $locale = 'en'): ?string;
+    public function getProtocol(): AuthenticationProtocolInterface;
 }
diff --git a/src/Entities/Providers/Identity/Oidc.php b/src/Entities/Providers/Identity/Oidc.php
index 660a850eecc1371ad9d12593cebf5874c7841a2b..d326113ce1918f16819d8eb0b798bd17b8fb3328 100644
--- a/src/Entities/Providers/Identity/Oidc.php
+++ b/src/Entities/Providers/Identity/Oidc.php
@@ -4,7 +4,9 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\accounting\Entities\Providers\Identity;
 
+use SimpleSAML\Module\accounting\Entities\Authentication;
 use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider;
+use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
 use SimpleSAML\Module\accounting\Entities\Interfaces\IdentityProviderInterface;
 use SimpleSAML\Module\accounting\Exceptions\MetadataException;
 
@@ -36,4 +38,9 @@ class Oidc extends AbstractProvider implements IdentityProviderInterface
 
         throw new MetadataException('OpenID Provider metadata does not contain entity ID.');
     }
+
+    public function getProtocol(): AuthenticationProtocolInterface
+    {
+        return new Authentication\Protocol\Oidc();
+    }
 }
diff --git a/src/Entities/Providers/Identity/Saml2.php b/src/Entities/Providers/Identity/Saml2.php
index 06bd9390336499ff31696208778598d017cf4475..04768636840af510618c96d26587f396b283afe4 100644
--- a/src/Entities/Providers/Identity/Saml2.php
+++ b/src/Entities/Providers/Identity/Saml2.php
@@ -4,7 +4,9 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\accounting\Entities\Providers\Identity;
 
+use SimpleSAML\Module\accounting\Entities\Authentication;
 use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider;
+use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
 use SimpleSAML\Module\accounting\Entities\Interfaces\IdentityProviderInterface;
 use SimpleSAML\Module\accounting\Exceptions\MetadataException;
 
@@ -38,4 +40,9 @@ class Saml2 extends AbstractProvider implements IdentityProviderInterface
 
         throw new MetadataException('Identity provider metadata does not contain entity ID.');
     }
+
+    public function getProtocol(): AuthenticationProtocolInterface
+    {
+        return new Authentication\Protocol\Saml2();
+    }
 }
diff --git a/src/Entities/Providers/Service/Oidc.php b/src/Entities/Providers/Service/Oidc.php
index 37e187b28f11c8aaf0f8830275776267619de7ce..382eabdf1815a3598b8f60bc168c33242febfeb6 100644
--- a/src/Entities/Providers/Service/Oidc.php
+++ b/src/Entities/Providers/Service/Oidc.php
@@ -4,7 +4,9 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\accounting\Entities\Providers\Service;
 
+use SimpleSAML\Module\accounting\Entities\Authentication;
 use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider;
+use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
 use SimpleSAML\Module\accounting\Entities\Interfaces\ServiceProviderInterface;
 use SimpleSAML\Module\accounting\Exceptions\MetadataException;
 
@@ -38,4 +40,9 @@ class Oidc extends AbstractProvider implements ServiceProviderInterface
 
         throw new MetadataException('Relying Provider metadata does not contain entity ID.');
     }
+
+    public function getProtocol(): AuthenticationProtocolInterface
+    {
+        return new Authentication\Protocol\Oidc();
+    }
 }
diff --git a/src/Entities/Providers/Service/Saml2.php b/src/Entities/Providers/Service/Saml2.php
index d88bfaee365311bf62f1aaf2c1dc62cec4c602fd..d0dfd4ac065c2b22a7f3dcdcf82c14096981f40d 100644
--- a/src/Entities/Providers/Service/Saml2.php
+++ b/src/Entities/Providers/Service/Saml2.php
@@ -4,7 +4,9 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\accounting\Entities\Providers\Service;
 
+use SimpleSAML\Module\accounting\Entities\Authentication;
 use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider;
+use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
 use SimpleSAML\Module\accounting\Entities\Interfaces\ServiceProviderInterface;
 use SimpleSAML\Module\accounting\Exceptions\MetadataException;
 
@@ -38,4 +40,9 @@ class Saml2 extends AbstractProvider implements ServiceProviderInterface
 
         throw new MetadataException('Service provider metadata does not contain entity ID.');
     }
+
+    public function getProtocol(): AuthenticationProtocolInterface
+    {
+        return new Authentication\Protocol\Saml2();
+    }
 }
diff --git a/src/Entities/User.php b/src/Entities/User.php
index 138bc4cb5f99501a15aea7b7fe23ffb4f601d9db..99bbf8642192ab84c508c414986a0e8284d30f77 100644
--- a/src/Entities/User.php
+++ b/src/Entities/User.php
@@ -4,20 +4,14 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\accounting\Entities;
 
+use SimpleSAML\Module\accounting\Traits\HasUserAttributesTrait;
+
 class User
 {
-    protected array $attributes;
+    use HasUserAttributesTrait;
 
     public function __construct(array $attributes)
     {
         $this->attributes = $attributes;
     }
-
-    /**
-     * @return array
-     */
-    public function getAttributes(): array
-    {
-        return $this->attributes;
-    }
 }
diff --git a/src/Helpers/Arr.php b/src/Helpers/Arr.php
index be464ee22144e7635cabd05dc5d32394134ec6b1..465e122ad3de3e8d9f57aed34b8c8e3494d3678c 100644
--- a/src/Helpers/Arr.php
+++ b/src/Helpers/Arr.php
@@ -17,4 +17,24 @@ class Arr
 
         ksort($array);
     }
+
+    /**
+     * @param array $array
+     * @param int|string $key
+     * @return array
+     */
+    public function groupByValue(array $array, $key): array
+    {
+        return array_reduce($array, function (array $carry, array $item) use ($key) {
+            /** @psalm-suppress MixedArrayOffset, MixedArrayAssignment */
+            $carry[$item[$key]][] = $item;
+            return $carry;
+        }, []);
+    }
+
+    public function isAssociative(array $array): bool
+    {
+        $keys = array_keys($array);
+        return $keys !== array_keys($keys);
+    }
 }
diff --git a/src/Helpers/DateTime.php b/src/Helpers/DateTime.php
index 1e328171ae42cda9987592db0cf403f6ef059220..e87b927d552a4f06e662f5bc632a37365a94dd28 100644
--- a/src/Helpers/DateTime.php
+++ b/src/Helpers/DateTime.php
@@ -9,6 +9,7 @@ use DateTimeImmutable;
 
 class DateTime
 {
+    public const FORMAT_MYSQL = 'Y-m-d H:i:s';
     /**
      * Convert date interval to seconds, interval being minimum 1 second.
      * @param DateInterval $dateInterval Minimum is 1 second.
@@ -27,4 +28,13 @@ class DateTime
 
         return $duration;
     }
+
+    public function toFormattedString(
+        \DateTimeInterface $dateTime = null,
+        string $format = self::FORMAT_MYSQL
+    ): string {
+        $dateTime = $dateTime ?? new DateTimeImmutable();
+
+        return $dateTime->format($format);
+    }
 }
diff --git a/src/Helpers/Random.php b/src/Helpers/Random.php
index e56fde76d5b31056d9929c392ed2e782460d5f9f..c839663891b8ae06f47f0dfdde224dacc0bdd6ec 100644
--- a/src/Helpers/Random.php
+++ b/src/Helpers/Random.php
@@ -8,7 +8,7 @@ use Throwable;
 
 class Random
 {
-    public function getRandomInt(int $minimum = PHP_INT_MIN, int $maximum = PHP_INT_MAX): int
+    public function getInt(int $minimum = PHP_INT_MIN, int $maximum = PHP_INT_MAX): int
     {
         try {
             return random_int($minimum, $maximum);
@@ -18,4 +18,15 @@ class Random
             // @codeCoverageIgnoreEnd
         }
     }
+
+    public function getString(int $length = 16): string
+    {
+        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+        $charactersLength = strlen($characters);
+        $randomString = '';
+        for ($i = 0; $i < $length; $i++) {
+            $randomString .= $characters[$this->getInt(0, $charactersLength - 1)];
+        }
+        return $randomString;
+    }
 }
diff --git a/src/Helpers/ModuleRoutes.php b/src/Helpers/Routes.php
similarity index 52%
rename from src/Helpers/ModuleRoutes.php
rename to src/Helpers/Routes.php
index f03617f990d087f6ade1e9d6e3187c9d8d8c184b..70bec363a3194f6b492368b26ca072173fb9b124 100644
--- a/src/Helpers/ModuleRoutes.php
+++ b/src/Helpers/Routes.php
@@ -9,20 +9,24 @@ use SimpleSAML\Module\accounting\Exceptions\InvalidConfigurationException;
 use SimpleSAML\Module\accounting\ModuleConfiguration;
 use SimpleSAML\Utils\HTTP;
 
-class ModuleRoutes
+class Routes
 {
     public const PATH_ADMIN_CONFIGURATION_STATUS = 'admin/configuration/status';
 
     public const PATH_USER_PERSONAL_DATA = 'user/personal-data';
+    public const PATH_USER_OIDC_TOKENS = 'user/oidc-tokens';
+    public const QUERY_REDIRECT_TO_PATH = 'redirectTo';
 
     protected HTTP $sspHttpUtils;
+    protected Arr $arr;
 
-    public function __construct(HTTP $sspHttpUtils = null)
+    public function __construct(HTTP $sspHttpUtils = null, Arr $arr = null)
     {
         $this->sspHttpUtils = $sspHttpUtils ?? new HTTP();
+        $this->arr = $arr ?? new Arr();
     }
 
-    public function getUrl(string $path, array $parameters = []): string
+    public function getUrl(string $path, array $queryParameters = [], array $fragmentParameters = []): string
     {
         try {
             $url = $this->sspHttpUtils->getBaseURL() . 'module.php/' . ModuleConfiguration::MODULE_NAME . '/' . $path;
@@ -34,8 +38,24 @@ class ModuleRoutes
             // @codeCoverageIgnoreEnd
         }
 
-        if (!empty($parameters)) {
-            $url = $this->sspHttpUtils->addURLParameters($url, $parameters);
+        if (!empty($queryParameters)) {
+            $url = $this->sspHttpUtils->addURLParameters($url, $queryParameters);
+        }
+
+        // Let's assume there are no current fragments in the URL. If the fragment array is not associative,
+        // simply append value(s). Otherwise, create key-value fragment pairs.
+        if (!empty($fragmentParameters)) {
+            /** @psalm-suppress MixedArgumentTypeCoercion */
+            $url .= '#' . implode(
+                '&',
+                (
+                    ! $this->arr->isAssociative($fragmentParameters) ?
+                    $fragmentParameters :
+                    array_map(function ($key, string $value): string {
+                        return $key . '=' . $value;
+                    }, array_keys($fragmentParameters), $fragmentParameters)
+                )
+            );
         }
 
         return $url;
diff --git a/src/Helpers/SspModule.php b/src/Helpers/SspModule.php
new file mode 100644
index 0000000000000000000000000000000000000000..df5798a0f7c18fc57b3c7e2c0b5409da8615c06b
--- /dev/null
+++ b/src/Helpers/SspModule.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SimpleSAML\Module\accounting\Helpers;
+
+use SimpleSAML\Module;
+
+class SspModule
+{
+    /**
+     * @throws \Exception
+     */
+    public function isEnabled(string $moduleName): bool
+    {
+        try {
+            return Module::isModuleEnabled($moduleName);
+        } catch (\Throwable $exception) {
+            $message = sprintf('Could not check if module %s is enabled', $moduleName);
+            throw new Module\accounting\Exceptions\InvalidConfigurationException(
+                $message,
+                (int) $exception->getCode(),
+                $exception
+            );
+        }
+    }
+}
diff --git a/src/Http/Controllers/Admin/Configuration.php b/src/Http/Controllers/Admin/Configuration.php
index 3ce99220ea42cdedb7513560662f53d6f50968a4..cd5d9534f49bc0d2bdfb63c3562c812c3848aa4e 100644
--- a/src/Http/Controllers/Admin/Configuration.php
+++ b/src/Http/Controllers/Admin/Configuration.php
@@ -7,7 +7,7 @@ namespace SimpleSAML\Module\accounting\Http\Controllers\Admin;
 use Exception;
 use Psr\Log\LoggerInterface;
 use SimpleSAML\Configuration as SspConfiguration;
-use SimpleSAML\Module\accounting\Helpers\ModuleRoutes;
+use SimpleSAML\Module\accounting\Helpers\Routes;
 use SimpleSAML\Module\accounting\ModuleConfiguration;
 use SimpleSAML\Module\accounting\Services\HelpersManager;
 use SimpleSAML\Module\accounting\Stores\Builders\JobsStoreBuilder;
@@ -119,8 +119,8 @@ class Configuration
             'defaultDataTrackerAndProvider' => $defaultDataTrackerAndProvider,
             'additionalTrackers' => $additionalTrackers,
             'setupNeeded' => $setupNeeded,
-            'profilePageUri' => $this->helpersManager->getModuleRoutes()
-                ->getUrl(ModuleRoutes::PATH_USER_PERSONAL_DATA),
+            'profilePageUri' => $this->helpersManager->getRoutes()
+                ->getUrl(Routes::PATH_USER_PERSONAL_DATA),
         ];
 
         $template = new Template($this->sspConfiguration, 'accounting:admin/configuration/status.twig');
diff --git a/src/Http/Controllers/User/Profile.php b/src/Http/Controllers/User/Profile.php
index 5ef9218bdd38b37d39a159e2af610a619b0ba8e1..c144a97b3bc35368582813b296cf54f9a654352d 100644
--- a/src/Http/Controllers/User/Profile.php
+++ b/src/Http/Controllers/User/Profile.php
@@ -10,16 +10,28 @@ use SimpleSAML\Configuration as SspConfiguration;
 use SimpleSAML\Error\ConfigurationError;
 use SimpleSAML\Error\CriticalConfigurationError;
 use SimpleSAML\HTTP\RunnableResponse;
+use SimpleSAML\Locale\Translate;
+use SimpleSAML\Module\accounting\Entities\Authentication\Protocol\Oidc;
+use SimpleSAML\Module\accounting\Entities\ConnectedServiceProvider;
+use SimpleSAML\Module\accounting\Entities\User;
 use SimpleSAML\Module\accounting\Exceptions\Exception;
 use SimpleSAML\Module\accounting\Exceptions\InvalidConfigurationException;
 use SimpleSAML\Module\accounting\Helpers\Attributes;
+use SimpleSAML\Module\accounting\Helpers\Routes;
 use SimpleSAML\Module\accounting\ModuleConfiguration;
 use SimpleSAML\Module\accounting\ModuleConfiguration\ConnectionType;
 use SimpleSAML\Module\accounting\Providers\Builders\AuthenticationDataProviderBuilder;
 use SimpleSAML\Module\accounting\Providers\Interfaces\AuthenticationDataProviderInterface;
+use SimpleSAML\Module\accounting\Services\AlertsBag;
+use SimpleSAML\Module\accounting\Services\CsrfToken;
 use SimpleSAML\Module\accounting\Services\HelpersManager;
+use SimpleSAML\Module\accounting\Services\MenuManager;
+use SimpleSAML\Module\accounting\Services\SspModuleManager;
 use SimpleSAML\Session;
 use SimpleSAML\XHTML\Template;
+use Symfony\Component\HttpFoundation\Cookie;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 
@@ -36,6 +48,11 @@ class Profile
     protected Simple $authSimple;
     protected AuthenticationDataProviderBuilder $authenticationDataProviderBuilder;
     protected HelpersManager $helpersManager;
+    protected SspModuleManager $sspModuleManager;
+    protected User $user;
+    protected MenuManager $menuManager;
+    protected CsrfToken $csrfToken;
+    protected AlertsBag $alertsBag;
 
     /**
      * @param ModuleConfiguration $moduleConfiguration
@@ -45,6 +62,9 @@ class Profile
      * @param Simple|null $authSimple
      * @param AuthenticationDataProviderBuilder|null $authenticationDataProviderBuilder
      * @param HelpersManager|null $helpersManager
+     * @param SspModuleManager|null $sspModuleManager
+     * @param CsrfToken|null $csrfToken
+     * @param AlertsBag|null $alertsBag
      */
     public function __construct(
         ModuleConfiguration $moduleConfiguration,
@@ -53,7 +73,10 @@ class Profile
         LoggerInterface $logger,
         Simple $authSimple = null,
         AuthenticationDataProviderBuilder $authenticationDataProviderBuilder = null,
-        HelpersManager $helpersManager = null
+        HelpersManager $helpersManager = null,
+        SspModuleManager $sspModuleManager = null,
+        CsrfToken $csrfToken = null,
+        AlertsBag $alertsBag = null
     ) {
         $this->moduleConfiguration = $moduleConfiguration;
         $this->sspConfiguration = $sspConfiguration;
@@ -68,8 +91,14 @@ class Profile
         $this->authenticationDataProviderBuilder = $authenticationDataProviderBuilder ??
             new AuthenticationDataProviderBuilder($this->moduleConfiguration, $this->logger, $this->helpersManager);
 
+        $this->sspModuleManager = $sspModuleManager ?? new SspModuleManager($this->logger, $this->helpersManager);
+
         // Make sure the end user is authenticated.
         $this->authSimple->requireAuth();
+        $this->user = new User($this->authSimple->getAttributes());
+        $this->menuManager = $this->prepareMenuManager();
+        $this->csrfToken = $csrfToken ?? new CsrfToken($this->session, $this->helpersManager);
+        $this->alertsBag = $alertsBag ?? new AlertsBag($this->session);
     }
 
     /**
@@ -85,7 +114,7 @@ class Profile
          * @var string $name
          * @var string[] $value
          */
-        foreach ($this->authSimple->getAttributes() as $name => $value) {
+        foreach ($this->user->getAttributes() as $name => $value) {
             // Convert attribute names to user-friendly names.
             if (array_key_exists($name, $toNameAttributeMap)) {
                 $name = (string)$toNameAttributeMap[$name];
@@ -94,7 +123,7 @@ class Profile
         }
 
         $template = $this->resolveTemplate('accounting:user/personal-data.twig');
-        $template->data = compact('normalizedAttributes');
+        $template->data += compact('normalizedAttributes');
 
         return $template;
     }
@@ -111,8 +140,48 @@ class Profile
 
         $connectedServiceProviderBag = $authenticationDataProvider->getConnectedServiceProviders($userIdentifier);
 
+        $oidc = $this->sspModuleManager->getOidc();
+        $accessTokensByClient = [];
+        $refreshTokensByClient = [];
+        $oidcProtocolDesignation = Oidc::DESIGNATION;
+
+        // If oidc module is enabled, gather users access and refresh tokens for particular OIDC service providers.
+        if ($oidc->isEnabled()) {
+            // Filter out OIDC service providers and get their entity (client) IDs.
+            $oidcClientIds = array_map(
+                function (ConnectedServiceProvider $connectedServiceProvider) {
+                    return $connectedServiceProvider->getServiceProvider()->getEntityId();
+                },
+                array_filter(
+                    $connectedServiceProviderBag->getAll(),
+                    function (ConnectedServiceProvider $connectedServiceProvider) {
+                        return $connectedServiceProvider->getServiceProvider()->getProtocol()->getDesignation() ===
+                            Oidc::DESIGNATION;
+                    }
+                )
+            );
+
+            if (! empty($oidcClientIds)) {
+                $accessTokensByClient = $this->helpersManager->getArr()->groupByValue(
+                    $oidc->getUsersAccessTokens($userIdentifier, $oidcClientIds),
+                    'client_id'
+                );
+
+                $refreshTokensByClient = $this->helpersManager->getArr()->groupByValue(
+                    $oidc->getUsersRefreshTokens($userIdentifier, $oidcClientIds),
+                    'client_id'
+                );
+            }
+            //die(var_dump($oidcClientIds, $accessTokensByClient, $refreshTokensByClient));
+        }
+
         $template = $this->resolveTemplate('accounting:user/connected-organizations.twig');
-        $template->data = compact('connectedServiceProviderBag');
+        $template->data += compact(
+            'connectedServiceProviderBag',
+            'accessTokensByClient',
+            'refreshTokensByClient',
+            'oidcProtocolDesignation'
+        );
 
         return $template;
     }
@@ -135,25 +204,159 @@ class Profile
         $activityBag = $authenticationDataProvider->getActivity($userIdentifier, $maxResults, $firstResult);
 
         $template = $this->resolveTemplate('accounting:user/activity.twig');
-        $template->data = compact('activityBag', 'page', 'maxResults');
+        $template->data += compact('activityBag', 'page', 'maxResults');
 
         return $template;
     }
 
+    /**
+     * @throws Exception|ConfigurationError
+     */
+    public function oidcTokens(): Response
+    {
+        $oidc = $this->sspModuleManager->getOidc();
+
+        // If oidc module is not enabled, this route should not be called.
+        if (!$oidc->isEnabled()) {
+            return new RedirectResponse($this->helpersManager->getRoutes()->getUrl(Routes::PATH_USER_PERSONAL_DATA));
+        }
+
+        $userIdentifier = $this->resolveUserIdentifier();
+
+        $accessTokensByClient = $this->helpersManager->getArr()->groupByValue(
+            $oidc->getUsersAccessTokens($userIdentifier),
+            'client_id'
+        );
+
+        $refreshTokensByClient = $this->helpersManager->getArr()->groupByValue(
+            $oidc->getUsersRefreshTokens($userIdentifier),
+            'client_id'
+        );
+
+        $clientIds = array_unique(array_merge(array_keys($accessTokensByClient), array_keys($refreshTokensByClient)));
+        $clients = $this->helpersManager->getArr()->groupByValue(
+            $oidc->getClients($clientIds),
+            'id'
+        );
+
+        //die(var_dump($accessTokensByClient, $refreshTokensByClient, $clientIds, $clients));
+
+        $template = $this->resolveTemplate('accounting:user/oidc-tokens.twig');
+        $template->data += compact('accessTokensByClient', 'refreshTokensByClient', 'clients');
+
+        return $template;
+    }
+
+    public function oidcTokenRevoke(Request $request): Response
+    {
+        $oidc = $this->sspModuleManager->getOidc();
+
+        // If oidc module is not enabled, this route should not be called.
+        if (! $oidc->isEnabled()) {
+            return new RedirectResponse($this->helpersManager->getRoutes()->getUrl(Routes::PATH_USER_PERSONAL_DATA));
+        }
+
+        $redirectTo = (string) $request->query->get(Routes::QUERY_REDIRECT_TO_PATH, Routes::PATH_USER_OIDC_TOKENS);
+
+        $response = new RedirectResponse(
+            $this->helpersManager->getRoutes()->getUrl($redirectTo)
+        );
+
+        if (! $this->csrfToken->validate($request->request->getAlnum('csrf-token'))) {
+            $this->alertsBag->put(
+                new AlertsBag\Alert('Could not verify CSRF token.', 'warning')
+            );
+
+            return $response;
+        }
+
+        $validTokenTypes = ['access', 'refresh'];
+
+        $tokenType = $request->request->getAlnum('token-type');
+
+        if (! in_array($tokenType, $validTokenTypes)) {
+            $this->alertsBag->put(
+                new AlertsBag\Alert('Token type not valid.', 'warning')
+            );
+            return $response;
+        }
+
+        $tokenId = $request->request->getAlnum('token-id');
+
+        $userIdentifier = $this->resolveUserIdentifier();
+
+        if ($tokenType === 'access') {
+            $oidc->revokeUsersAccessToken($userIdentifier, $tokenId);
+        } elseif ($tokenType === 'refresh') {
+            $oidc->revokeUsersRefreshToken($userIdentifier, $tokenId);
+        }
+
+        $this->alertsBag->put(
+            new AlertsBag\Alert('Token revoked successfully.', 'success')
+        );
+
+        return $response;
+    }
+
+    public function oidcTokenRevokeXhr(Request $request): Response
+    {
+
+        $oidc = $this->sspModuleManager->getOidc();
+        $response = new JsonResponse();
+
+
+        // If oidc module is not enabled, this route should not be called.
+        if (! $oidc->isEnabled()) {
+            return new JsonResponse(['status' => 'error', 'message' => 'Not available.'], 404);
+        }
+
+        if (! $this->csrfToken->validate((string) $request->cookies->get(CsrfToken::KEY))) {
+            $this->appendCsrfCookie($response);
+            return $response
+                ->setData(['status' => 'error', 'message' => 'CSRF validation failed.'])
+                ->setStatusCode(400);
+        }
+
+        $this->appendCsrfCookie($response);
+
+        $validTokenTypes = ['access', 'refresh'];
+
+        $tokenType = $request->request->getAlnum('token-type');
+
+        if (! in_array($tokenType, $validTokenTypes)) {
+            return $response
+                ->setData(['status' => 'error', 'message' => 'Token type not valid.'])
+                ->setStatusCode(422);
+        }
+
+        $tokenId = $request->request->getAlnum('token-id');
+
+        $userIdentifier = $this->resolveUserIdentifier();
+
+        if ($tokenType === 'access') {
+            $oidc->revokeUsersAccessToken($userIdentifier, $tokenId);
+        } elseif ($tokenType === 'refresh') {
+            $oidc->revokeUsersRefreshToken($userIdentifier, $tokenId);
+        }
+
+        return $response
+            ->setData(['status' => 'success', 'message' => 'Token revoked successfully.']);
+    }
+
     /**
      * @throws Exception
      */
     protected function resolveUserIdentifier(): string
     {
-        $attributes = $this->authSimple->getAttributes();
-        $idAttributeName = $this->moduleConfiguration->getUserIdAttributeName();
+        $userIdAttributeName = $this->moduleConfiguration->getUserIdAttributeName();
+        $userIdentifier = $this->user->getFirstAttributeValue($userIdAttributeName);
 
-        if (empty($attributes[$idAttributeName]) || !is_array($attributes[$idAttributeName])) {
-            $message = sprintf('No identifier %s present in user attributes.', $idAttributeName);
+        if (is_null($userIdentifier)) {
+            $message = sprintf('No identifier %s present in user attributes.', $userIdAttributeName);
             throw new Exception($message);
         }
 
-        return (string)reset($attributes[$idAttributeName]);
+        return $userIdentifier;
     }
 
     /**
@@ -204,6 +407,64 @@ class Profile
         $templateInstance->getLocalization()->addModuleDomain(ModuleConfiguration::MODULE_NAME);
         $templateInstance->getLocalization()->addAttributeDomains();
 
+        $templateInstance->data = [
+            'menuManager' => $this->menuManager,
+            'csrfToken' => $this->csrfToken,
+            'alertsBag' => $this->alertsBag,
+        ];
+
+        // Make CSRF token also available as a cookie, so it can be used for XHR POST requests validation.
+        $this->appendCsrfCookie($templateInstance);
+
         return $templateInstance;
     }
+
+    protected function prepareMenuManager(): MenuManager
+    {
+        $menuManager = new MenuManager();
+
+        $menuManager->addItems(
+            new MenuManager\MenuItem(
+                'personal-data',
+                Translate::noop('Personal Data'),
+                'css/src/icons/prof-page.svg'
+            ),
+            new MenuManager\MenuItem(
+                'connected-organizations',
+                Translate::noop('Connected Organizations'),
+                'css/src/icons/conn-orgs.svg'
+            ),
+            new MenuManager\MenuItem(
+                'activity',
+                Translate::noop('Activity'),
+                'css/src/icons/activity.svg'
+            )
+        );
+
+        // Depending on other functionalities, add additional menu items.
+        if ($this->sspModuleManager->getOidc()->isEnabled()) {
+            $menuManager->addItems(
+                new MenuManager\MenuItem(
+                    'oidc-tokens',
+                    Translate::noop('Tokens'),
+                    'css/src/icons/activity.svg'
+                )
+            );
+        }
+
+        $menuManager->addItems(
+            new MenuManager\MenuItem(
+                'logout',
+                Translate::noop('Log out'),
+                'css/src/icons/logout.svg'
+            )
+        );
+
+        return $menuManager;
+    }
+
+    protected function appendCsrfCookie(Response $response): void
+    {
+        $response->headers->setCookie(new Cookie(CsrfToken::KEY, $this->csrfToken->get()));
+    }
 }
diff --git a/src/Services/AlertsBag.php b/src/Services/AlertsBag.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e392e26d757f2fffc5682e264f5cc693da3639e
--- /dev/null
+++ b/src/Services/AlertsBag.php
@@ -0,0 +1,54 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SimpleSAML\Module\accounting\Services;
+
+use SimpleSAML\Module\accounting\Exceptions\Exception;
+use SimpleSAML\Module\accounting\ModuleConfiguration;
+use SimpleSAML\Module\accounting\Services\AlertsBag\Alert;
+use SimpleSAML\Session;
+
+class AlertsBag
+{
+    protected Session $sspSession;
+
+    public const SESSION_KEY = 'alerts';
+
+    public function __construct(Session $session)
+    {
+        $this->sspSession = $session;
+    }
+
+    public function isNotEmpty(): bool
+    {
+        return ! empty($this->getAll(false));
+    }
+
+    /**
+     * @throws Exception
+     */
+    public function getAll(bool $reinitialize = true): array
+    {
+        $alerts = $this->sspSession->getData(ModuleConfiguration::MODULE_NAME, self::SESSION_KEY) ?? [];
+
+        if (! is_array($alerts)) {
+            throw new Exception('Unexpected value type.');
+        }
+
+        if ($reinitialize) {
+            $this->sspSession->setData(ModuleConfiguration::MODULE_NAME, self::SESSION_KEY, null);
+        }
+
+        return $alerts;
+    }
+
+    public function put(Alert $alert): void
+    {
+        $this->sspSession->setData(
+            ModuleConfiguration::MODULE_NAME,
+            self::SESSION_KEY,
+            array_merge($this->getAll(false), [$alert])
+        );
+    }
+}
diff --git a/src/Services/AlertsBag/Alert.php b/src/Services/AlertsBag/Alert.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e4db04f34f31a97455f66f897ecfed6283f72cd
--- /dev/null
+++ b/src/Services/AlertsBag/Alert.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace SimpleSAML\Module\accounting\Services\AlertsBag;
+
+class Alert
+{
+    protected string $message;
+    protected string $level;
+
+    public function __construct(
+        string $message,
+        string $level
+    ) {
+        $this->message = $message;
+        $this->level = $level;
+    }
+
+    public function getMessage(): string
+    {
+        return $this->message;
+    }
+
+    public function getLevel(): string
+    {
+        return $this->level;
+    }
+}
diff --git a/src/Services/CsrfToken.php b/src/Services/CsrfToken.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff2d2c577cd44aa2881b5b434b9ad5dc661b69cf
--- /dev/null
+++ b/src/Services/CsrfToken.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SimpleSAML\Module\accounting\Services;
+
+use SimpleSAML\Module\accounting\ModuleConfiguration;
+use SimpleSAML\Session;
+
+class CsrfToken
+{
+    protected Session $session;
+
+    public const KEY = 'ssp-' . ModuleConfiguration::MODULE_NAME . '-csrf-token';
+    protected HelpersManager $helpersManager;
+
+    public function __construct(
+        Session $session = null,
+        HelpersManager $helpersManager = null
+    ) {
+        $this->session = $session ?? Session::getSessionFromRequest();
+        $this->helpersManager = $helpersManager ?? new HelpersManager();
+
+        if ($this->get() === null) {
+            $this->set();
+        }
+    }
+
+    protected function set(?string $token = null): void
+    {
+        $this->session->setData(
+            ModuleConfiguration::MODULE_NAME,
+            self::KEY,
+            $token ?? $this->helpersManager->getRandom()->getString()
+        );
+    }
+
+    public function get(): ?string
+    {
+        $token = $this->session->getData(ModuleConfiguration::MODULE_NAME, self::KEY);
+
+        if ($token !== null) {
+            return (string) $token;
+        }
+
+        return null;
+    }
+
+    public function validate(string $token): bool
+    {
+        $isValid = $token === $this->get();
+
+        $this->set();
+
+        return $isValid;
+    }
+}
diff --git a/src/Services/HelpersManager.php b/src/Services/HelpersManager.php
index e61c64d2f012c0084ad8a76f08fc2f07e70799e9..5fe3a362f58a6e81347757fa92678d073ac7096d 100644
--- a/src/Services/HelpersManager.php
+++ b/src/Services/HelpersManager.php
@@ -15,14 +15,15 @@ use SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfiguration
 use SimpleSAML\Module\accounting\Helpers\Network;
 use SimpleSAML\Module\accounting\Helpers\ProviderResolver;
 use SimpleSAML\Module\accounting\Helpers\Random;
-use SimpleSAML\Module\accounting\Helpers\ModuleRoutes;
+use SimpleSAML\Module\accounting\Helpers\Routes;
+use SimpleSAML\Module\accounting\Helpers\SspModule;
 
 class HelpersManager
 {
     protected static ?DateTime $dateTime;
     protected static ?Environment $environment;
     protected static ?Random $random;
-    protected static ?ModuleRoutes $routes;
+    protected static ?Routes $routes;
     protected static ?Arr $arr;
     protected static ?Hash $hash;
     protected static ?Attributes $attributes;
@@ -31,6 +32,7 @@ class HelpersManager
     protected static ?Network $network;
     protected static ?AuthenticationEventStateResolver $authenticationEventStateResolver;
     protected static ?ProviderResolver $providerResolver;
+    protected static ?SspModule $sspModule;
 
 
     public function getDateTime(): DateTime
@@ -48,9 +50,9 @@ class HelpersManager
         return self::$random ??= new Random();
     }
 
-    public function getModuleRoutes(): ModuleRoutes
+    public function getRoutes(): Routes
     {
-        return self::$routes ??= new ModuleRoutes();
+        return self::$routes ??= new Routes();
     }
 
     public function getArr(): Arr
@@ -92,4 +94,9 @@ class HelpersManager
     {
         return self::$providerResolver ??= new ProviderResolver();
     }
+
+    public function getSspModule(): SspModule
+    {
+        return self::$sspModule ??= new SspModule();
+    }
 }
diff --git a/src/Services/JobRunner.php b/src/Services/JobRunner.php
index 0e9fc05d6491fe331ac699562f2cfb7737c9ff96..12b47e2fbbefeb4be1b848764e0a8941ecd38de8 100644
--- a/src/Services/JobRunner.php
+++ b/src/Services/JobRunner.php
@@ -79,7 +79,7 @@ class JobRunner
 
         $this->cache = $cache ?? $this->resolveCache();
 
-        $this->jobRunnerId = $this->helpersManager->getRandom()->getRandomInt();
+        $this->jobRunnerId = $this->helpersManager->getRandom()->getInt();
 
         $this->state = $state ?? new State($this->jobRunnerId);
 
diff --git a/src/Services/MenuManager.php b/src/Services/MenuManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..45ae8287998dbaccffd9aec5fcb6e443e0aa5c84
--- /dev/null
+++ b/src/Services/MenuManager.php
@@ -0,0 +1,41 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SimpleSAML\Module\accounting\Services;
+
+use SimpleSAML\Module\accounting\Services\MenuManager\MenuItem;
+
+class MenuManager
+{
+    /** @var array<MenuItem> */
+    protected array $items = [];
+
+    /**
+     * Add MenuItems to the end of the list.
+     * @param MenuItem ...$menuItems
+     * @return void
+     */
+    public function addItems(MenuItem ...$menuItems): void
+    {
+        array_push($this->items, ...$menuItems);
+    }
+
+    /**
+     * Add MenuItem to specific offset (position). If offset not set, MenuItem will be appended to the end.
+     * @param MenuItem $menuItem
+     * @param int|null $offset
+     * @return void
+     */
+    public function addItem(MenuItem $menuItem, int $offset = null): void
+    {
+        $offset = $offset ?? count($this->items);
+
+        array_splice($this->items, $offset, 0, [$menuItem]);
+    }
+
+    public function getItems(): array
+    {
+        return $this->items;
+    }
+}
diff --git a/src/Services/MenuManager/MenuItem.php b/src/Services/MenuManager/MenuItem.php
new file mode 100644
index 0000000000000000000000000000000000000000..aef046f490c0404bc172c765e8f702149da055c8
--- /dev/null
+++ b/src/Services/MenuManager/MenuItem.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SimpleSAML\Module\accounting\Services\MenuManager;
+
+class MenuItem
+{
+    protected string $hrefPath;
+    protected string $label;
+    protected ?string $iconAssetPath;
+
+    public function __construct(
+        string $hrefPath,
+        string $label,
+        string $iconAssetPath = null
+    ) {
+        $this->hrefPath = $hrefPath;
+        $this->label = $label;
+        $this->iconAssetPath = $iconAssetPath;
+    }
+
+    /**
+     * @return string
+     */
+    public function getHrefPath(): string
+    {
+        return $this->hrefPath;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLabel(): string
+    {
+        return $this->label;
+    }
+
+    /**
+     * @return string
+     */
+    public function getIconAssetPath(): ?string
+    {
+        return $this->iconAssetPath;
+    }
+}
diff --git a/src/Services/SspModuleManager.php b/src/Services/SspModuleManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c55cf6b691e2437fb932eb8a7e05912b8f80fe7
--- /dev/null
+++ b/src/Services/SspModuleManager.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SimpleSAML\Module\accounting\Services;
+
+use Psr\Log\LoggerInterface;
+use SimpleSAML\Module\accounting\SspModule\Oidc;
+
+class SspModuleManager
+{
+    protected LoggerInterface $logger;
+    protected HelpersManager $helpersManager;
+
+    protected static ?Oidc $oidc;
+
+    public function __construct(
+        LoggerInterface $logger = null,
+        HelpersManager $helpersManager = null
+    ) {
+        $this->logger = $logger ?? new Logger();
+        $this->helpersManager = $helpersManager ?? new HelpersManager();
+    }
+
+    public function getOidc(): Oidc
+    {
+        return self::$oidc ??= new Oidc(
+            $this->logger,
+            $this->helpersManager
+        );
+    }
+}
diff --git a/src/SspModule/Oidc.php b/src/SspModule/Oidc.php
new file mode 100644
index 0000000000000000000000000000000000000000..f9850412b27a4ec3222c88d16b40d174b5c13760
--- /dev/null
+++ b/src/SspModule/Oidc.php
@@ -0,0 +1,241 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SimpleSAML\Module\accounting\SspModule;
+
+use Psr\Log\LoggerInterface;
+use SimpleSAML\Database;
+use SimpleSAML\Module\accounting\Services\HelpersManager;
+use SimpleSAML\Module\accounting\Services\Logger;
+use SimpleSAML\Module\oidc\Repositories\AccessTokenRepository;
+use SimpleSAML\Module\oidc\Repositories\ClientRepository;
+use SimpleSAML\Module\oidc\Repositories\RefreshTokenRepository;
+use SimpleSAML\Module\oidc\Services\Container;
+
+class Oidc
+{
+    public const MODULE_NAME = 'oidc';
+    public const DEFAULT_LIMIT = 50;
+
+    protected LoggerInterface $logger;
+    protected HelpersManager $helpersManager;
+    protected bool $isEnabled = false;
+    protected Container $container;
+    protected Database $database;
+
+    public function __construct(
+        LoggerInterface $logger = null,
+        HelpersManager $helpersManager = null,
+        Container $container = null,
+        Database $database = null
+    ) {
+        $this->logger = $logger ?? new Logger();
+        $this->helpersManager = $helpersManager ?? new HelpersManager();
+        $this->container = $container ?? new Container();
+        $this->database = $database ?? Database::getInstance();
+
+        $this->isEnabled = $this->helpersManager->getSspModule()->isEnabled(self::MODULE_NAME);
+    }
+
+    /**
+     * @return bool
+     */
+    public function isEnabled(): bool
+    {
+        return $this->isEnabled;
+    }
+
+    /**
+     * @return Container
+     */
+    public function getContainer(): Container
+    {
+        return $this->container;
+    }
+
+    public function getUsersAccessTokens(
+        string $userId,
+        ?array $clientIds = null,
+        ?int $limit = self::DEFAULT_LIMIT
+    ): array {
+        $sql = sprintf(
+            <<<EOF
+            SELECT id, client_id, expires_at, is_revoked
+            FROM %s
+            WHERE user_id = :user_id AND is_revoked = 0 AND expires_at > '%s'
+            EOF,
+            $this->getPrefixedTableName(AccessTokenRepository::TABLE_NAME),
+            $this->helpersManager->getDateTime()->toFormattedString()
+        );
+
+        $params = ['user_id' => $userId,];
+
+        if ($clientIds !== null) {
+            $index = 0;
+            $clientIdPlaceholders = [];
+            $clientIdParams = [];
+
+            /** @var string $clientId */
+            foreach ($clientIds as $clientId) {
+                $currentPlaceholder = 'client_id' . $index++;
+                $clientIdPlaceholders[] = ':' . $currentPlaceholder;
+                $clientIdParams[$currentPlaceholder] = $clientId;
+            }
+
+            $sql .= ' AND client_id IN (' . implode(', ', $clientIdPlaceholders) . ')';
+            $params += $clientIdParams;
+        }
+
+        $sql .= ' ORDER BY client_id, expires_at';
+
+        if ($limit > 0) {
+            $sql .= ' LIMIT ' . $limit;
+        }
+
+        $statement = $this->database->read($sql, $params);
+
+        if (!$data = $statement->fetchAll(\PDO::FETCH_ASSOC)) {
+            $this->logger->debug('No OIDC access tokens available for user ID ' . $userId);
+            return [];
+        }
+
+        return $data;
+    }
+
+    /**
+     * @param string $userId
+     * @param string $accessTokenId
+     * @return false|int
+     */
+    public function revokeUsersAccessToken(string $userId, string $accessTokenId)
+    {
+        $sql = sprintf(
+            <<<EOF
+            UPDATE %s
+            SET is_revoked = 1
+            WHERE user_id = :user_id AND id = :access_token_id
+            EOF,
+            $this->getPrefixedTableName(AccessTokenRepository::TABLE_NAME),
+        );
+
+        $params = ['user_id' => $userId, 'access_token_id' => $accessTokenId];
+
+        return $this->database->write($sql, $params);
+    }
+
+    public function getUsersRefreshTokens(
+        string $userId,
+        ?array $clientIds = null,
+        ?int $limit = self::DEFAULT_LIMIT
+    ): array {
+        $sql = sprintf(
+            <<<EOF
+            SELECT ort.id, oat.client_id, ort.expires_at, ort.is_revoked
+            FROM %s AS ort
+            INNER JOIN %s as oat ON ort.access_token_id = oat.id
+            WHERE oat.user_id = :user_id AND ort.is_revoked = 0 AND ort.expires_at > '%s'
+            EOF,
+            $this->getPrefixedTableName(RefreshTokenRepository::TABLE_NAME),
+            $this->getPrefixedTableName(AccessTokenRepository::TABLE_NAME),
+            $this->helpersManager->getDateTime()->toFormattedString()
+        );
+
+        $params = ['user_id' => $userId,];
+
+        if ($clientIds !== null) {
+            $index = 0;
+            $clientIdPlaceholders = [];
+            $clientIdParams = [];
+
+            /** @var string $clientId */
+            foreach ($clientIds as $clientId) {
+                $currentPlaceholder = 'client_id' . $index++;
+                $clientIdPlaceholders[] = ':' . $currentPlaceholder;
+                $clientIdParams[$currentPlaceholder] = $clientId;
+            }
+
+            $sql .= ' AND oat.client_id IN (' . implode(', ', $clientIdPlaceholders) . ')';
+            $params += $clientIdParams;
+        }
+
+        $sql .= ' ORDER BY oat.client_id, ort.expires_at';
+
+        if ($limit > 0) {
+            $sql .= ' LIMIT ' . $limit;
+        }
+
+        $statement = $this->database->read($sql, $params);
+
+        if (!$data = $statement->fetchAll(\PDO::FETCH_ASSOC)) {
+            $this->logger->debug('No OIDC refresh tokens available for user ID ' . $userId);
+            return [];
+        }
+
+        return $data;
+    }
+
+    /**
+     * @param string $userId
+     * @param string $refreshTokenId
+     * @return false|int
+     */
+    public function revokeUsersRefreshToken(string $userId, string $refreshTokenId)
+    {
+        $sql = sprintf(
+            <<<EOF
+            UPDATE %s AS ort
+            INNER JOIN %s as oat ON ort.access_token_id = oat.id
+            SET ort.is_revoked = 1
+            WHERE oat.user_id = :user_id AND ort.id = :refresh_token_id
+            EOF,
+            $this->getPrefixedTableName(RefreshTokenRepository::TABLE_NAME),
+            $this->getPrefixedTableName(AccessTokenRepository::TABLE_NAME),
+        );
+
+        $params = ['user_id' => $userId, 'refresh_token_id' => $refreshTokenId];
+
+        return $this->database->write($sql, $params);
+    }
+
+    public function getClients(array $clientIds): array
+    {
+        $index = 0;
+        $clientIdPlaceholders = [];
+        $clientIdParams = [];
+
+        /** @var string $clientId */
+        foreach ($clientIds as $clientId) {
+            $currentPlaceholder = 'client_id' . $index++;
+            $clientIdPlaceholders[] = ':' . $currentPlaceholder;
+            $clientIdParams[$currentPlaceholder] = $clientId;
+        }
+
+        $sql = sprintf(
+            <<<EOF
+            SELECT id, name, description
+            FROM %s
+            EOF,
+            $this->getPrefixedTableName(ClientRepository::TABLE_NAME),
+        );
+
+        $sql .= ' WHERE id IN (' . implode(', ', $clientIdPlaceholders) . ')';
+        $sql .= ' ORDER BY name';
+
+        $params = $clientIdParams;
+
+        $statement = $this->database->read($sql, $params);
+
+        if (!$data = $statement->fetchAll(\PDO::FETCH_ASSOC)) {
+            $this->logger->debug('No OIDC clients available for ' . var_export($clientIds, true));
+            return [];
+        }
+
+        return $data;
+    }
+
+    protected function getPrefixedTableName(string $tableName): string
+    {
+        return $this->database->applyPrefix($tableName);
+    }
+}
diff --git a/src/Traits/HasUserAttributesTrait.php b/src/Traits/HasUserAttributesTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..13e30450bdd94a38e92c8252188e92a0e06b2dec
--- /dev/null
+++ b/src/Traits/HasUserAttributesTrait.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SimpleSAML\Module\accounting\Traits;
+
+trait HasUserAttributesTrait
+{
+    protected array $attributes = [];
+
+    public function getAttributes(): array
+    {
+        return $this->attributes;
+    }
+
+    public function getFirstAttributeValue(string $attributeName): ?string
+    {
+        if (($value = $this->getAttributeValue($attributeName)) !== null) {
+            return (string)reset($value);
+        }
+
+        return null;
+    }
+
+    public function getAttributeValue(string $attributeName): ?array
+    {
+        if (!empty($this->attributes[$attributeName]) && is_array($this->attributes[$attributeName])) {
+            return $this->attributes[$attributeName];
+        }
+
+        return null;
+    }
+}
diff --git a/templates/base.twig b/templates/base.twig
index 6ee008bde89bdcc8aaad74aef745c0397fe86de7..d07567be3d9081aab97108a4a3241ae3b3de837e 100644
--- a/templates/base.twig
+++ b/templates/base.twig
@@ -24,6 +24,8 @@
 {% block banner %}{% endblock %}
 
 <section id="main">
+    {% include '@accounting/includes/_alerts.twig' %}
+
     {% block content %}{% endblock %}
 </section>
 
@@ -35,5 +37,24 @@
         {% endtrans %}
     </div>
 </footer>
+
+<script>
+    const accounting = {
+        alert: function (message) {
+            // TODO implement nice alerts.
+            alert(message);
+        },
+        removeElement: function (element, speed = 500) {
+            const seconds = speed / 1000;
+            element.style.transition = "opacity " + seconds + "s ease";
+            element.style.opacity = 0;
+            setTimeout(function() {
+                element.parentNode.removeChild(element);
+            }, speed);
+        }
+    };
+</script>
+
+{% block tail %}{% endblock %}
 </body>
 </html>
\ No newline at end of file
diff --git a/templates/includes/_alerts.twig b/templates/includes/_alerts.twig
new file mode 100644
index 0000000000000000000000000000000000000000..5e3d80ade0cbe32e8e9bbbd9df6492434551faa9
--- /dev/null
+++ b/templates/includes/_alerts.twig
@@ -0,0 +1,14 @@
+
+{# @var alertsBag \SimpleSAML\Module\accounting\Services\AlertsBag #}
+{# @var alert \SimpleSAML\Module\accounting\Services\AlertsBag\Alert #}
+
+{% if alertsBag is defined and alertsBag.isNotEmpty %}
+    <div class="alerts">
+        {% for alert in alertsBag.getAll %}
+            <div class="alert">
+                <span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
+                {{ alert.message }}
+            </div>
+        {% endfor %}
+    </div>
+{% endif %}
\ No newline at end of file
diff --git a/templates/includes/_navigation.twig b/templates/includes/_navigation.twig
index a77537ae85dde946bf4dd24235e427f19976041e..90a76e4fa1ce6be0e37ef04cb16589f400b93435 100644
--- a/templates/includes/_navigation.twig
+++ b/templates/includes/_navigation.twig
@@ -1,40 +1,24 @@
+{# @var menuManager \SimpleSAML\Module\accounting\Services\MenuManager #}
+{# @var menuItem \SimpleSAML\Module\accounting\Services\MenuManager\MenuItem #}
+{# @var csrfToken \SimpleSAML\Module\accounting\Services\CsrfToken #}
+
 <div id="nav">
     <input type="checkbox" id="nav-toggle" class="nav-toggle">
     <nav role="navigation" aria-label="XXX-pagedesc-XXX">
         <ul>
-            <li>
-                <a href="personal-data">
-                    <span class="navicon">
-                        <img src="{{ asset('css/src/icons/prof-page.svg', 'accounting') }}" alt="Profile Page Icon"/>
-                    </span>
-                    <span class="navlabel">{{ 'Personal Data'|trans }}</span>
-                </a>
-            </li>
-            <li>
-                <a href="connected-organizations">
-                    <span class="navicon">
-                        <img src="{{ asset('css/src/icons/conn-orgs.svg', 'accounting') }}"
-                             alt="Connected Organizations Icon"/>
-                    </span>
-                    <span class="navlabel">{{ 'Connected Organizations'|trans }}</span>
-                </a>
-            </li>
-            <li>
-                <a href="activity">
-                    <span class="navicon">
-                        <img src="{{ asset('css/src/icons/activity.svg', 'accounting') }}" alt="Activity Icon"/>
-                    </span>
-                    <span class="navlabel">{{ 'Activity'|trans }}</span>
-                </a>
-            </li>
-            <li>
-                <a href="logout">
-                    <span class="navicon">
-                        <img src="{{ asset('css/src/icons/logout.svg', 'accounting') }}" alt="Logout Icon"/>
-                    </span>
-                    <span class="navlabel">{{ 'Log out'|trans }}</span>
-                </a>
-            </li>
+            {% for menuItem in menuManager.items %}
+                <li>
+                    <a href="{{ menuItem.hrefPath }}">
+                        {% if menuItem.iconAssetPath %}
+                            <span class="navicon">
+                                <img src="{{ asset(menuItem.iconAssetPath, 'accounting') }}"
+                                     alt="{{ menuItem.label|trans }} Icon"/>
+                            </span>
+                        {% endif %}
+                        <span class="navlabel">{{ menuItem.label|trans }}</span>
+                    </a>
+                </li>
+            {% endfor %}
         </ul>
     </nav>
 </div>
\ No newline at end of file
diff --git a/templates/user/connected-organizations.twig b/templates/user/connected-organizations.twig
index 69851706db384fbe79130699237635b7393a9b93..00d545462f8c11162b205dbe851fbacc26288342 100644
--- a/templates/user/connected-organizations.twig
+++ b/templates/user/connected-organizations.twig
@@ -1,5 +1,7 @@
 {# @var connectedServiceProviderBag \SimpleSAML\Module\accounting\Entities\ConnectedServiceProvider\Bag #}
 {# @var connectedServiceProvider \SimpleSAML\Module\accounting\Entities\ConnectedServiceProvider #}
+{# @var accessTokensByClient array #}
+{# @var refreshTokensByClient array #}
 
 {% extends "@accounting/base.twig" %}
 
@@ -17,7 +19,7 @@
         </tr>
 
         {% for connectedServiceProvider in connectedServiceProviderBag.getAll %}
-            <tr>
+            <tr id="connected-service-provider-{{ loop.index }}">
                 <td>{{ connectedServiceProvider.getServiceProvider.getName|e }}</td>
                 <td>{{ connectedServiceProvider.getNumberOfAuthentications|e }}</td>
                 <td>{{ connectedServiceProvider.getLastAuthenticationAt|date() }}</td>
@@ -28,7 +30,7 @@
                     <label class="dropdown-label" for="dropdown-toggle-{{ loop.index }}">
                         <img src="{{ asset('css/src/icons/dropdown.svg', 'accounting') }}" alt="Dropdown icon">
                     </label>
-                    <div class="dropdown-box">
+                    <div class="dropdown-box" >
                         <strong>{{ 'Service details'|trans }}</strong>
                         <ul>
                             <li>{{ 'Entity ID'|trans }}: {{ connectedServiceProvider.getServiceProvider.getEntityId|e }}</li>
@@ -44,6 +46,50 @@
                                 {{ 'Last access'|trans }}: {{ connectedServiceProvider.getLastAuthenticationAt|date() }}
                             </li>
                         </ul>
+
+                        {% if connectedServiceProvider.serviceProvider.protocol.designation is same as oidcProtocolDesignation %}
+                            {% if accessTokensByClient is not empty and attribute(accessTokensByClient, connectedServiceProvider.serviceProvider.entityId) %}
+                                <strong>{{ 'Access Tokens'|trans }}</strong>
+                                <table>
+                                    {% for accessToken in attribute(accessTokensByClient, connectedServiceProvider.serviceProvider.entityId) %}
+                                        <tr>
+                                            <td>
+                                                {{ accessToken.id }}<br>
+                                                {{ 'Expires at'|trans }} {{ accessToken.expires_at|date }}
+                                            </td>
+                                            <td>
+                                                <form class="token-revoke-form" action="oidc-tokens/revoke-xhr">
+                                                    <input type="hidden" name="token-type" value="access">
+                                                    <input type="hidden" name="token-id" value="{{ accessToken.id }}">
+                                                    <input type="submit" value="Revoke">
+                                                </form>
+                                            </td>
+                                        </tr>
+                                    {% endfor %}
+                                </table>
+                            {% endif %}
+
+                            {% if refreshTokensByClient is not empty and attribute(refreshTokensByClient, connectedServiceProvider.serviceProvider.entityId) %}
+                                <strong>{{ 'Refresh Tokens'|trans }}</strong>
+                                <table>
+                                    {% for refreshToken in attribute(refreshTokensByClient, connectedServiceProvider.serviceProvider.entityId) %}
+                                        <tr>
+                                            <td>
+                                                {{ refreshToken.id }}<br>
+                                                {{ 'Expires at'|trans }} {{ refreshToken.expires_at|date }}
+                                            </td>
+                                            <td>
+                                                <form class="token-revoke-form" action="oidc-tokens/revoke-xhr">
+                                                    <input type="hidden" name="token-type" value="refresh">
+                                                    <input type="hidden" name="token-id" value="{{ refreshToken.id }}">
+                                                    <input type="submit" value="Revoke">
+                                                </form>
+                                            </td>
+                                        </tr>
+                                    {% endfor %}
+                                </table>
+                            {% endif %}
+                        {% endif %}
                     </div>
                 </td>
             </tr>
@@ -55,3 +101,45 @@
         <!-- end of repeating item -->
     </table>
 {% endblock %}
+
+{% block tail %}
+
+    <script>
+        (function () {
+            document.querySelectorAll('.token-revoke-form').forEach(
+                element => element.addEventListener('submit', revokeToken)
+            );
+
+            function revokeToken(event) {
+                event.preventDefault();
+
+                const form = event.target;
+                const submitButton = event.submitter;
+                const formData = new FormData(form);
+
+                if (! confirm('{{ 'Are you sure?'|trans }}')) {
+                    return;
+                }
+
+                submitButton.disabled = true;
+
+                const request = new XMLHttpRequest();
+
+                request.open('POST', form.action);
+
+                request.onload = function () {
+                    if (this.status === 200) {
+                        accounting.removeElement(form.closest('tr'));
+                    } else {
+                        const response = JSON.parse(this.responseText);
+                        console.log(response);
+                        accounting.alert('{{ 'Oups, there was an error while trying to revoke token.'|trans }}');
+                    }
+                };
+
+                request.send(formData);
+            }
+        })();
+    </script>
+
+{% endblock %}
\ No newline at end of file
diff --git a/templates/user/oidc-tokens.twig b/templates/user/oidc-tokens.twig
new file mode 100644
index 0000000000000000000000000000000000000000..0f9c6e95125f3ae97478a4e971929bf977e54495
--- /dev/null
+++ b/templates/user/oidc-tokens.twig
@@ -0,0 +1,78 @@
+{# @var accessTokensByClient array #}
+{# @var refreshTokensByClient array #}
+{# @var clients array #}
+
+{% extends "@accounting/base.twig" %}
+
+{% set pagetitle = 'OIDC Tokens'|trans %}
+
+{% set pageMenuItem = 'oidc-tokens' %}
+
+{% block content %}
+    <section id="banner">
+        <div>
+            {% trans %}Overview of active OIDC Access / Refresh Tokens by OIDC client.{% endtrans %}
+        </div>
+    </section>
+
+    <table>
+        {% for clientId, clientInfo in clients %}
+            <tr>
+                <td colspan="2">
+                    <strong>{{ clientInfo.0.name }}</strong>
+                    <br>
+                    {{ clientInfo.0.description }}
+                </td>
+            </tr>
+
+            {% if accessTokensByClient is not empty and attribute(accessTokensByClient, clientId) %}
+                <tr>
+                    <td colspan="2">{{ 'Access Tokens'|trans }}</td>
+                </tr>
+                {% for accessToken in attribute(accessTokensByClient, clientId) %}
+                <tr>
+                    <td>
+                        {{ accessToken.id }}<br>
+                        {{ 'Expires at'|trans }} {{ accessToken.expires_at|date }}
+                    </td>
+                    <td>
+                        <form method="post" action="oidc-tokens/revoke">
+                            <input type="hidden" name="csrf-token" value="{{ csrfToken.get }}">
+                            <input type="hidden" name="token-type" value="access">
+                            <input type="hidden" name="token-id" value="{{ accessToken.id }}">
+                            <input type="submit" value="Revoke">
+                        </form>
+                    </td>
+                </tr>
+                {% endfor %}
+            {% endif %}
+
+            {% if refreshTokensByClient is not empty and attribute(refreshTokensByClient, clientId) %}
+                <tr>
+                    <td colspan="2">{{ 'Refresh Tokens'|trans }}</td>
+                </tr>
+                {% for refreshToken in attribute(refreshTokensByClient, clientId) %}
+                    <tr>
+                        <td>
+                            {{ refreshToken.id }}<br>
+                            {{ 'Expires at'|trans }} {{ refreshToken.expires_at|date }}
+                        </td>
+                        <td>
+                            <form method="post" action="oidc-tokens/revoke">
+                                <input type="hidden" name="csrf-token" value="{{ csrfToken.get }}">
+                                <input type="hidden" name="token-type" value="refresh">
+                                <input type="hidden" name="token-id" value="{{ refreshToken.id }}">
+                                <input type="submit" value="Revoke">
+                            </form>
+                        </td>
+                    </tr>
+                {% endfor %}
+            {% endif %}
+        {% else %}
+            <tr>
+                <td colspan="3">{{ 'No data available'|trans }}</td>
+            </tr>
+        {% endfor %}
+        <!-- end of repeating item -->
+    </table>
+{% endblock %}
diff --git a/tests/src/Entities/Bases/AbstractProviderTest.php b/tests/src/Entities/Bases/AbstractProviderTest.php
index 5eac3d84f2b596d24eed02675c18d46016f745ea..e8d8a2743b4492f6242c9ae8aa5b162bc8cead90 100644
--- a/tests/src/Entities/Bases/AbstractProviderTest.php
+++ b/tests/src/Entities/Bases/AbstractProviderTest.php
@@ -6,6 +6,7 @@ namespace SimpleSAML\Test\Module\accounting\Entities\Bases;
 
 use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider;
 use PHPUnit\Framework\TestCase;
+use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
 use SimpleSAML\Module\accounting\Entities\Providers\Identity\Saml2;
 
 /**
@@ -96,6 +97,21 @@ class AbstractProviderTest extends TestCase
             {
                 return (string)($this->metadata['entityid'] ?? 'N/A');
             }
+
+            public function getProtocol(): AuthenticationProtocolInterface
+            {
+                return new class implements AuthenticationProtocolInterface {
+                    public function getDesignation(): string
+                    {
+                        return 'designation';
+                    }
+
+                    public function getId(): int
+                    {
+                        return 999;
+                    }
+                };
+            }
         };
     }
 }
diff --git a/tests/src/Helpers/RandomTest.php b/tests/src/Helpers/RandomTest.php
index 3031c219b855e9dd098cc1d664deac2384705bb2..29fa51e895c02c3a17435abc33c2ef3060d5951c 100644
--- a/tests/src/Helpers/RandomTest.php
+++ b/tests/src/Helpers/RandomTest.php
@@ -14,6 +14,6 @@ class RandomTest extends TestCase
 {
     public function testCanGetRandomInt(): void
     {
-        $this->assertIsInt((new Random())->getRandomInt());
+        $this->assertIsInt((new Random())->getInt());
     }
 }
diff --git a/tests/src/Helpers/ModuleRoutesTest.php b/tests/src/Helpers/RoutesTest.php
similarity index 82%
rename from tests/src/Helpers/ModuleRoutesTest.php
rename to tests/src/Helpers/RoutesTest.php
index 15fd5609393e8af7d8f33e28bcd6bdb3d5339540..b649a1458867d538d1e2af76888772ed6031569e 100644
--- a/tests/src/Helpers/ModuleRoutesTest.php
+++ b/tests/src/Helpers/RoutesTest.php
@@ -7,15 +7,15 @@ namespace SimpleSAML\Test\Module\accounting\Helpers;
 use PHPUnit\Framework\MockObject\Stub;
 use SimpleSAML\Error\CriticalConfigurationError;
 use SimpleSAML\Module\accounting\Exceptions\InvalidConfigurationException;
-use SimpleSAML\Module\accounting\Helpers\ModuleRoutes;
+use SimpleSAML\Module\accounting\Helpers\Routes;
 use PHPUnit\Framework\TestCase;
 use SimpleSAML\Module\accounting\ModuleConfiguration;
 use SimpleSAML\Utils\HTTP;
 
 /**
- * @covers \SimpleSAML\Module\accounting\Helpers\ModuleRoutes
+ * @covers \SimpleSAML\Module\accounting\Helpers\Routes
  */
-class ModuleRoutesTest extends TestCase
+class RoutesTest extends TestCase
 {
     protected const BASE_URL = 'https://example.org/ssp/';
     /**
@@ -37,7 +37,7 @@ class ModuleRoutesTest extends TestCase
         $path = 'sample-path';
         $moduleUrlWithPath = $this->moduleUrl . '/' . $path;
 
-        $moduleRoutesHelper = new ModuleRoutes($this->sspHttpUtilsStub);
+        $moduleRoutesHelper = new Routes($this->sspHttpUtilsStub);
 
         $this->assertSame($moduleUrlWithPath, $moduleRoutesHelper->getUrl($path));
     }
@@ -49,7 +49,7 @@ class ModuleRoutesTest extends TestCase
         $fullUrl = 'full-url-with-sample-param';
 
         $this->sspHttpUtilsStub->method('addURLParameters')->willReturn($fullUrl);
-        $moduleRoutesHelper = new ModuleRoutes($this->sspHttpUtilsStub);
+        $moduleRoutesHelper = new Routes($this->sspHttpUtilsStub);
 
         $this->assertSame($fullUrl, $moduleRoutesHelper->getUrl($path, $params));
     }
diff --git a/tests/src/Services/HelpersManagerTest.php b/tests/src/Services/HelpersManagerTest.php
index 0d82af94c48085979a4dd8d1a4cb313df81406d1..aad618084fdde23b22033c93d8930b73a1f8a8e8 100644
--- a/tests/src/Services/HelpersManagerTest.php
+++ b/tests/src/Services/HelpersManagerTest.php
@@ -12,7 +12,7 @@ use SimpleSAML\Module\accounting\Helpers\Environment;
 use SimpleSAML\Module\accounting\Helpers\Filesystem;
 use SimpleSAML\Module\accounting\Helpers\Hash;
 use SimpleSAML\Module\accounting\Helpers\InstanceBuilderUsingModuleConfiguration;
-use SimpleSAML\Module\accounting\Helpers\ModuleRoutes;
+use SimpleSAML\Module\accounting\Helpers\Routes;
 use SimpleSAML\Module\accounting\Helpers\Network;
 use SimpleSAML\Module\accounting\Helpers\ProviderResolver;
 use SimpleSAML\Module\accounting\Helpers\Random;
@@ -21,7 +21,7 @@ use PHPUnit\Framework\TestCase;
 
 /**
  * @covers \SimpleSAML\Module\accounting\Services\HelpersManager
- * @uses \SimpleSAML\Module\accounting\Helpers\ModuleRoutes
+ * @uses \SimpleSAML\Module\accounting\Helpers\Routes
  * @uses \SimpleSAML\Module\accounting\Helpers\Hash
  */
 class HelpersManagerTest extends TestCase
@@ -42,7 +42,7 @@ class HelpersManagerTest extends TestCase
         );
         $this->assertInstanceOf(Network::class, $helpersManager->getNetwork());
         $this->assertInstanceOf(Random::class, $helpersManager->getRandom());
-        $this->assertInstanceOf(ModuleRoutes::class, $helpersManager->getModuleRoutes());
+        $this->assertInstanceOf(Routes::class, $helpersManager->getRoutes());
         $this->assertInstanceOf(
             AuthenticationEventStateResolver::class,
             $helpersManager->getAuthenticationEventStateResolver()
diff --git a/tests/src/Services/JobRunnerTest.php b/tests/src/Services/JobRunnerTest.php
index 15b57fe144b1a42d0cba4541fe49231cae035773..5c748b25b80ce2b3ce06d6c279e8e94c99219624 100644
--- a/tests/src/Services/JobRunnerTest.php
+++ b/tests/src/Services/JobRunnerTest.php
@@ -123,7 +123,7 @@ class JobRunnerTest extends TestCase
      */
     public function testCanCreateInstance(): void
     {
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->assertInstanceOf(
@@ -148,7 +148,7 @@ class JobRunnerTest extends TestCase
      */
     public function testPreRunValidationFailsForSameJobRunnerId(): void
     {
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(123);
@@ -185,7 +185,7 @@ class JobRunnerTest extends TestCase
      */
     public function testPreRunValidationFailsForStaleState(): void
     {
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(321);
@@ -222,7 +222,7 @@ class JobRunnerTest extends TestCase
      */
     public function testPreRunValidationPassesWhenStateIsNull(): void
     {
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->cacheMock->method('get')->willReturn(null);
@@ -258,7 +258,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(321);
@@ -296,7 +296,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(321);
@@ -336,7 +336,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(321);
@@ -372,7 +372,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(321);
@@ -417,7 +417,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getJobRunnerMaximumExecutionTime')
             ->willReturn(new DateInterval('PT1S'));
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->cacheMock->method('get')->willReturn(null);
@@ -459,7 +459,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getJobRunnerMaximumExecutionTime')
             ->willReturn(new DateInterval('PT20S'));
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
         $this->environmentHelperStub->method('isCli')->willReturn(false);
         $this->helpersManagerStub->method('getEnvironment')->willReturn($this->environmentHelperStub);
@@ -505,7 +505,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->cacheMock->method('get')->willReturn(null);
@@ -544,7 +544,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->cacheMock->method('get')->willReturnOnConsecutiveCalls(
@@ -585,7 +585,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->cacheMock->method('get')->willReturnOnConsecutiveCalls(
@@ -626,7 +626,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(321);
@@ -669,7 +669,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(123);
@@ -713,7 +713,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
 
         $this->stateStub->method('getJobRunnerId')->willReturn(123);
@@ -758,7 +758,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
         $this->environmentHelperStub->method('isCli')->willReturn(true);
         $this->helpersManagerStub->method('getEnvironment')->willReturn($this->environmentHelperStub);
@@ -813,7 +813,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getAccountingProcessingType')
             ->willReturn(ModuleConfiguration\AccountingProcessingType::VALUE_ASYNCHRONOUS);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
         $this->environmentHelperStub->method('isCli')->willReturn(false);
         $this->helpersManagerStub->method('getEnvironment')->willReturn($this->environmentHelperStub);
@@ -867,7 +867,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getDefaultDataTrackerAndProviderClass')
             ->willReturn('mock');
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
         $this->environmentHelperStub->method('isCli')->willReturn(false);
         $this->helpersManagerStub->method('getEnvironment')->willReturn($this->environmentHelperStub);
@@ -934,7 +934,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getDefaultDataTrackerAndProviderClass')
             ->willReturn('mock');
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
         $this->environmentHelperStub->method('isCli')->willReturn(false);
         $this->helpersManagerStub->method('getEnvironment')->willReturn($this->environmentHelperStub);
@@ -998,7 +998,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getJobRunnerShouldPauseAfterNumberOfJobsProcessed')
             ->willReturn(0);
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
         $this->environmentHelperStub->method('isCli')->willReturn(false);
         $this->helpersManagerStub->method('getEnvironment')->willReturn($this->environmentHelperStub);
@@ -1069,7 +1069,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getDefaultDataTrackerAndProviderClass')
             ->willReturn('mock');
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
         $this->environmentHelperStub->method('isCli')->willReturn(false);
         $this->helpersManagerStub->method('getEnvironment')->willReturn($this->environmentHelperStub);
@@ -1135,7 +1135,7 @@ class JobRunnerTest extends TestCase
         $this->moduleConfigurationStub->method('getDefaultDataTrackerAndProviderClass')
             ->willReturn('mock');
 
-        $this->randomHelperStub->method('getRandomInt')->willReturn(123);
+        $this->randomHelperStub->method('getInt')->willReturn(123);
         $this->helpersManagerStub->method('getRandom')->willReturn($this->randomHelperStub);
         $this->environmentHelperStub->method('isCli')->willReturn(false);
         $this->helpersManagerStub->method('getEnvironment')->willReturn($this->environmentHelperStub);