diff --git a/app/User/MultiFactorAuth.php b/app/User/MultiFactorAuth.php index 94303fd40..dadc25f21 100644 --- a/app/User/MultiFactorAuth.php +++ b/app/User/MultiFactorAuth.php @@ -18,12 +18,19 @@ use Endroid\QrCode\QrCode; use Endroid\QrCode\RoundBlockSizeMode; use Endroid\QrCode\Writer\PngWriter; use Endroid\QrCode\Writer\Result\ResultInterface; +use RobThree\Auth\Providers\Qr\EndroidQrCodeProvider; use RobThree\Auth\TwoFactorAuth; class MultiFactorAuth extends \Gazelle\BaseUser { protected const RECOVERY_KEY_LEN = 20; - private string|false $secret; + private string|false $secret; + private TwoFactorAuth $auth; + + public function __construct(\Gazelle\User $user) { + parent::__construct($user); + $this->auth = new TwoFactorAuth(new EndroidQrCodeProvider(), SITE_NAME); + } public function flush(): static { unset($this->secret); @@ -68,27 +75,27 @@ class MultiFactorAuth extends \Gazelle\BaseUser { } public function generateSessionSecret(): string { - return new TwoFactorAuth()->createSecret(); + return $this->auth->createSecret(); } public function generateQrCode(string $secret, string $logo): ResultInterface { $qrCode = new QrCode( - data: 'otpauth://totp/' . SITE_NAME . "?secret=$secret", - encoding: new Encoding('UTF-8'), + data: 'otpauth://totp/' . SITE_NAME . "?secret=$secret", + encoding: new Encoding('UTF-8'), errorCorrectionLevel: ErrorCorrectionLevel::Medium, - size: 400, - margin: 16, - roundBlockSizeMode: RoundBlockSizeMode::None, - backgroundColor: new Color(1, 8, 1), - foregroundColor: new Color(250, 250, 250) + size: 400, + margin: 16, + roundBlockSizeMode: RoundBlockSizeMode::None, + backgroundColor: new Color(1, 8, 1), + foregroundColor: new Color(250, 250, 250), ); $logo = new Logo( - path: $logo, - resizeToWidth: 96, + path: $logo, + resizeToWidth: 96, punchoutBackground: false, ); $label = new Label( - text: SITE_NAME, + text: SITE_NAME, textColor: new Color(0, 192, 0), ); $writer = new PngWriter(); @@ -144,11 +151,11 @@ class MultiFactorAuth extends \Gazelle\BaseUser { } public function verifyCode(string $truth, string $code): bool { - return new TwoFactorAuth()->verifyCode($truth, $code, 2); + return $this->auth->verifyCode($truth, $code, 2); } public function verify(string $token): bool { - if (!new TwoFactorAuth()->verifyCode($this->secret() ?: '', $token, 2)) { + if (!$this->auth->verifyCode($this->secret() ?: '', $token, 2)) { // They have MFA but the device key did not match // Fallback to considering it as a recovery key. if (strlen($token) === self::RECOVERY_KEY_LEN) { diff --git a/composer.json b/composer.json index 1825a4086..48f4e4856 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "orpheusnet/logchecker": "^0.14.4", "protonlabs/bitcoin": "^1.0", "robmorgan/phinx": "^0.16", - "robthree/twofactorauth": "^1.8.2", + "robthree/twofactorauth": "^3.0", "sad_spirit/pg_wrapper": "^3", "twig/twig": "^3.28", "whichbrowser/parser": "^2.1.8" diff --git a/composer.lock b/composer.lock index a1d6719ef..7fd547247 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": "393d799d614eef74d5d80b45aa655506", + "content-hash": "12dccd98071efb843b89114c3275f0c0", "packages": [ { "name": "bacon/bacon-qr-code", @@ -1213,7 +1213,7 @@ "issues": "https://github.com/monero-integrations/monerophp/issues", "source": "https://github.com/monero-integrations/monerophp/tree/master" }, - "time": "2024-01-20T09:09:40+00:00" + "time": "2026-08-24T09:46:02+00:00" }, { "name": "orpheusnet/bencode-torrent", @@ -1872,24 +1872,25 @@ }, { "name": "robthree/twofactorauth", - "version": "1.8.2", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/RobThree/TwoFactorAuth.git", - "reference": "65681de5a324eae05140ac58b08648a60212afc0" + "reference": "85408c4e775dba7c0802f2d928efd921d530bc5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/RobThree/TwoFactorAuth/zipball/65681de5a324eae05140ac58b08648a60212afc0", - "reference": "65681de5a324eae05140ac58b08648a60212afc0", + "url": "https://api.github.com/repos/RobThree/TwoFactorAuth/zipball/85408c4e775dba7c0802f2d928efd921d530bc5b", + "reference": "85408c4e775dba7c0802f2d928efd921d530bc5b", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": ">=8.2.0" }, "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpunit/phpunit": "@stable" + "friendsofphp/php-cs-fixer": "^3.13", + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^9" }, "suggest": { "bacon/bacon-qr-code": "Needed for BaconQrCodeProvider provider", @@ -1910,6 +1911,16 @@ "name": "Rob Janssen", "homepage": "http://robiii.me", "role": "Developer" + }, + { + "name": "Nicolas CARPi", + "homepage": "https://github.com/NicolasCARPi", + "role": "Developer" + }, + { + "name": "Will Power", + "homepage": "https://github.com/willpower232", + "role": "Developer" } ], "description": "Two Factor Authentication", @@ -1938,7 +1949,7 @@ "type": "github" } ], - "time": "2022-03-22T16:11:07+00:00" + "time": "2026-01-05T13:17:41+00:00" }, { "name": "sad_spirit/pg_wrapper", @@ -2087,16 +2098,16 @@ }, { "name": "symfony/config", - "version": "v7.4.16", + "version": "v7.4.17", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "e896f5e874e6983d0a098f554ca82a08a924c298" + "reference": "696e12da8eea497a1a3808d714b43ff67a7df43e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/e896f5e874e6983d0a098f554ca82a08a924c298", - "reference": "e896f5e874e6983d0a098f554ca82a08a924c298", + "url": "https://api.github.com/repos/symfony/config/zipball/696e12da8eea497a1a3808d714b43ff67a7df43e", + "reference": "696e12da8eea497a1a3808d714b43ff67a7df43e", "shasum": "" }, "require": { @@ -2142,7 +2153,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/v7.4.16" + "source": "https://github.com/symfony/config/tree/v7.4.17" }, "funding": [ { @@ -2162,20 +2173,20 @@ "type": "tidelift" } ], - "time": "2026-07-30T15:04:16+00:00" + "time": "2026-08-20T09:55:18+00:00" }, { "name": "symfony/console", - "version": "v7.4.16", + "version": "v7.4.17", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f4c69c9aed03abf933b294257d618bdd9b30a06d" + "reference": "962e18f09ebe68a49039b4c82fc0ea4871824fca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f4c69c9aed03abf933b294257d618bdd9b30a06d", - "reference": "f4c69c9aed03abf933b294257d618bdd9b30a06d", + "url": "https://api.github.com/repos/symfony/console/zipball/962e18f09ebe68a49039b4c82fc0ea4871824fca", + "reference": "962e18f09ebe68a49039b4c82fc0ea4871824fca", "shasum": "" }, "require": { @@ -2240,7 +2251,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.16" + "source": "https://github.com/symfony/console/tree/v7.4.17" }, "funding": [ { @@ -2260,7 +2271,7 @@ "type": "tidelift" } ], - "time": "2026-07-31T12:37:14+00:00" + "time": "2026-08-21T12:09:28+00:00" }, { "name": "symfony/deprecation-contracts", @@ -2335,16 +2346,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.4.15", + "version": "v7.4.17", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "ff16a16bf87fdf264638b8f6995b3515975e3c79" + "reference": "ee7bc7bca4c7079b88e57d5000aeeb20df570c8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/ff16a16bf87fdf264638b8f6995b3515975e3c79", - "reference": "ff16a16bf87fdf264638b8f6995b3515975e3c79", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ee7bc7bca4c7079b88e57d5000aeeb20df570c8d", + "reference": "ee7bc7bca4c7079b88e57d5000aeeb20df570c8d", "shasum": "" }, "require": { @@ -2381,7 +2392,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.4.15" + "source": "https://github.com/symfony/filesystem/tree/v7.4.17" }, "funding": [ { @@ -2401,7 +2412,7 @@ "type": "tidelift" } ], - "time": "2026-07-22T07:36:05+00:00" + "time": "2026-08-21T12:09:28+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2570,16 +2581,16 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.38.0", + "version": "v1.42.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b" + "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b", - "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/aa20edea75bd9c48cfecc8360922e5a6e5c44502", + "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502", "shasum": "" }, "require": { @@ -2631,7 +2642,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.42.0" }, "funding": [ { @@ -2651,7 +2662,7 @@ "type": "tidelift" } ], - "time": "2026-05-25T13:48:31+00:00" + "time": "2026-08-07T06:33:24+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -2740,16 +2751,16 @@ }, { "name": "symfony/process", - "version": "v7.4.13", + "version": "v7.4.17", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "f5804be144caceb570f6747519999636b664f24c" + "reference": "058d17fc284cce14efb2385783b55014a461b176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/f5804be144caceb570f6747519999636b664f24c", - "reference": "f5804be144caceb570f6747519999636b664f24c", + "url": "https://api.github.com/repos/symfony/process/zipball/058d17fc284cce14efb2385783b55014a461b176", + "reference": "058d17fc284cce14efb2385783b55014a461b176", "shasum": "" }, "require": { @@ -2781,7 +2792,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.4.13" + "source": "https://github.com/symfony/process/tree/v7.4.17" }, "funding": [ { @@ -2801,7 +2812,7 @@ "type": "tidelift" } ], - "time": "2026-05-23T16:05:06+00:00" + "time": "2026-08-21T17:40:08+00:00" }, { "name": "symfony/service-contracts", @@ -2982,16 +2993,16 @@ }, { "name": "symfony/yaml", - "version": "v7.4.15", + "version": "v7.4.17", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e101850ded5d2c0d44bf32abb8996404afec2dec" + "reference": "0b040d7b66ceb10b7bb24c8e6656257932693a12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e101850ded5d2c0d44bf32abb8996404afec2dec", - "reference": "e101850ded5d2c0d44bf32abb8996404afec2dec", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0b040d7b66ceb10b7bb24c8e6656257932693a12", + "reference": "0b040d7b66ceb10b7bb24c8e6656257932693a12", "shasum": "" }, "require": { @@ -3034,7 +3045,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.4.15" + "source": "https://github.com/symfony/yaml/tree/v7.4.17" }, "funding": [ { @@ -3054,7 +3065,7 @@ "type": "tidelift" } ], - "time": "2026-07-21T15:13:06+00:00" + "time": "2026-08-21T12:09:28+00:00" }, { "name": "twig/twig", @@ -3203,16 +3214,16 @@ "packages-dev": [ { "name": "brianium/paratest", - "version": "v7.24.0", + "version": "v7.24.1", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "c63bfd148355e6aeb9e22697bae6c0fee2dfe96c" + "reference": "c29bc43a5cdd0124b7eff959064ae83ea902b49a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/c63bfd148355e6aeb9e22697bae6c0fee2dfe96c", - "reference": "c63bfd148355e6aeb9e22697bae6c0fee2dfe96c", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/c29bc43a5cdd0124b7eff959064ae83ea902b49a", + "reference": "c29bc43a5cdd0124b7eff959064ae83ea902b49a", "shasum": "" }, "require": { @@ -3223,10 +3234,10 @@ "fidry/cpu-core-counter": "^1.3.0", "jean85/pretty-package-versions": "^2.1.1", "php": "~8.4.0 || ~8.5.0", - "phpunit/php-code-coverage": "^14.3.0", + "phpunit/php-code-coverage": "^14.3.1", "phpunit/php-file-iterator": "^7", "phpunit/php-timer": "^9", - "phpunit/phpunit": "^13.3.0", + "phpunit/phpunit": "^13.3.1", "sebastian/environment": "^9.3.2", "symfony/console": "^7.4.8 || ^8.1.2", "symfony/process": "^7.4.8 || ^8.1.0" @@ -3280,7 +3291,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.24.0" + "source": "https://github.com/paratestphp/paratest/tree/v7.24.1" }, "funding": [ { @@ -3292,7 +3303,7 @@ "type": "paypal" } ], - "time": "2026-08-07T13:03:48+00:00" + "time": "2026-08-17T06:31:26+00:00" }, { "name": "composer/pcre", @@ -3988,11 +3999,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.2.8", + "version": "2.2.9", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e285254e60f33c21902efef4a926ca0987c06804", - "reference": "e285254e60f33c21902efef4a926ca0987c06804", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/13d6b4f347bad222da436580c8304fa6f83e6bd0", + "reference": "13d6b4f347bad222da436580c8304fa6f83e6bd0", "shasum": "" }, "require": { @@ -4048,7 +4059,7 @@ "type": "github" } ], - "time": "2026-08-04T22:21:45+00:00" + "time": "2026-08-22T07:38:16+00:00" }, { "name": "phpstan/phpstan-phpunit", @@ -4162,16 +4173,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "14.3.0", + "version": "14.3.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "060a5c93e81afb01e97dbe8930a5d0c9bd46e54e" + "reference": "6ce313bb110384148d1dc7695a99175f59529069" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/060a5c93e81afb01e97dbe8930a5d0c9bd46e54e", - "reference": "060a5c93e81afb01e97dbe8930a5d0c9bd46e54e", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6ce313bb110384148d1dc7695a99175f59529069", + "reference": "6ce313bb110384148d1dc7695a99175f59529069", "shasum": "" }, "require": { @@ -4190,7 +4201,7 @@ "theseer/tokenizer": "^2.0.1" }, "require-dev": { - "phpunit/phpunit": "^13.3" + "phpunit/phpunit": "^13.3.1" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -4228,7 +4239,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.3.0" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.3.1" }, "funding": [ { @@ -4248,27 +4259,27 @@ "type": "tidelift" } ], - "time": "2026-08-07T07:24:15+00:00" + "time": "2026-08-16T05:23:47+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "7.0.1", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "3ccaa29123548190af12fee7af078dcd7f3ddfab" + "reference": "9bb4e6c58b62c1e043be995c66abec7c97307aae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3ccaa29123548190af12fee7af078dcd7f3ddfab", - "reference": "3ccaa29123548190af12fee7af078dcd7f3ddfab", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/9bb4e6c58b62c1e043be995c66abec7c97307aae", + "reference": "9bb4e6c58b62c1e043be995c66abec7c97307aae", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.3.0" + "phpunit/phpunit": "^13.3.1" }, "type": "library", "extra": { @@ -4301,7 +4312,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/7.0.1" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/7.0.2" }, "funding": [ { @@ -4321,7 +4332,7 @@ "type": "tidelift" } ], - "time": "2026-08-10T06:43:12+00:00" + "time": "2026-08-25T14:47:43+00:00" }, { "name": "phpunit/php-invoker", @@ -4609,16 +4620,16 @@ }, { "name": "phpunit/phpunit", - "version": "13.3.1", + "version": "13.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "fc024931d6ad047404e9d86536735923fe63a06b" + "reference": "22104a5ceb8d642e6b30ab00211d53d88e2db368" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc024931d6ad047404e9d86536735923fe63a06b", - "reference": "fc024931d6ad047404e9d86536735923fe63a06b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/22104a5ceb8d642e6b30ab00211d53d88e2db368", + "reference": "22104a5ceb8d642e6b30ab00211d53d88e2db368", "shasum": "" }, "require": { @@ -4632,8 +4643,8 @@ "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.4.1", - "phpunit/php-code-coverage": "^14.3", - "phpunit/php-file-iterator": "^7.0.1", + "phpunit/php-code-coverage": "^14.3.1", + "phpunit/php-file-iterator": "^7.0.2", "phpunit/php-invoker": "^7.0.0", "phpunit/php-text-template": "^6.0.0", "phpunit/php-timer": "^9.0.0", @@ -4689,7 +4700,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/13.3.1" + "source": "https://github.com/sebastianbergmann/phpunit/tree/13.3.2" }, "funding": [ { @@ -4697,20 +4708,20 @@ "type": "other" } ], - "time": "2026-08-13T13:14:23+00:00" + "time": "2026-08-27T08:40:49+00:00" }, { "name": "rector/rector", - "version": "2.6.2", + "version": "2.6.4", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "03cd615cdd5648abb5f10ff3a684fdb976687190" + "reference": "6ff008471683591224951526247b7a2b86980ba9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/03cd615cdd5648abb5f10ff3a684fdb976687190", - "reference": "03cd615cdd5648abb5f10ff3a684fdb976687190", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/6ff008471683591224951526247b7a2b86980ba9", + "reference": "6ff008471683591224951526247b7a2b86980ba9", "shasum": "" }, "require": { @@ -4749,7 +4760,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/2.6.2" + "source": "https://github.com/rectorphp/rector/tree/2.6.4" }, "funding": [ { @@ -4757,7 +4768,7 @@ "type": "github" } ], - "time": "2026-08-12T06:23:05+00:00" + "time": "2026-08-27T09:20:34+00:00" }, { "name": "sebastian/cli-parser", @@ -4992,24 +5003,24 @@ }, { "name": "sebastian/diff", - "version": "9.0.0", + "version": "9.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226" + "reference": "a2df6626c1baf31d5a88674882a3072f151b5a26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a3fb6a298a265ff487a91bbea46e03cd01dbb226", - "reference": "a3fb6a298a265ff487a91bbea46e03cd01dbb226", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/a2df6626c1baf31d5a88674882a3072f151b5a26", + "reference": "a2df6626c1baf31d5a88674882a3072f151b5a26", "shasum": "" }, "require": { "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^13.2", - "symfony/process": "^7.4.13" + "phpunit/phpunit": "^13.3.1", + "symfony/process": "^7.4.17" }, "type": "library", "extra": { @@ -5047,7 +5058,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/9.0.0" + "source": "https://github.com/sebastianbergmann/diff/tree/9.0.1" }, "funding": [ { @@ -5067,7 +5078,7 @@ "type": "tidelift" } ], - "time": "2026-06-05T03:04:51+00:00" + "time": "2026-08-25T15:38:55+00:00" }, { "name": "sebastian/environment", @@ -6003,16 +6014,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v7.4.16", + "version": "v7.4.17", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "7f59a843c1fbcceafecdf6863d3e38ea6ecd5061" + "reference": "f318ac9da5aba0be2cf43ecdd562c05a33bc11c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7f59a843c1fbcceafecdf6863d3e38ea6ecd5061", - "reference": "7f59a843c1fbcceafecdf6863d3e38ea6ecd5061", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f318ac9da5aba0be2cf43ecdd562c05a33bc11c0", + "reference": "f318ac9da5aba0be2cf43ecdd562c05a33bc11c0", "shasum": "" }, "require": { @@ -6063,7 +6074,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/v7.4.16" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.17" }, "funding": [ { @@ -6083,20 +6094,20 @@ "type": "tidelift" } ], - "time": "2026-08-06T09:45:22+00:00" + "time": "2026-08-21T17:40:08+00:00" }, { "name": "symfony/polyfill-deepclone", - "version": "v1.40.0", + "version": "v1.42.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-deepclone.git", - "reference": "dca4ccba5f360070b574414dce4c1e7a559844fa" + "reference": "70ba0627efc68e97ea392843458a2dd9d6dbd156" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-deepclone/zipball/dca4ccba5f360070b574414dce4c1e7a559844fa", - "reference": "dca4ccba5f360070b574414dce4c1e7a559844fa", + "url": "https://api.github.com/repos/symfony/polyfill-deepclone/zipball/70ba0627efc68e97ea392843458a2dd9d6dbd156", + "reference": "70ba0627efc68e97ea392843458a2dd9d6dbd156", "shasum": "" }, "require": { @@ -6150,7 +6161,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-deepclone/tree/v1.40.0" + "source": "https://github.com/symfony/polyfill-deepclone/tree/v1.42.0" }, "funding": [ { @@ -6170,20 +6181,20 @@ "type": "tidelift" } ], - "time": "2026-06-12T07:27:17+00:00" + "time": "2026-08-07T06:33:24+00:00" }, { "name": "symfony/var-exporter", - "version": "v8.1.4", + "version": "v8.1.5", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "6efa89335ab6d336643a807fcc89ae4f8a7a17e9" + "reference": "b8f7dd85493e8372c7c81a1547caaaf86b9c16d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/6efa89335ab6d336643a807fcc89ae4f8a7a17e9", - "reference": "6efa89335ab6d336643a807fcc89ae4f8a7a17e9", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b8f7dd85493e8372c7c81a1547caaaf86b9c16d1", + "reference": "b8f7dd85493e8372c7c81a1547caaaf86b9c16d1", "shasum": "" }, "require": { @@ -6233,7 +6244,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v8.1.4" + "source": "https://github.com/symfony/var-exporter/tree/v8.1.5" }, "funding": [ { @@ -6253,7 +6264,7 @@ "type": "tidelift" } ], - "time": "2026-07-30T12:40:56+00:00" + "time": "2026-08-13T16:11:28+00:00" }, { "name": "theseer/tokenizer", diff --git a/tests/phpunit/UserMultiFactorAuthTest.php b/tests/phpunit/UserMultiFactorAuthTest.php index 6a4c6b426..325b6b050 100644 --- a/tests/phpunit/UserMultiFactorAuthTest.php +++ b/tests/phpunit/UserMultiFactorAuthTest.php @@ -4,6 +4,7 @@ namespace Gazelle; use PHPUnit\Framework\TestCase; use GazelleUnitTest\Helper; +use RobThree\Auth\Providers\Qr\EndroidQrCodeProvider; use RobThree\Auth\TwoFactorAuth; class UserMultiFactorAuthTest extends TestCase { @@ -70,8 +71,10 @@ class UserMultiFactorAuthTest extends TestCase { $this->assertTrue($mfa->verify($burn), 'utest-burn-verify-mfa'); $this->assertFalse($mfa->verify('invalid'), 'utest-verify-bad-mfa'); $this->assertTrue( - $mfa->verify(new TwoFactorAuth()->getCode($secret)), - 'utest-verify-good-mfa' + $mfa->verify( + new TwoFactorAuth(new EndroidQrCodeProvider(), SITE_NAME)->getCode($secret) + ), + 'utest-verify-good-mfa', ); $this->assertTrue($mfa->enabled(), 'utest-has-mfa-key');