diff --git a/assets/js/u2f_auth.js b/assets/js/u2f_auth.js deleted file mode 100644 index 9ab9a256..00000000 --- a/assets/js/u2f_auth.js +++ /dev/null @@ -1,134 +0,0 @@ -import u2fApi from 'u2f-api' - -'use strict' - -window.u2fauth = window.u2fauth || {} - -u2fauth.formId = 'u2fForm' -u2fauth.authCodeId = '_auth_code' -u2fauth.keynameId = 'u2fkeyname' -u2fauth.pressButtonId = 'u2fpressbutton' -u2fauth.errorId = 'u2fError' -u2fauth.timeout = 30 -u2fauth.errorTranslation = { - 1: 'Unknown Error', - 2: 'Bad Request', - 3: 'Client configuration not supported', - 4: 'Device already registered or ineligible', - 5: 'Timeout. Click to retry' -} - -u2fauth.ready = function (fn) { - if (document.readyState !== 'loading') { - fn() - } else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', fn) - } else { - document.attachEvent('onreadystatechange', function () { - if (document.readyState !== 'loading') { fn() } - }) - } -} - -u2fauth.authenticate = function () { - u2fauth.clearError() - u2fauth.showPressButton() - - var form = document.getElementById(u2fauth.formId) - var request = JSON.parse(form.dataset.request) - - u2fApi.isSupported() - .then(function (supported) { - if (supported) { - return u2fApi.sign(request, u2fauth.timeout) - .then(response => { - u2fauth.hidePressButton() - u2fauth.submit(form, response) - }) - } else { - alert('Browser not supported') - } - }) - .catch(data => { - u2fauth.hidePressButton() - u2fauth.showError(data.metaData.code, u2fauth.authenticate) - }) -} - -u2fauth.register = function () { - u2fauth.clearError() - u2fauth.hideKeyname() - u2fauth.showPressButton() - - var form = document.getElementById(u2fauth.formId) - var request = JSON.parse(form.dataset.request) - - u2fApi.isSupported() - .then(function (supported) { - if (supported) { - return u2fApi.register(request[0], request[1], u2fauth.timeout) - .then(response => { - u2fauth.hidePressButton() - u2fauth.submit(form, response) - }) - } else { - alert('Browser not supported') - } - }) - .catch(data => { - console.info(data) - u2fauth.hidePressButton() - u2fauth.showError(data.metaData.code, u2fauth.register) - }) -} - -u2fauth.submit = function (form, data) { - var codeField = document.getElementById(u2fauth.authCodeId) - codeField.value = JSON.stringify(data) - form.submit() -} - -u2fauth.hideKeyname = function () { - var keyname = document.getElementById(u2fauth.keynameId) - keyname.style.display = 'none' -} - -u2fauth.hidePressButton = function () { - var pressButton = document.getElementById(u2fauth.pressButtonId) - pressButton.style.display = 'none' -} - -u2fauth.showPressButton = function () { - var pressButton = document.getElementById(u2fauth.pressButtonId) - pressButton.style.display = 'block' -} - -u2fauth.clearError = function () { - var errorDisplay = document.getElementById(u2fauth.errorId) - errorDisplay.style.display = 'none' - errorDisplay.innerText = '' -} - -u2fauth.showError = function (error, callback) { - var errorDisplay = document.getElementById(u2fauth.errorId) - errorDisplay.style.display = 'block' - errorDisplay.innerText = u2fauth.errorTranslation[error] - errorDisplay.onclick = callback -} - -u2fauth.ready(function () { - const form = document.getElementById('u2fForm') - if (!form) { - return - } - const type = form.dataset.action - - if (type === 'auth') { - u2fauth.authenticate() - } else if (type === 'reg' && form.addEventListener) { - form.addEventListener('submit', function (event) { - event.preventDefault() - u2fauth.register() - }, false) - } -}) diff --git a/assets/js/webauthn_tfa.js b/assets/js/webauthn_tfa.js new file mode 100644 index 00000000..5c7c5c94 --- /dev/null +++ b/assets/js/webauthn_tfa.js @@ -0,0 +1,218 @@ +'use strict' + +class WebauthnTFA { + +// Decodes a Base64Url string + _base64UrlDecode = (input) => { + input = input + .replace(/-/g, '+') + .replace(/_/g, '/'); + + const pad = input.length % 4; + if (pad) { + if (pad === 1) { + throw new Error('InvalidLengthError: Input base64url string is the wrong length to determine padding'); + } + input += new Array(5-pad).join('='); + } + + return window.atob(input); + }; + + // Converts an array of bytes into a Base64Url string + _arrayToBase64String = (a) => btoa(String.fromCharCode(...a)); + + // Prepares the public key options object returned by the Webauthn Framework + _preparePublicKeyOptions = publicKey => { + //Convert challenge from Base64Url string to Uint8Array + publicKey.challenge = Uint8Array.from( + this._base64UrlDecode(publicKey.challenge), + c => c.charCodeAt(0) + ); + + //Convert the user ID from Base64 string to Uint8Array + if (publicKey.user !== undefined) { + publicKey.user = { + ...publicKey.user, + id: Uint8Array.from( + window.atob(publicKey.user.id), + c => c.charCodeAt(0) + ), + }; + } + + //If excludeCredentials is defined, we convert all IDs to Uint8Array + if (publicKey.excludeCredentials !== undefined) { + publicKey.excludeCredentials = publicKey.excludeCredentials.map( + data => { + return { + ...data, + id: Uint8Array.from( + this._base64UrlDecode(data.id), + c => c.charCodeAt(0) + ), + }; + } + ); + } + + if (publicKey.allowCredentials !== undefined) { + publicKey.allowCredentials = publicKey.allowCredentials.map( + data => { + return { + ...data, + id: Uint8Array.from( + this._base64UrlDecode(data.id), + c => c.charCodeAt(0) + ), + }; + } + ); + } + + return publicKey; + }; + +// Prepares the public key credentials object returned by the authenticator + _preparePublicKeyCredentials = data => { + const publicKeyCredential = { + id: data.id, + type: data.type, + rawId: this._arrayToBase64String(new Uint8Array(data.rawId)), + response: { + clientDataJSON: this._arrayToBase64String( + new Uint8Array(data.response.clientDataJSON) + ), + }, + }; + + if (data.response.attestationObject !== undefined) { + publicKeyCredential.response.attestationObject = this._arrayToBase64String( + new Uint8Array(data.response.attestationObject) + ); + } + + if (data.response.authenticatorData !== undefined) { + publicKeyCredential.response.authenticatorData = this._arrayToBase64String( + new Uint8Array(data.response.authenticatorData) + ); + } + + if (data.response.signature !== undefined) { + publicKeyCredential.response.signature = this._arrayToBase64String( + new Uint8Array(data.response.signature) + ); + } + + if (data.response.userHandle !== undefined) { + publicKeyCredential.response.userHandle = this._arrayToBase64String( + new Uint8Array(data.response.userHandle) + ); + } + + return publicKeyCredential; + }; + + + constructor() + { + const register_dom_ready = (fn) => { + if (document.readyState !== 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } + } + + register_dom_ready(() => { + this.registerForms(); + }); + } + + registerForms() + { + //Find all forms which have an data-webauthn-tfa-action attribute + const forms = document.querySelectorAll('form[data-webauthn-tfa-action]'); + + forms.forEach((form) => { + console.debug('Found webauthn TFA form with action: ' + form.getAttribute('data-webauthn-tfa-action'), form); + //Ensure that the form has webauthn data + + const dataString = form.getAttribute('data-webauthn-tfa-data') + const action = form.getAttribute('data-webauthn-tfa-action'); + + if (!dataString) { + console.error('Form does not have webauthn data, can not continue!', form); + return; + } + + //Convert dataString to the needed dataObject + const dataObject = JSON.parse(dataString); + const options = this._preparePublicKeyOptions(dataObject); + + + if(action === 'authenticate'){ + this.authenticate(form, {publicKey: options}); + } + + if(action === 'register'){ + //Register submit action, so we can do the registration on submit + form.addEventListener('submit', (e) => { + e.preventDefault(); + this.register(form, {publicKey: options}); + }); + } + + + + //Catch submit event and do webauthn stuff + + + }); + } + + /** + * Submit the form with the given result data + * @param form + * @param data + * @private + */ + _submit(form, data) + { + const resultField = document.getElementById('_auth_code'); + resultField.value = JSON.stringify(data) + form.submit(); + } + + authenticate(form, authData) + { + navigator.credentials.get(authData) + .then((credential) => { + //Convert our credential to a form which can be JSON encoded + let data = this._preparePublicKeyCredentials(credential); + + this._submit(form, data) + }) + .catch((error) => { + console.error("WebAuthn Authentication error: ", error); + alert("Error: " + error) + }); + } + + register(form, authData) + { + navigator.credentials.create(authData) + .then((credential) => { + //Convert our credential to a form which can be JSON encoded + let data = this._preparePublicKeyCredentials(credential); + + this._submit(form, data) + }) + .catch((error) => { + console.error("WebAuthn Registration error: ", error); + alert("Error: " + error) + }); + } +} + +window.webauthnTFA = new WebauthnTFA(); \ No newline at end of file diff --git a/composer.json b/composer.json index 484f367c..3955f213 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "ext-json": "*", "ext-mbstring": "*", "beberlei/doctrineextensions": "^1.2", - "brick/math": "^0.10.2", + "brick/math": "^0.8.15", "composer/package-versions-deprecated": "1.11.99.4", "doctrine/annotations": "^1.6", "doctrine/doctrine-bundle": "^2.0", @@ -70,7 +70,7 @@ "twig/intl-extra": "^3.0", "twig/markdown-extra": "^3.0", "webmozart/assert": "^1.4", - "r/u2f-two-factor-bundle": "dev-scheb/2fa-support" + "jbtronics/2fa-webauthn": "dev-master" }, "require-dev": { "dama/doctrine-test-bundle": "^7.0", @@ -147,6 +147,10 @@ { "type": "vcs", "url": "https://github.com/jbtronics/u2f-two-factor-bundle.git" + }, + { + "type": "path", + "url": "../2fa-webauthn" } ] } diff --git a/composer.lock b/composer.lock index 4a6cd7ef..cecdb5e6 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": "8993207c8622a9f3b421a65bbf4072a1", + "content-hash": "e94249960fe23d18a3977983c795266c", "packages": [ { "name": "beberlei/assert", @@ -132,26 +132,26 @@ }, { "name": "brick/math", - "version": "0.10.2", + "version": "0.8.17", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f" + "reference": "e6f8e7d04346a95be89580f8c2c22d6c3fa65556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/459f2781e1a08d52ee56b0b1444086e038561e3f", - "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f", + "url": "https://api.github.com/repos/brick/math/zipball/e6f8e7d04346a95be89580f8c2c22d6c3fa65556", + "reference": "e6f8e7d04346a95be89580f8c2c22d6c3fa65556", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.4 || ^8.0" + "php": "^7.1|^8.0" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^9.0", - "vimeo/psalm": "4.25.0" + "phpunit/phpunit": "^7.5.15|^8.5", + "vimeo/psalm": "^3.5" }, "type": "library", "autoload": { @@ -176,15 +176,15 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.10.2" + "source": "https://github.com/brick/math/tree/v0.8" }, "funding": [ { - "url": "https://github.com/BenMorel", - "type": "github" + "url": "https://tidelift.com/funding/github/packagist/brick/math", + "type": "tidelift" } ], - "time": "2022-08-10T22:54:19+00:00" + "time": "2020-08-18T23:41:20+00:00" }, { "name": "composer/ca-bundle", @@ -503,16 +503,16 @@ }, { "name": "doctrine/collections", - "version": "1.7.3", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "09dde3eb237756190f2de738d3c97cff10a8407b" + "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/09dde3eb237756190f2de738d3c97cff10a8407b", - "reference": "09dde3eb237756190f2de738d3c97cff10a8407b", + "url": "https://api.github.com/repos/doctrine/collections/zipball/2b44dd4cbca8b5744327de78bafef5945c7e7b5e", + "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e", "shasum": "" }, "require": { @@ -567,22 +567,22 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/1.7.3" + "source": "https://github.com/doctrine/collections/tree/1.8.0" }, - "time": "2022-09-01T19:34:23+00:00" + "time": "2022-09-01T20:12:10+00:00" }, { "name": "doctrine/common", - "version": "3.4.0", + "version": "3.4.2", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "e09556bbdf95b8420e649162b19ae9da2d1a80f3" + "reference": "609c3a7b6af49a7b4b13945ca2fdf4af801946af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/e09556bbdf95b8420e649162b19ae9da2d1a80f3", - "reference": "e09556bbdf95b8420e649162b19ae9da2d1a80f3", + "url": "https://api.github.com/repos/doctrine/common/zipball/609c3a7b6af49a7b4b13945ca2fdf4af801946af", + "reference": "609c3a7b6af49a7b4b13945ca2fdf4af801946af", "shasum": "" }, "require": { @@ -590,13 +590,13 @@ "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^9.0 || ^10.0", "doctrine/collections": "^1", "phpstan/phpstan": "^1.4.1", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.0", - "symfony/phpunit-bridge": "^4.0.5", + "symfony/phpunit-bridge": "^6.1", "vimeo/psalm": "^4.4" }, "type": "library", @@ -644,7 +644,7 @@ ], "support": { "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.0" + "source": "https://github.com/doctrine/common/tree/3.4.2" }, "funding": [ { @@ -660,7 +660,7 @@ "type": "tidelift" } ], - "time": "2022-08-23T19:46:56+00:00" + "time": "2022-09-28T14:20:50+00:00" }, { "name": "doctrine/dbal", @@ -1884,6 +1884,81 @@ }, "time": "2019-12-30T22:54:17+00:00" }, + { + "name": "fgrosse/phpasn1", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/fgrosse/PHPASN1.git", + "reference": "eef488991d53e58e60c9554b09b1201ca5ba9296" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/eef488991d53e58e60c9554b09b1201ca5ba9296", + "reference": "eef488991d53e58e60c9554b09b1201ca5ba9296", + "shasum": "" + }, + "require": { + "php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "~2.0", + "phpunit/phpunit": "^6.3 || ^7.0 || ^8.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.4.0" + }, + "time": "2021-12-11T12:41:06+00:00" + }, { "name": "florianv/exchanger", "version": "2.7.2", @@ -2350,6 +2425,45 @@ }, "time": "2022-04-01T11:58:30+00:00" }, + { + "name": "jbtronics/2fa-webauthn", + "version": "dev-master", + "dist": { + "type": "path", + "url": "../2fa-webauthn", + "reference": "6a004d54d5e3336291f383a57aaa449173971e5a" + }, + "require": { + "ext-json": "*", + "nyholm/psr7": "^1.5", + "php": "^7.4.0|^8.0", + "scheb/2fa-bundle": "^5.0.0|^6.0.0", + "symfony/framework-bundle": "^5.0|^6.0", + "symfony/psr-http-message-bridge": "^2.1", + "web-auth/webauthn-lib": "^3.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Jbtronics\\TFAWebauthn\\": "src/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Böhmer", + "email": "mail@jan-boehmer.de" + } + ], + "transport-options": { + "relative": true + } + }, { "name": "laminas/laminas-code", "version": "4.7.0", @@ -2640,6 +2754,176 @@ ], "time": "2022-03-02T17:24:08+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": "liip/imagine-bundle", "version": "2.8.0", @@ -2744,16 +3028,16 @@ }, { "name": "lorenzo/pinky", - "version": "1.0.6", + "version": "1.0.7", "source": { "type": "git", "url": "https://github.com/lorenzo/pinky.git", - "reference": "61de35ec6a17badea8b0922e65a979472c886d01" + "reference": "60afc9f8c2b8fb6a2f77050b485ce93143dd8dcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lorenzo/pinky/zipball/61de35ec6a17badea8b0922e65a979472c886d01", - "reference": "61de35ec6a17badea8b0922e65a979472c886d01", + "url": "https://api.github.com/repos/lorenzo/pinky/zipball/60afc9f8c2b8fb6a2f77050b485ce93143dd8dcf", + "reference": "60afc9f8c2b8fb6a2f77050b485ce93143dd8dcf", "shasum": "" }, "require": { @@ -2791,9 +3075,9 @@ ], "support": { "issues": "https://github.com/lorenzo/pinky/issues", - "source": "https://github.com/lorenzo/pinky/tree/1.0.6" + "source": "https://github.com/lorenzo/pinky/tree/1.0.7" }, - "time": "2022-03-17T12:11:56+00:00" + "time": "2022-10-02T12:15:42+00:00" }, { "name": "masterminds/html5", @@ -3456,56 +3740,6 @@ }, "time": "2022-06-14T06:56:20+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": "2020-10-15T08:29:30+00:00" - }, { "name": "phenx/php-font-lib", "version": "0.5.4", @@ -4686,70 +4920,181 @@ "time": "2017-10-23T01:57:42+00:00" }, { - "name": "r/u2f-two-factor-bundle", - "version": "dev-scheb/2fa-support", + "name": "ramsey/collection", + "version": "1.2.2", "source": { "type": "git", - "url": "https://github.com/jbtronics/u2f-two-factor-bundle.git", - "reference": "3ba2d95de56a8ded97c841bbfac159f4350dbfdf" + "url": "https://github.com/ramsey/collection.git", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jbtronics/u2f-two-factor-bundle/zipball/3ba2d95de56a8ded97c841bbfac159f4350dbfdf", - "reference": "3ba2d95de56a8ded97c841bbfac159f4350dbfdf", + "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a", "shasum": "" }, "require": { - "doctrine/collections": "^1.6", - "doctrine/common": "*", - "ext-json": "*", - "php": "^7.1.3|^8.0", - "scheb/2fa-bundle": "^5.0.0|^6.0.0", - "symfony/event-dispatcher-contracts": "^2.0", - "symfony/framework-bundle": "^5.0|^6.0", - "symfony/templating": "^5.0|^6.0", - "yubico/u2flib-server": "^1.0.0" - }, - "conflict": { - "godzillante/u2f-two-factor-bundle": "*", - "tubssz/u2f-two-factor-bundle": "*" + "php": "^7.3 || ^8", + "symfony/polyfill-php81": "^1.23" }, "require-dev": { - "phpstan/phpstan": "^1.8.2" + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fakerphp/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.8", + "mockery/mockery": "^1.3", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5 || ^9", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.4" }, - "type": "symfony-bundle", + "type": "library", "autoload": { "psr-4": { - "R\\U2FTwoFactorBundle\\": "" + "Ramsey\\Collection\\": "src/" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Nils Uliczka", - "email": "nils.uliczka@darookee.net" - }, - { - "name": "Francesco De Francesco", - "email": "francesco.defrancesco@gmail.com" + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" } ], - "description": "Use U2F-Keys as 2FA for Symfony2, using scheb/two-factor-bundle", - "homepage": "https://github.com/darookee/u2f-two-factor-bundle", + "description": "A PHP library for representing and manipulating collections.", "keywords": [ - "authentication", - "fido", - "symfony2", - "two-factor", - "two-step", - "yubikey" + "array", + "collection", + "hash", + "map", + "queue", + "set" ], "support": { - "source": "https://github.com/jbtronics/u2f-two-factor-bundle/tree/scheb/2fa-support" + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.2.2" }, - "time": "2022-08-13T22:31:11+00:00" + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2021-10-10T03:01:02+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.2.3", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "shasum": "" + }, + "require": { + "brick/math": "^0.8 || ^0.9", + "ext-json": "*", + "php": "^7.2 || ^8.0", + "ramsey/collection": "^1.0", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-php80": "^1.14" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "moontoast/math": "^1.1", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-mockery": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^8.5 || ^9", + "slevomat/coding-standard": "^7.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-ctype": "Enables faster processing of character classification using ctype functions.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + }, + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.2.3" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2021-09-25T23:10:38+00:00" }, { "name": "s9e/regexp-builder", @@ -5317,6 +5662,151 @@ }, "time": "2022-02-17T07:56:41+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": "spomky-labs/cbor-php", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/Spomky-Labs/cbor-php.git", + "reference": "28e2712cfc0b48fae661a48ffc6896d7abe83684" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/28e2712cfc0b48fae661a48ffc6896d7abe83684", + "reference": "28e2712cfc0b48fae661a48ffc6896d7abe83684", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.15|^0.9.0", + "ext-mbstring": "*", + "php": ">=7.3" + }, + "require-dev": { + "ekino/phpstan-banned-code": "^1.0", + "ext-json": "*", + "infection/infection": "^0.18|^0.25", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-beberlei-assert": "^1.0", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.12", + "roave/security-advisories": "dev-latest", + "symplify/easy-coding-standard": "^10.0" + }, + "suggest": { + "ext-bcmath": "GMP or BCMath extensions will drastically improve the library performance. BCMath extension needed to handle the Big Float and Decimal Fraction Tags", + "ext-gmp": "GMP or BCMath extensions will drastically improve the library performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "CBOR\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/Spomky-Labs/cbor-php/contributors" + } + ], + "description": "CBOR Encoder/Decoder for PHP", + "keywords": [ + "Concise Binary Object Representation", + "RFC7049", + "cbor" + ], + "support": { + "issues": "https://github.com/Spomky-Labs/cbor-php/issues", + "source": "https://github.com/Spomky-Labs/cbor-php/tree/v2.1.0" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2021-12-13T12:46:26+00:00" + }, { "name": "spomky-labs/otphp", "version": "v10.0.3", @@ -5420,16 +5910,16 @@ }, { "name": "symfony/asset", - "version": "v5.4.7", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "4affdca3da5f380caa27a338269b36ac288b3981" + "reference": "9aa867206711cb6fcca51ef127ba52a018170be9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/4affdca3da5f380caa27a338269b36ac288b3981", - "reference": "4affdca3da5f380caa27a338269b36ac288b3981", + "url": "https://api.github.com/repos/symfony/asset/zipball/9aa867206711cb6fcca51ef127ba52a018170be9", + "reference": "9aa867206711cb6fcca51ef127ba52a018170be9", "shasum": "" }, "require": { @@ -5474,7 +5964,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v5.4.7" + "source": "https://github.com/symfony/asset/tree/v5.4.13" }, "funding": [ { @@ -5490,20 +5980,20 @@ "type": "tidelift" } ], - "time": "2022-03-18T16:00:30+00:00" + "time": "2022-08-31T08:17:19+00:00" }, { "name": "symfony/cache", - "version": "v5.4.11", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "5a0fff46df349f0db3fe242263451fddf5277362" + "reference": "89bb6a0fe27205636d80e568ffaf9bbb52f691e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/5a0fff46df349f0db3fe242263451fddf5277362", - "reference": "5a0fff46df349f0db3fe242263451fddf5277362", + "url": "https://api.github.com/repos/symfony/cache/zipball/89bb6a0fe27205636d80e568ffaf9bbb52f691e3", + "reference": "89bb6a0fe27205636d80e568ffaf9bbb52f691e3", "shasum": "" }, "require": { @@ -5564,14 +6054,14 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides an extended PSR-6, PSR-16 (and tags) implementation", + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", "homepage": "https://symfony.com", "keywords": [ "caching", "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v5.4.11" + "source": "https://github.com/symfony/cache/tree/v5.4.13" }, "funding": [ { @@ -5587,7 +6077,7 @@ "type": "tidelift" } ], - "time": "2022-07-28T15:25:17+00:00" + "time": "2022-09-06T13:23:31+00:00" }, { "name": "symfony/cache-contracts", @@ -5749,16 +6239,16 @@ }, { "name": "symfony/console", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1" + "reference": "3f97f6c7b7e26848a90c0c0cfb91eeb2bb8618be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c072aa8f724c3af64e2c7a96b796a4863d24dba1", - "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1", + "url": "https://api.github.com/repos/symfony/console/zipball/3f97f6c7b7e26848a90c0c0cfb91eeb2bb8618be", + "reference": "3f97f6c7b7e26848a90c0c0cfb91eeb2bb8618be", "shasum": "" }, "require": { @@ -5828,7 +6318,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.12" + "source": "https://github.com/symfony/console/tree/v5.4.13" }, "funding": [ { @@ -5844,7 +6334,7 @@ "type": "tidelift" } ], - "time": "2022-08-17T13:18:05+00:00" + "time": "2022-08-26T13:50:20+00:00" }, { "name": "symfony/css-selector", @@ -5914,16 +6404,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v5.4.11", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "a8b9251016e9476db73e25fa836904bc0bf74c62" + "reference": "24cf522668845391c0542bc1de496366072a6d0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a8b9251016e9476db73e25fa836904bc0bf74c62", - "reference": "a8b9251016e9476db73e25fa836904bc0bf74c62", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/24cf522668845391c0542bc1de496366072a6d0e", + "reference": "24cf522668845391c0542bc1de496366072a6d0e", "shasum": "" }, "require": { @@ -5983,7 +6473,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.11" + "source": "https://github.com/symfony/dependency-injection/tree/v5.4.13" }, "funding": [ { @@ -5999,7 +6489,7 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2022-08-30T19:10:13+00:00" }, { "name": "symfony/deprecation-contracts", @@ -6070,16 +6560,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v5.4.11", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "e0250f61a450518dd5b0b7847ec63d26665241dd" + "reference": "6ac912989e0c31b178aa534eb9ed75f7fa485fae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/e0250f61a450518dd5b0b7847ec63d26665241dd", - "reference": "e0250f61a450518dd5b0b7847ec63d26665241dd", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/6ac912989e0c31b178aa534eb9ed75f7fa485fae", + "reference": "6ac912989e0c31b178aa534eb9ed75f7fa485fae", "shasum": "" }, "require": { @@ -6167,7 +6657,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v5.4.11" + "source": "https://github.com/symfony/doctrine-bridge/tree/v5.4.13" }, "funding": [ { @@ -6183,7 +6673,7 @@ "type": "tidelift" } ], - "time": "2022-07-28T14:12:24+00:00" + "time": "2022-09-06T13:23:31+00:00" }, { "name": "symfony/dotenv", @@ -6556,16 +7046,16 @@ }, { "name": "symfony/filesystem", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "2d67c1f9a1937406a9be3171b4b22250c0a11447" + "reference": "ac09569844a9109a5966b9438fc29113ce77cf51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/2d67c1f9a1937406a9be3171b4b22250c0a11447", - "reference": "2d67c1f9a1937406a9be3171b4b22250c0a11447", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51", + "reference": "ac09569844a9109a5966b9438fc29113ce77cf51", "shasum": "" }, "require": { @@ -6600,7 +7090,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.12" + "source": "https://github.com/symfony/filesystem/tree/v5.4.13" }, "funding": [ { @@ -6616,7 +7106,7 @@ "type": "tidelift" } ], - "time": "2022-08-02T13:48:16+00:00" + "time": "2022-09-21T19:53:16+00:00" }, { "name": "symfony/finder", @@ -6748,16 +7238,16 @@ }, { "name": "symfony/form", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "d8c5cc929f8dc7a58b710c9474dd7a0173006017" + "reference": "d9d661776636ce689bc879b66fb06c6a6895f1a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/d8c5cc929f8dc7a58b710c9474dd7a0173006017", - "reference": "d8c5cc929f8dc7a58b710c9474dd7a0173006017", + "url": "https://api.github.com/repos/symfony/form/zipball/d9d661776636ce689bc879b66fb06c6a6895f1a7", + "reference": "d9d661776636ce689bc879b66fb06c6a6895f1a7", "shasum": "" }, "require": { @@ -6831,7 +7321,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v5.4.12" + "source": "https://github.com/symfony/form/tree/v5.4.13" }, "funding": [ { @@ -6847,20 +7337,20 @@ "type": "tidelift" } ], - "time": "2022-08-05T13:13:10+00:00" + "time": "2022-09-28T15:33:58+00:00" }, { "name": "symfony/framework-bundle", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "49f8fe5d39b7513a3f26898788885dbe66b0d910" + "reference": "394866c2cb8bb189b9bd5ebd043b66f89c800363" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/49f8fe5d39b7513a3f26898788885dbe66b0d910", - "reference": "49f8fe5d39b7513a3f26898788885dbe66b0d910", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/394866c2cb8bb189b9bd5ebd043b66f89c800363", + "reference": "394866c2cb8bb189b9bd5ebd043b66f89c800363", "shasum": "" }, "require": { @@ -6982,7 +7472,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.12" + "source": "https://github.com/symfony/framework-bundle/tree/v5.4.13" }, "funding": [ { @@ -6998,20 +7488,20 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:10+00:00" + "time": "2022-09-29T08:12:55+00:00" }, { "name": "symfony/http-client", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "6a057be154824487fd5e6b65ab83899e0c5ac550" + "reference": "596fd752f00e0205d895cd6b184d135c27bb5d6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/6a057be154824487fd5e6b65ab83899e0c5ac550", - "reference": "6a057be154824487fd5e6b65ab83899e0c5ac550", + "url": "https://api.github.com/repos/symfony/http-client/zipball/596fd752f00e0205d895cd6b184d135c27bb5d6a", + "reference": "596fd752f00e0205d895cd6b184d135c27bb5d6a", "shasum": "" }, "require": { @@ -7069,7 +7559,7 @@ "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-client/tree/v5.4.12" + "source": "https://github.com/symfony/http-client/tree/v5.4.13" }, "funding": [ { @@ -7085,7 +7575,7 @@ "type": "tidelift" } ], - "time": "2022-08-02T15:52:22+00:00" + "time": "2022-09-08T18:41:21+00:00" }, { "name": "symfony/http-client-contracts", @@ -7167,16 +7657,16 @@ }, { "name": "symfony/http-foundation", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "f4bfe9611b113b15d98a43da68ec9b5a00d56791" + "reference": "54be067587a4f2b7fffb7a699f9481ec3daf9379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f4bfe9611b113b15d98a43da68ec9b5a00d56791", - "reference": "f4bfe9611b113b15d98a43da68ec9b5a00d56791", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/54be067587a4f2b7fffb7a699f9481ec3daf9379", + "reference": "54be067587a4f2b7fffb7a699f9481ec3daf9379", "shasum": "" }, "require": { @@ -7223,7 +7713,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.12" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.13" }, "funding": [ { @@ -7239,20 +7729,20 @@ "type": "tidelift" } ], - "time": "2022-08-19T07:33:17+00:00" + "time": "2022-09-17T07:31:22+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "37f660fa3bcd78fe4893ce23ebe934618ec099be" + "reference": "4f25330c216b7bb178603b2e25fb7a9325015507" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/37f660fa3bcd78fe4893ce23ebe934618ec099be", - "reference": "37f660fa3bcd78fe4893ce23ebe934618ec099be", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4f25330c216b7bb178603b2e25fb7a9325015507", + "reference": "4f25330c216b7bb178603b2e25fb7a9325015507", "shasum": "" }, "require": { @@ -7335,7 +7825,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.12" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.13" }, "funding": [ { @@ -7351,7 +7841,7 @@ "type": "tidelift" } ], - "time": "2022-08-26T14:40:40+00:00" + "time": "2022-09-30T07:40:28+00:00" }, { "name": "symfony/intl", @@ -7443,16 +7933,16 @@ }, { "name": "symfony/mailer", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "076043af11e58b20a68d2fd93f59cdbc6e8fdd00" + "reference": "63bf36a5150ac0bfed1c4d0a4e0b114a57b77e11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/076043af11e58b20a68d2fd93f59cdbc6e8fdd00", - "reference": "076043af11e58b20a68d2fd93f59cdbc6e8fdd00", + "url": "https://api.github.com/repos/symfony/mailer/zipball/63bf36a5150ac0bfed1c4d0a4e0b114a57b77e11", + "reference": "63bf36a5150ac0bfed1c4d0a4e0b114a57b77e11", "shasum": "" }, "require": { @@ -7499,7 +7989,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v5.4.12" + "source": "https://github.com/symfony/mailer/tree/v5.4.13" }, "funding": [ { @@ -7515,20 +8005,20 @@ "type": "tidelift" } ], - "time": "2022-08-03T05:17:26+00:00" + "time": "2022-08-29T06:47:07+00:00" }, { "name": "symfony/mime", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "03876e9c5a36f5b45e7d9a381edda5421eff8a90" + "reference": "bb2ccf759e2b967dcd11bdee5bdf30dddd2290bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/03876e9c5a36f5b45e7d9a381edda5421eff8a90", - "reference": "03876e9c5a36f5b45e7d9a381edda5421eff8a90", + "url": "https://api.github.com/repos/symfony/mime/zipball/bb2ccf759e2b967dcd11bdee5bdf30dddd2290bd", + "reference": "bb2ccf759e2b967dcd11bdee5bdf30dddd2290bd", "shasum": "" }, "require": { @@ -7582,7 +8072,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.12" + "source": "https://github.com/symfony/mime/tree/v5.4.13" }, "funding": [ { @@ -7598,7 +8088,7 @@ "type": "tidelift" } ], - "time": "2022-08-19T14:24:03+00:00" + "time": "2022-09-01T18:18:29+00:00" }, { "name": "symfony/monolog-bridge", @@ -9029,6 +9519,94 @@ ], "time": "2022-03-02T12:42:23+00:00" }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v2.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "d444f85dddf65c7e57c58d8e5b3a4dbb593b1840" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/d444f85dddf65c7e57c58d8e5b3a4dbb593b1840", + "reference": "d444f85dddf65c7e57c58d8e5b3a4dbb593b1840", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^4.4 || ^5.0 || ^6.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", + "symfony/config": "^4.4 || ^5.0 || ^6.0", + "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0", + "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.4@dev || ^6.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-main": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.3" + }, + "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": "2022-09-05T10:34:54+00:00" + }, { "name": "symfony/routing", "version": "v5.4.11", @@ -9300,16 +9878,16 @@ }, { "name": "symfony/security-core", - "version": "v5.4.11", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "25d14fa47f9efa084d3c23d0ae3b2624d2ad9e92" + "reference": "71bc477807d9afc9c904fd62b3b5d48f97308460" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/25d14fa47f9efa084d3c23d0ae3b2624d2ad9e92", - "reference": "25d14fa47f9efa084d3c23d0ae3b2624d2ad9e92", + "url": "https://api.github.com/repos/symfony/security-core/zipball/71bc477807d9afc9c904fd62b3b5d48f97308460", + "reference": "71bc477807d9afc9c904fd62b3b5d48f97308460", "shasum": "" }, "require": { @@ -9373,7 +9951,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v5.4.11" + "source": "https://github.com/symfony/security-core/tree/v5.4.13" }, "funding": [ { @@ -9389,7 +9967,7 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2022-09-17T07:31:22+00:00" }, { "name": "symfony/security-csrf", @@ -9465,16 +10043,16 @@ }, { "name": "symfony/security-guard", - "version": "v5.4.9", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/security-guard.git", - "reference": "64c83d25b5b23fa07e77c861d19e46ce7929a789" + "reference": "83f647fcdc17aa14908f0e02a302d3d9d0f63fbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-guard/zipball/64c83d25b5b23fa07e77c861d19e46ce7929a789", - "reference": "64c83d25b5b23fa07e77c861d19e46ce7929a789", + "url": "https://api.github.com/repos/symfony/security-guard/zipball/83f647fcdc17aa14908f0e02a302d3d9d0f63fbc", + "reference": "83f647fcdc17aa14908f0e02a302d3d9d0f63fbc", "shasum": "" }, "require": { @@ -9512,7 +10090,7 @@ "description": "Symfony Security Component - Guard", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-guard/tree/v5.4.9" + "source": "https://github.com/symfony/security-guard/tree/v5.4.13" }, "funding": [ { @@ -9528,20 +10106,20 @@ "type": "tidelift" } ], - "time": "2022-05-06T14:25:18+00:00" + "time": "2022-09-28T13:19:49+00:00" }, { "name": "symfony/security-http", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "3ca3eb2a866a4a5adaf0a952d2d7db7208da378b" + "reference": "64e9926b8ab8e4460e4dfdc53dc098fed2dad837" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/3ca3eb2a866a4a5adaf0a952d2d7db7208da378b", - "reference": "3ca3eb2a866a4a5adaf0a952d2d7db7208da378b", + "url": "https://api.github.com/repos/symfony/security-http/zipball/64e9926b8ab8e4460e4dfdc53dc098fed2dad837", + "reference": "64e9926b8ab8e4460e4dfdc53dc098fed2dad837", "shasum": "" }, "require": { @@ -9597,7 +10175,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v5.4.12" + "source": "https://github.com/symfony/security-http/tree/v5.4.13" }, "funding": [ { @@ -9613,20 +10191,20 @@ "type": "tidelift" } ], - "time": "2022-08-23T10:55:18+00:00" + "time": "2022-09-29T19:14:22+00:00" }, { "name": "symfony/serializer", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "776fa3010f62b97a7119757a66596a654cd244d4" + "reference": "f8c32e94c8656c17a7360d88d6d486bc8ce23b2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/776fa3010f62b97a7119757a66596a654cd244d4", - "reference": "776fa3010f62b97a7119757a66596a654cd244d4", + "url": "https://api.github.com/repos/symfony/serializer/zipball/f8c32e94c8656c17a7360d88d6d486bc8ce23b2d", + "reference": "f8c32e94c8656c17a7360d88d6d486bc8ce23b2d", "shasum": "" }, "require": { @@ -9700,7 +10278,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v5.4.12" + "source": "https://github.com/symfony/serializer/tree/v5.4.13" }, "funding": [ { @@ -9716,7 +10294,7 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:10+00:00" + "time": "2022-09-29T09:26:59+00:00" }, { "name": "symfony/service-contracts", @@ -9803,16 +10381,16 @@ }, { "name": "symfony/stopwatch", - "version": "v5.4.5", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "4d04b5c24f3c9a1a168a131f6cbe297155bc0d30" + "reference": "6df7a3effde34d81717bbef4591e5ffe32226d69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4d04b5c24f3c9a1a168a131f6cbe297155bc0d30", - "reference": "4d04b5c24f3c9a1a168a131f6cbe297155bc0d30", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6df7a3effde34d81717bbef4591e5ffe32226d69", + "reference": "6df7a3effde34d81717bbef4591e5ffe32226d69", "shasum": "" }, "require": { @@ -9845,7 +10423,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v5.4.5" + "source": "https://github.com/symfony/stopwatch/tree/v5.4.13" }, "funding": [ { @@ -9861,20 +10439,20 @@ "type": "tidelift" } ], - "time": "2022-02-18T16:06:09+00:00" + "time": "2022-09-28T13:19:49+00:00" }, { "name": "symfony/string", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058" + "reference": "2900c668a32138a34118740de3e4d5a701801f53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/2fc515e512d721bf31ea76bd02fe23ada4640058", - "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058", + "url": "https://api.github.com/repos/symfony/string/zipball/2900c668a32138a34118740de3e4d5a701801f53", + "reference": "2900c668a32138a34118740de3e4d5a701801f53", "shasum": "" }, "require": { @@ -9931,7 +10509,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.12" + "source": "https://github.com/symfony/string/tree/v5.4.13" }, "funding": [ { @@ -9947,75 +10525,7 @@ "type": "tidelift" } ], - "time": "2022-08-12T17:03:11+00:00" - }, - { - "name": "symfony/templating", - "version": "v5.4.11", - "source": { - "type": "git", - "url": "https://github.com/symfony/templating.git", - "reference": "3933eaad08c7f83672c53f635d7c3988252a658a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/templating/zipball/3933eaad08c7f83672c53f635d7c3988252a658a", - "reference": "3933eaad08c7f83672c53f635d7c3988252a658a", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" - }, - "require-dev": { - "psr/log": "^1|^2|^3" - }, - "suggest": { - "psr/log-implementation": "For using debug logging in loaders" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Templating\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides all the tools needed to build any kind of template system", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/templating/tree/v5.4.11" - }, - "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": "2022-06-27T16:58:25+00:00" + "time": "2022-09-01T01:52:16+00:00" }, { "name": "symfony/translation", @@ -10502,16 +11012,16 @@ }, { "name": "symfony/validator", - "version": "v5.4.12", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "38bc4d83d01b800f1fa5acaceb5ff77490b8f768" + "reference": "8fba40ed3c21054cb9a543ccecd4f3175b6a011b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/38bc4d83d01b800f1fa5acaceb5ff77490b8f768", - "reference": "38bc4d83d01b800f1fa5acaceb5ff77490b8f768", + "url": "https://api.github.com/repos/symfony/validator/zipball/8fba40ed3c21054cb9a543ccecd4f3175b6a011b", + "reference": "8fba40ed3c21054cb9a543ccecd4f3175b6a011b", "shasum": "" }, "require": { @@ -10595,7 +11105,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v5.4.12" + "source": "https://github.com/symfony/validator/tree/v5.4.13" }, "funding": [ { @@ -10611,20 +11121,20 @@ "type": "tidelift" } ], - "time": "2022-08-09T11:54:29+00:00" + "time": "2022-09-17T07:31:22+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.4.11", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "b8f306d7b8ef34fb3db3305be97ba8e088fb4861" + "reference": "2bf2ccab581bec363191672f0df40e0c85569e1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b8f306d7b8ef34fb3db3305be97ba8e088fb4861", - "reference": "b8f306d7b8ef34fb3db3305be97ba8e088fb4861", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2bf2ccab581bec363191672f0df40e0c85569e1c", + "reference": "2bf2ccab581bec363191672f0df40e0c85569e1c", "shasum": "" }, "require": { @@ -10684,7 +11194,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.11" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.13" }, "funding": [ { @@ -10700,7 +11210,7 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:00:38+00:00" + "time": "2022-09-06T13:23:31+00:00" }, { "name": "symfony/var-exporter", @@ -11804,16 +12314,16 @@ }, { "name": "twig/twig", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077" + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", - "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", "shasum": "" }, "require": { @@ -11864,7 +12374,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.2" + "source": "https://github.com/twigphp/Twig/tree/v3.4.3" }, "funding": [ { @@ -11876,7 +12386,7 @@ "type": "tidelift" } ], - "time": "2022-08-12T06:47:24+00:00" + "time": "2022-09-28T08:42:51+00:00" }, { "name": "ua-parser/uap-php", @@ -11941,6 +12451,220 @@ }, "time": "2020-10-02T23:36:20+00:00" }, + { + "name": "web-auth/cose-lib", + "version": "v3.3.12", + "source": { + "type": "git", + "url": "https://github.com/web-auth/cose-lib.git", + "reference": "efa6ec2ba4e840bc1316a493973c9916028afeeb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/efa6ec2ba4e840bc1316a493973c9916028afeeb", + "reference": "efa6ec2ba4e840bc1316a493973c9916028afeeb", + "shasum": "" + }, + "require": { + "beberlei/assert": "^3.2", + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "fgrosse/phpasn1": "^2.1", + "php": ">=7.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cose\\": "src/" + } + }, + "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-auth/cose/contributors" + } + ], + "description": "CBOR Object Signing and Encryption (COSE) For PHP", + "homepage": "https://github.com/web-auth", + "keywords": [ + "COSE", + "RFC8152" + ], + "support": { + "source": "https://github.com/web-auth/cose-lib/tree/v3.3.12" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2021-12-04T12:13:35+00:00" + }, + { + "name": "web-auth/metadata-service", + "version": "v3.3.12", + "source": { + "type": "git", + "url": "https://github.com/web-auth/webauthn-metadata-service.git", + "reference": "ef40d2b7b68c4964247d13fab52e2fa8dbd65246" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-auth/webauthn-metadata-service/zipball/ef40d2b7b68c4964247d13fab52e2fa8dbd65246", + "reference": "ef40d2b7b68c4964247d13fab52e2fa8dbd65246", + "shasum": "" + }, + "require": { + "beberlei/assert": "^3.2", + "ext-json": "*", + "league/uri": "^6.0", + "php": ">=7.2", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/log": "^1.1" + }, + "suggest": { + "web-token/jwt-key-mgmt": "Mandatory for fetching Metadata Statement from distant sources", + "web-token/jwt-signature-algorithm-ecdsa": "Mandatory for fetching Metadata Statement from distant sources" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webauthn\\MetadataService\\": "src/" + } + }, + "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-auth/metadata-service/contributors" + } + ], + "description": "Metadata Service for FIDO2/Webauthn", + "homepage": "https://github.com/web-auth", + "keywords": [ + "FIDO2", + "fido", + "webauthn" + ], + "support": { + "source": "https://github.com/web-auth/webauthn-metadata-service/tree/v3.3.12" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2021-11-21T11:14:31+00:00" + }, + { + "name": "web-auth/webauthn-lib", + "version": "v3.3.12", + "source": { + "type": "git", + "url": "https://github.com/web-auth/webauthn-lib.git", + "reference": "5ef9b21c8e9f8a817e524ac93290d08a9f065b33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/5ef9b21c8e9f8a817e524ac93290d08a9f065b33", + "reference": "5ef9b21c8e9f8a817e524ac93290d08a9f065b33", + "shasum": "" + }, + "require": { + "beberlei/assert": "^3.2", + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "fgrosse/phpasn1": "^2.1", + "php": ">=7.2", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "psr/log": "^1.1", + "ramsey/uuid": "^3.8|^4.0", + "spomky-labs/base64url": "^2.0", + "spomky-labs/cbor-php": "^1.0|^2.0", + "symfony/process": "^3.0|^4.0|^5.0", + "thecodingmachine/safe": "^1.1", + "web-auth/cose-lib": "self.version", + "web-auth/metadata-service": "self.version" + }, + "suggest": { + "psr/log-implementation": "Recommended to receive logs from the library", + "web-token/jwt-key-mgmt": "Mandatory for the AndroidSafetyNet Attestation Statement support", + "web-token/jwt-signature-algorithm-ecdsa": "Recommended for the AndroidSafetyNet Attestation Statement support", + "web-token/jwt-signature-algorithm-eddsa": "Recommended for the AndroidSafetyNet Attestation Statement support", + "web-token/jwt-signature-algorithm-rsa": "Mandatory for the AndroidSafetyNet Attestation Statement support" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webauthn\\": "src/" + } + }, + "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-auth/webauthn-library/contributors" + } + ], + "description": "FIDO2/Webauthn Support For PHP", + "homepage": "https://github.com/web-auth", + "keywords": [ + "FIDO2", + "fido", + "webauthn" + ], + "support": { + "source": "https://github.com/web-auth/webauthn-lib/tree/v3.3.12" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2022-02-18T07:13:44+00:00" + }, { "name": "webmozart/assert", "version": "1.11.0", @@ -11998,48 +12722,6 @@ "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, "time": "2022-06-03T18:03:27+00:00" - }, - { - "name": "yubico/u2flib-server", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/Yubico/php-u2flib-server.git", - "reference": "55d813acf68212ad2cadecde07551600d6971939" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Yubico/php-u2flib-server/zipball/55d813acf68212ad2cadecde07551600d6971939", - "reference": "55d813acf68212ad2cadecde07551600d6971939", - "shasum": "" - }, - "require": { - "ext-openssl": "*", - "paragonie/random_compat": ">= 1", - "php": ">=5.6" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "vimeo/psalm": "^0|^1|^2" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "description": "Library for U2F implementation", - "homepage": "https://developers.yubico.com/php-u2flib-server", - "support": { - "issues": "https://github.com/Yubico/php-u2flib-server/issues", - "source": "https://github.com/Yubico/php-u2flib-server/tree/1.0.2" - }, - "abandoned": true, - "time": "2018-09-07T08:16:44+00:00" } ], "packages-dev": [ @@ -13072,21 +13754,21 @@ }, { "name": "phpstan/phpstan-doctrine", - "version": "1.3.14", + "version": "1.3.15", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-doctrine.git", - "reference": "bfefffeee7ea770090c99934509f29ced1b29c3f" + "reference": "93fe8c18ee955009e2033efeb64284b4e4df66a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/bfefffeee7ea770090c99934509f29ced1b29c3f", - "reference": "bfefffeee7ea770090c99934509f29ced1b29c3f", + "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/93fe8c18ee955009e2033efeb64284b4e4df66a0", + "reference": "93fe8c18ee955009e2033efeb64284b4e4df66a0", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.8.3" + "phpstan/phpstan": "^1.8.6" }, "conflict": { "doctrine/collections": "<1.0", @@ -13135,9 +13817,9 @@ "description": "Doctrine extensions for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-doctrine/issues", - "source": "https://github.com/phpstan/phpstan-doctrine/tree/1.3.14" + "source": "https://github.com/phpstan/phpstan-doctrine/tree/1.3.15" }, - "time": "2022-09-21T13:08:55+00:00" + "time": "2022-09-29T20:11:01+00:00" }, { "name": "phpstan/phpstan-symfony", @@ -13281,12 +13963,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "50a6bc0d820c35aab4d7818208f5ec815dff1fe1" + "reference": "51ff2179e48fdb0d495649a9c0681f46de777f4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/50a6bc0d820c35aab4d7818208f5ec815dff1fe1", - "reference": "50a6bc0d820c35aab4d7818208f5ec815dff1fe1", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/51ff2179e48fdb0d495649a9c0681f46de777f4e", + "reference": "51ff2179e48fdb0d495649a9c0681f46de777f4e", "shasum": "" }, "conflict": { @@ -13307,6 +13989,7 @@ "appwrite/server-ce": "<0.11.1|>=0.12,<0.12.2", "area17/twill": "<1.2.5|>=2,<2.5.3", "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", + "awesome-support/awesome-support": "<=6.0.7", "aws/aws-sdk-php": ">=3,<3.2.1", "bagisto/bagisto": "<0.1.5", "barrelstrength/sprout-base-email": "<1.2.7", @@ -13332,7 +14015,7 @@ "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", "cartalyst/sentry": "<=2.1.6", "catfan/medoo": "<1.7.5", - "centreon/centreon": "<20.10.7", + "centreon/centreon": "<21.4.16|>=21.10,<21.10.8|>=22,<22.4.1", "cesnet/simplesamlphp-module-proxystatistics": "<3.1", "codeception/codeception": "<3.1.3|>=4,<4.1.22", "codeigniter/framework": "<=3.0.6", @@ -13367,7 +14050,7 @@ "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", "dolibarr/dolibarr": "<16|= 12.0.5|>= 3.3.beta1, < 13.0.2", - "dompdf/dompdf": "<2", + "dompdf/dompdf": "<2.0.1", "drupal/core": ">=7,<7.91|>=8,<9.3.19|>=9.4,<9.4.3", "drupal/drupal": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", "dweeves/magmi": "<=0.7.24", @@ -13400,7 +14083,7 @@ "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", "facturascripts/facturascripts": "<=2022.8", "feehi/cms": "<=2.1.1", - "feehi/feehicms": "<=0.1.3", + "feehi/feehicms": "<=2.0.1.1", "fenom/fenom": "<=2.12.1", "filegator/filegator": "<7.8", "firebase/php-jwt": "<2", @@ -13692,7 +14375,7 @@ "topthink/thinkphp": "<=3.2.3", "tribalsystems/zenario": "<9.2.55826", "truckersmp/phpwhois": "<=4.3.1", - "twig/twig": "<1.38|>=2,<2.14.11|>=3,<3.3.8", + "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3", "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.32|>=11,<11.5.16", "typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", "typo3/cms-core": ">=6.2,<=6.2.56|>=7,<7.6.58|>=8,<8.7.48|>=9,<9.5.37|>=10,<10.4.32|>=11,<11.5.16", @@ -13797,7 +14480,7 @@ "type": "tidelift" } ], - "time": "2022-09-23T21:04:15+00:00" + "time": "2022-10-01T16:04:26+00:00" }, { "name": "sebastian/diff", @@ -14267,16 +14950,16 @@ }, { "name": "symfony/web-profiler-bundle", - "version": "v5.4.10", + "version": "v5.4.13", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "f61c99d8dbd864b11935851b598f784bcff36fc7" + "reference": "6fefe0a7761a35b33c616e199c19f0c0d069e282" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/f61c99d8dbd864b11935851b598f784bcff36fc7", - "reference": "f61c99d8dbd864b11935851b598f784bcff36fc7", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/6fefe0a7761a35b33c616e199c19f0c0d069e282", + "reference": "6fefe0a7761a35b33c616e199c19f0c0d069e282", "shasum": "" }, "require": { @@ -14327,7 +15010,7 @@ "description": "Provides a development tool that gives detailed information about the execution of any request", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v5.4.10" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v5.4.13" }, "funding": [ { @@ -14343,20 +15026,20 @@ "type": "tidelift" } ], - "time": "2022-06-06T19:10:58+00:00" + "time": "2022-08-28T23:24:00+00:00" }, { "name": "symplify/easy-coding-standard", - "version": "11.1.9", + "version": "11.1.10", "source": { "type": "git", "url": "https://github.com/symplify/easy-coding-standard.git", - "reference": "65341819f0f518b5f424a57736e9b0e9c5a9202f" + "reference": "dc1c9c50059de9b0f51029a9446537f80bbf0c4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/65341819f0f518b5f424a57736e9b0e9c5a9202f", - "reference": "65341819f0f518b5f424a57736e9b0e9c5a9202f", + "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/dc1c9c50059de9b0f51029a9446537f80bbf0c4e", + "reference": "dc1c9c50059de9b0f51029a9446537f80bbf0c4e", "shasum": "" }, "require": { @@ -14386,7 +15069,7 @@ ], "description": "Prefixed scoped version of ECS package", "support": { - "source": "https://github.com/symplify/easy-coding-standard/tree/11.1.9" + "source": "https://github.com/symplify/easy-coding-standard/tree/11.1.10" }, "funding": [ { @@ -14398,7 +15081,7 @@ "type": "github" } ], - "time": "2022-09-02T10:10:26+00:00" + "time": "2022-09-29T10:40:41+00:00" }, { "name": "vimeo/psalm", @@ -14563,7 +15246,7 @@ "minimum-stability": "stable", "stability-flags": { "florianv/swap-bundle": 20, - "r/u2f-two-factor-bundle": 20, + "jbtronics/2fa-webauthn": 20, "roave/security-advisories": 20 }, "prefer-stable": false, diff --git a/config/bundles.php b/config/bundles.php index f08122e3..64f77e59 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -23,6 +23,6 @@ return [ Florianv\SwapBundle\FlorianvSwapBundle::class => ['all' => true], Nelmio\SecurityBundle\NelmioSecurityBundle::class => ['all' => true], Symfony\UX\Turbo\TurboBundle::class => ['all' => true], + Jbtronics\TFAWebauthn\TFAWebauthnBundle::class => ['all' => true], Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true], - R\U2FTwoFactorBundle\RU2FTwoFactorBundle::class => ['all' => true], ]; diff --git a/config/packages/r_u2f_two_factor.yaml b/config/packages/r_u2f_two_factor.yaml deleted file mode 100644 index d3b962b2..00000000 --- a/config/packages/r_u2f_two_factor.yaml +++ /dev/null @@ -1,4 +0,0 @@ -ru2_f_two_factor: - formTemplate: "/security/U2F/u2f_login.html.twig" - registerTemplate: "/security/U2F/u2f_register.html.twig" - authCodeParameter: _auth_code \ No newline at end of file diff --git a/config/packages/scheb_2fa.yaml b/config/packages/scheb_2fa.yaml index 9ba0ed41..f58bdacc 100644 --- a/config/packages/scheb_2fa.yaml +++ b/config/packages/scheb_2fa.yaml @@ -25,4 +25,4 @@ scheb_two_factor: # If you're using guard-based authentication, you have to use this one: # - Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken # If you're using authenticator-based security (introduced in Symfony 5.1), you have to use this one: - # - Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken + # - Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken \ No newline at end of file diff --git a/config/packages/webauthn_2fa.yaml b/config/packages/webauthn_2fa.yaml new file mode 100644 index 00000000..915e7d48 --- /dev/null +++ b/config/packages/webauthn_2fa.yaml @@ -0,0 +1,5 @@ +tfa_webauthn: + enabled: true + template: 'Security/Webauthn/webauthn_login.html.twig' + + rpName: '%partdb.title%' diff --git a/config/routes/scheb_2fa.yaml b/config/routes/scheb_2fa.yaml index c0b47b5e..21f90fca 100644 --- a/config/routes/scheb_2fa.yaml +++ b/config/routes/scheb_2fa.yaml @@ -4,8 +4,4 @@ _controller: "scheb_two_factor.form_controller::form" 2fa_login_check: - path: /{_locale}/2fa_check - -r_u2f_register: - resource: "@RU2FTwoFactorBundle/Resources/config/routing.yml" - prefix: /{_locale}/user \ No newline at end of file + path: /{_locale}/2fa_check \ No newline at end of file diff --git a/src/Controller/WebauthnKeyRegistrationController.php b/src/Controller/WebauthnKeyRegistrationController.php new file mode 100644 index 00000000..512f6658 --- /dev/null +++ b/src/Controller/WebauthnKeyRegistrationController.php @@ -0,0 +1,41 @@ +getMethod() === 'POST') { + $webauthnResponse = $request->request->get('_auth_code'); + + //Retrieve other data from the form, that you want to store with the key + $keyName = $request->request->get('keyName'); + + //Check the response + $new_key = $registrationHelper->checkRegistrationResponse($webauthnResponse); + + dump($new_key); + + $this->addFlash('success', 'Key registered successfully'); + } + + + return $this->render( + 'Security/U2F/u2f_register.html.twig', + [ + 'registrationRequest' => $registrationHelper->generateRegistrationRequestAsJSON(), + ] + ); + } +} \ No newline at end of file diff --git a/src/Entity/UserSystem/U2FKey.php b/src/Entity/UserSystem/U2FKey.php index d4e6aa05..3fbd2534 100644 --- a/src/Entity/UserSystem/U2FKey.php +++ b/src/Entity/UserSystem/U2FKey.php @@ -44,8 +44,7 @@ namespace App\Entity\UserSystem; use App\Entity\Base\TimestampTrait; use Doctrine\ORM\Mapping as ORM; -use R\U2FTwoFactorBundle\Model\U2F\TwoFactorKeyInterface; -use u2flib_server\Registration; +use Jbtronics\TFAWebauthn\Model\LegacyU2FKeyInterface; /** * @ORM\Entity @@ -56,7 +55,7 @@ use u2flib_server\Registration; * }) * @ORM\HasLifecycleCallbacks() */ -class U2FKey implements TwoFactorKeyInterface +class U2FKey implements LegacyU2FKeyInterface { use TimestampTrait; @@ -110,14 +109,6 @@ class U2FKey implements TwoFactorKeyInterface **/ protected ?User $user = null; - public function fromRegistrationData(Registration $data): void - { - $this->keyHandle = $data->keyHandle; - $this->publicKey = $data->publicKey; - $this->certificate = $data->certificate; - $this->counter = $data->counter; - } - public function getKeyHandle(): string { return $this->keyHandle; diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index 1ec48ca9..5c9c0de9 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -58,6 +58,7 @@ use App\Security\Interfaces\HasPermissionsInterface; use App\Validator\Constraints\Selectable; use App\Validator\Constraints\ValidPermission; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; +use Webauthn\PublicKeyCredentialUserEntity; use function count; use DateTime; use Doctrine\Common\Collections\ArrayCollection; @@ -65,8 +66,6 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Exception; use function in_array; -use R\U2FTwoFactorBundle\Model\U2F\TwoFactorInterface as U2FTwoFactorInterface; -use R\U2FTwoFactorBundle\Model\U2F\TwoFactorKeyInterface; use Scheb\TwoFactorBundle\Model\BackupCodeInterface; use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface; use Scheb\TwoFactorBundle\Model\PreferredProviderInterface; @@ -74,6 +73,7 @@ use Scheb\TwoFactorBundle\Model\TrustedDeviceInterface; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Validator\Constraints as Assert; +use Jbtronics\TFAWebauthn\Model\TwoFactorInterface as WebauthnTwoFactorInterface; /** * This entity represents a user, which can log in and have permissions. @@ -86,7 +86,7 @@ use Symfony\Component\Validator\Constraints as Assert; * @ORM\EntityListeners({"App\EntityListeners\TreeCacheInvalidationListener"}) * @UniqueEntity("name", message="validator.user.username_already_used") */ -class User extends AttachmentContainingDBElement implements UserInterface, HasPermissionsInterface, TwoFactorInterface, BackupCodeInterface, TrustedDeviceInterface, U2FTwoFactorInterface, PreferredProviderInterface, PasswordAuthenticatedUserInterface +class User extends AttachmentContainingDBElement implements UserInterface, HasPermissionsInterface, TwoFactorInterface, BackupCodeInterface, TrustedDeviceInterface, WebauthnTwoFactorInterface, PreferredProviderInterface, PasswordAuthenticatedUserInterface { //use MasterAttachmentTrait; @@ -838,48 +838,38 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe ++$this->trustedDeviceCookieVersion; } - /** - * Check if U2F is enabled. - */ - public function isU2FAuthEnabled(): bool - { - return count($this->u2fKeys) > 0; - } - - /** - * Get all U2F Keys that are associated with this user. - * - * @psalm-return Collection - */ - public function getU2FKeys(): Collection - { - return $this->u2fKeys; - } - - /** - * Add a U2F key to this user. - */ - public function addU2FKey(TwoFactorKeyInterface $key): void - { - $this->u2fKeys->add($key); - } - - /** - * Remove a U2F key from this user. - */ - public function removeU2FKey(TwoFactorKeyInterface $key): void - { - $this->u2fKeys->removeElement($key); - } - public function getPreferredTwoFactorProvider(): ?string { //If U2F is available then prefer it - if ($this->isU2FAuthEnabled()) { - return 'u2f_two_factor'; - } + //if ($this->isU2FAuthEnabled()) { + // return 'u2f_two_factor'; + //} //Otherwise use other methods return null; } + + public function isWebAuthnAuthenticatorEnabled(): bool + { + return count($this->u2fKeys) > 0; + } + + public function getLegacyU2FKeys(): iterable + { + return $this->u2fKeys; + } + + public function getWebAuthnUser(): PublicKeyCredentialUserEntity + { + return new PublicKeyCredentialUserEntity( + $this->getUsername(), + (string) $this->getId(), + $this->getFullName(), + ); + } + + public function getWebauthnKeys(): iterable + { + return []; + } } diff --git a/src/EventSubscriber/UserSystem/PasswordChangeNeededSubscriber.php b/src/EventSubscriber/UserSystem/PasswordChangeNeededSubscriber.php index 7bb6e667..d324009f 100644 --- a/src/EventSubscriber/UserSystem/PasswordChangeNeededSubscriber.php +++ b/src/EventSubscriber/UserSystem/PasswordChangeNeededSubscriber.php @@ -146,7 +146,7 @@ final class PasswordChangeNeededSubscriber implements EventSubscriberInterface */ public static function TFARedirectNeeded(User $user): bool { - $tfa_enabled = $user->isU2FAuthEnabled() || $user->isGoogleAuthenticatorEnabled(); + $tfa_enabled = $user->isWebAuthnAuthenticatorEnabled() || $user->isGoogleAuthenticatorEnabled(); return null !== $user->getGroup() && $user->getGroup()->isEnforce2FA() && !$tfa_enabled; } diff --git a/symfony.lock b/symfony.lock index 91b32038..d5ff4847 100644 --- a/symfony.lock +++ b/symfony.lock @@ -176,6 +176,9 @@ "imagine/imagine": { "version": "1.2.2" }, + "jbtronics/2fa-webauthn": { + "version": "dev-master" + }, "laminas/laminas-code": { "version": "3.4.1" }, @@ -252,9 +255,6 @@ "openlss/lib-array2xml": { "version": "1.0.0" }, - "paragonie/random_compat": { - "version": "v9.99.99" - }, "phenx/php-font-lib": { "version": "0.5.1" }, @@ -348,9 +348,6 @@ "psr/simple-cache": { "version": "1.0.1" }, - "r/u2f-two-factor-bundle": { - "version": "dev-scheb/2fa-support" - }, "roave/security-advisories": { "version": "dev-master" }, diff --git a/templates/base.html.twig b/templates/base.html.twig index 7a481114..7aa119df 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -52,7 +52,7 @@ {% block javascripts %} {{ encore_entry_script_tags('app') }} - {{ encore_entry_script_tags('ru2ftwofactor') }} + {{ encore_entry_script_tags('webauthn_tfa') }} {# load translation files for ckeditor #} {% set two_chars_locale = app.request.locale|default("en")|slice(0,2) %} diff --git a/templates/security/U2F/u2f_register.html.twig b/templates/security/Webauthn/u2f_register.html.twig similarity index 73% rename from templates/security/U2F/u2f_register.html.twig rename to templates/security/Webauthn/u2f_register.html.twig index c04931db..06650d31 100644 --- a/templates/security/U2F/u2f_register.html.twig +++ b/templates/security/Webauthn/u2f_register.html.twig @@ -10,13 +10,13 @@

{% trans %}tfa_u2f.http_warning{% endtrans %}

{% endif %} -
+
- +
- +
diff --git a/templates/security/U2F/u2f_login.html.twig b/templates/security/Webauthn/webauthn_login.html.twig similarity index 64% rename from templates/security/U2F/u2f_login.html.twig rename to templates/security/Webauthn/webauthn_login.html.twig index 63d2751b..f9bf6a55 100644 --- a/templates/security/U2F/u2f_login.html.twig +++ b/templates/security/Webauthn/webauthn_login.html.twig @@ -1,14 +1,12 @@ {% extends "security/2fa_base_form.html.twig" %} -{% block form_attributes %}id="u2fForm" data-action="auth" data-request='{{ authenticationData|raw }}'{% endblock %} +{% block form_attributes %} data-webauthn-tfa-action="authenticate" data-webauthn-tfa-data='{{ webauthn_request_data|raw }}'{% endblock %} {% block form %} {% if not app.request.secure %}

{% trans %}tfa_u2f.http_warning{% endtrans %}

{% endif %} - -

{% trans %}user.logout{% endtrans %} {% endblock %} diff --git a/webpack.config.js b/webpack.config.js index 484b4744..06e165be 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -59,7 +59,7 @@ Encore * and one CSS file (e.g. app.css) if you JavaScript imports CSS. */ .addEntry('app', './assets/js/app.js') - .addEntry('ru2ftwofactor', './assets/js/u2f_auth.js') + .addEntry('webauthn_tfa', './assets/js/webauthn_tfa.js') // enables the Symfony UX Stimulus bridge (used in assets/bootstrap.js) .enableStimulusBridge('./assets/controllers.json')