From 2673a5a8aebd71ac4279d1d48290abb86aa3f0c4 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Thu, 14 Jan 2021 18:40:53 -0600 Subject: [PATCH 1/9] Add readme example for displaying QR code --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3a9f72f..f4f17e9 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,23 @@ composer require paragonie/multi-factor ## Example Usage +### Display QR code + ```php makeQRCode(null, 'php://output', 'email@example.com', 'Issuer', 'Label'); +``` + +### Validate two-factor code + +```php + Date: Mon, 2 Jan 2023 15:15:36 -0600 Subject: [PATCH 2/9] Exclude test files from Composer package --- .gitattributes | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a96124c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +/test export-ignore +/phpunit.xml export-ignore +/psalm.xml export-ignore From 6d76e20e680119d0540cda8860ec4935a9a8f18a Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Mon, 2 Jan 2023 15:16:30 -0600 Subject: [PATCH 3/9] Exclude PhpStorm config folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 525642d..c5aa734 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.idea/ /vendor/ /composer.lock .phpunit.result.cache From a2b0b7119913d77c5abb3416985aee09ccc55cb4 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Mon, 2 Jan 2023 15:22:41 -0600 Subject: [PATCH 4/9] Add changelog --- CHANGELOG.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2cbcec9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,55 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [Unreleased] +### Added +- Support for PHP 8. +- `GoogleAuth::getQRCode()` and `GoogleAuth::makeQRCodeMessage()` methods. +- HiddenString support for secret key. +- `GoogleAuth->defaultQRCodeSize` property (replaces the removed width and height properties). + +### Changed +- PHP 7.2+ is now required. +- Renamed `FIDOU2F` class to `OneTime`. +- Updated [BaconQrCode](https://github.com/Bacon/BaconQrCode) dependency to v2. + This version has a slightly different API for rendering QR code images. +- Test files are now excluded from Composer package. + +### Removed +- `GoogleAuth->defaultQRCodeWidth` and `GoogleAuth->defaultQRCodeHeight` properties. + + +## [0.2.2] - 2016-06-17 +### Changed +- Appended HTTP query string in QR code. + + +## [0.2.1] - 2016-06-17 +### Changed +- `TOTP` and `HOTP` classes now implement `OTPInterface`. + + +## [0.2.0] - 2016-06-16 +### Added +- Support for HOTP and Google Authenticator. +- Range check to ensure that code length is between 1 and 10. + +### Changed +- Replaced giant switch statement with `**` operator. +- Improved readme. + + +## [0.1.0] - 2016-06-13 +- Initial pre-release + + +[Unreleased]: https://github.com/paragonie/multi_factor/compare/v0.2.2...HEAD +[0.2.2]: https://github.com/paragonie/multi_factor/compare/v0.2.1...v0.2.2 +[0.2.1]: https://github.com/paragonie/multi_factor/compare/v0.2.0...v0.2.1 +[0.2.0]: https://github.com/paragonie/multi_factor/compare/v0.1.0...v0.2.0 +[0.1.0]: https://github.com/paragonie/multi_factor/tree/v0.1.0 From 5b31bf8a712c9e9f56401a3619eafb70812cf51a Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Wed, 17 Mar 2021 12:40:06 -0600 Subject: [PATCH 5/9] Avoid duplicating code for HOTP value generation Also fixed level one static analysis warnings. --- composer.json | 2 +- psalm.xml | 2 +- src/MultiFactorInterface.php | 5 -- src/OTP/HOTP.php | 89 +++++++++++++++++------------------- src/OTP/TOTP.php | 61 +++--------------------- src/OneTime.php | 11 +---- 6 files changed, 54 insertions(+), 116 deletions(-) diff --git a/composer.json b/composer.json index 05e7860..7d1b411 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "require-dev": { "phpunit/phpunit": "^8", "psalm/plugin-phpunit": "^0.15", - "vimeo/psalm": "^4.4" + "vimeo/psalm": "^4.6.4" }, "autoload": { "psr-4": { diff --git a/psalm.xml b/psalm.xml index 2124cd8..03f4d03 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,6 +1,6 @@ length = $length; $this->algo = $algo; } @@ -47,24 +43,56 @@ public function __construct( * @return string * @throws \OutOfRangeException */ - public function getCode( - $sharedSecret, - int $counterValue - ): string { - if ($this->length < 1 || $this->length > 10) { + public function getCode($sharedSecret, int $counterValue): string + { + $key = is_string($sharedSecret) ? $sharedSecret : $sharedSecret->getString(); + $msg = $this->getTValue($counterValue, true); + return self::generateHOTPValue($this->length, $key, $this->algo, $msg); + } + + public function getLength(): int + { + return $this->length; + } + + /** + * Get the binary T value + */ + protected function getTValue(int $counter, bool $rawOutput = false): string + { + $hex = \str_pad( + \dechex($counter), + 16, + '0', + STR_PAD_LEFT + ); + if ($rawOutput) { + return Hex::decode($hex); + } + return $hex; + } + + /** + * @internal + * @ref https://tools.ietf.org/html/rfc4226 + */ + public static function generateHOTPValue(int $length, string $key, string $algo, string $data): string + { + if ($length < 1 || $length > 10) { throw new \OutOfRangeException( 'Length must be between 1 and 10, as a consequence of RFC 6238.' ); } - $msg = $this->getTValue($counterValue, true); - $bytes = \hash_hmac($this->algo, $msg, is_string($sharedSecret) ? $sharedSecret : $sharedSecret->getString(), true); + $bytes = \hash_hmac($algo, $data, $key, true); $byteLen = Binary::safeStrlen($bytes); // Per the RFC + /** @var int $offset */ $offset = \unpack('C', $bytes[$byteLen - 1])[1]; $offset &= 0x0f; + /** @var array{0: int, 1: int, 2: int, 3: int} $unpacked */ $unpacked = \array_values( \unpack('C*', Binary::safeSubstr($bytes, $offset, 4)) ); @@ -76,44 +104,13 @@ public function getCode( | (($unpacked[3] & 0xff) ) ); - $intValue %= 10 ** $this->length; + $intValue %= 10 ** $length; return \str_pad( (string) $intValue, - $this->length, + $length, '0', \STR_PAD_LEFT ); } - - /** - * @return int - */ - public function getLength(): int - { - return $this->length; - } - - /** - * Get the binary T value - * - * @param int $unixTimestamp - * @param bool $rawOutput - * @return string - */ - protected function getTValue( - int $counter, - bool $rawOutput = false - ): string { - $hex = \str_pad( - \dechex($counter), - 16, - '0', - STR_PAD_LEFT - ); - if ($rawOutput) { - return Hex::decode($hex); - } - return $hex; - } } diff --git a/src/OTP/TOTP.php b/src/OTP/TOTP.php index b65c683..6ffa905 100644 --- a/src/OTP/TOTP.php +++ b/src/OTP/TOTP.php @@ -2,10 +2,7 @@ declare(strict_types=1); namespace ParagonIE\MultiFactor\OTP; -use ParagonIE\ConstantTime\{ - Binary, - Hex -}; +use ParagonIE\ConstantTime\Hex; use ParagonIE\HiddenString\HiddenString; /** @@ -63,56 +60,18 @@ public function __construct( * @return string * @throws \OutOfRangeException */ - public function getCode( - $sharedSecret, - int $counterValue - ): string { - if ($this->length < 1 || $this->length > 10) { - throw new \OutOfRangeException( - 'Length must be between 1 and 10, as a consequence of RFC 6238.' - ); - } + public function getCode($sharedSecret, int $counterValue): string + { + $key = is_string($sharedSecret) ? $sharedSecret : $sharedSecret->getString(); $msg = $this->getTValue($counterValue, true); - $bytes = \hash_hmac($this->algo, $msg, is_string($sharedSecret) ? $sharedSecret : $sharedSecret->getString(), true); - - $byteLen = Binary::safeStrlen($bytes); - - // Per the RFC - $offset = \unpack('C', $bytes[$byteLen - 1])[1]; - $offset &= 0x0f; - - $unpacked = \array_values( - \unpack('C*', Binary::safeSubstr($bytes, $offset, 4)) - ); - - $intValue = ( - (($unpacked[0] & 0x7f) << 24) - | (($unpacked[1] & 0xff) << 16) - | (($unpacked[2] & 0xff) << 8) - | (($unpacked[3] & 0xff) ) - ); - - $intValue %= 10 ** $this->length; - - return \str_pad( - (string) $intValue, - $this->length, - '0', - \STR_PAD_LEFT - ); + return HOTP::generateHOTPValue($this->length, $key, $this->algo, $msg); } - /** - * @return int - */ public function getLength(): int { return $this->length; } - /** - * @return int - */ public function getTimeStep(): int { return $this->timeStep; @@ -120,15 +79,9 @@ public function getTimeStep(): int /** * Get the binary T value - * - * @param int $unixTimestamp - * @param bool $rawOutput - * @return string */ - protected function getTValue( - int $unixTimestamp, - bool $rawOutput = false - ): string { + protected function getTValue(int $unixTimestamp, bool $rawOutput = false): string + { $value = \intdiv( $unixTimestamp - $this->timeZero, $this->timeStep !== 0 diff --git a/src/OneTime.php b/src/OneTime.php index 0679f50..63f5f92 100644 --- a/src/OneTime.php +++ b/src/OneTime.php @@ -29,11 +29,11 @@ class OneTime implements MultiFactorInterface * FIDOU2F constructor. * * @param string|HiddenString $secretKey - * @param OTPInterface $otp + * @param OTPInterface|null $otp */ public function __construct( $secretKey = '', - OTPInterface $otp = null + ?OTPInterface $otp = null ) { $this->secretKey = ($secretKey instanceof HiddenString) ? $secretKey : new HiddenString($secretKey); if (!$otp) { @@ -44,9 +44,6 @@ public function __construct( /** * Generate a TOTP code for 2FA - * - * @param int $counterValue - * @return string */ public function generateCode(int $counterValue = 0): string { @@ -58,10 +55,6 @@ public function generateCode(int $counterValue = 0): string /** * Validate a user-provided code - * - * @param string $code - * @param int $counterValue - * @return bool */ public function validateCode(string $code, int $counterValue = 0): bool { From 54ee2241adc107e93b87b143814f198faf690d4a Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Wed, 17 Mar 2021 12:49:33 -0600 Subject: [PATCH 6/9] Add property type declarations and require PHP 7.4+ Also updated the HiddenString dependency to v2.0 which requires PHP 7.4. --- .github/workflows/php.yml | 28 +++++++++++++++------------- README.md | 2 +- composer.json | 6 +++--- src/OTP/HOTP.php | 11 ++--------- src/OTP/TOTP.php | 25 ++++--------------------- src/OneTime.php | 15 +++------------ src/Vendor/GoogleAuth.php | 5 +---- 7 files changed, 29 insertions(+), 63 deletions(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index ca4015f..a13e6d7 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -1,9 +1,5 @@ name: PHP Composer - -on: - push: ~ - pull_request: ~ - +on: [push, pull_request] jobs: build: name: Run tests on ${{ matrix.php }} @@ -11,21 +7,27 @@ jobs: strategy: matrix: - php: [ '7.2', '7.3', '7.4', '8.0' ] + php: [ '7.4', '8.0', '8.1', '8.2' ] steps: - - uses: actions/checkout@v2 - - uses: shivammathur/setup-php@v2 + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - tools: composer:v2, psalm + tools: psalm - name: Setup problem matchers for PHPUnit run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - run: composer install --no-progress --prefer-dist --no-suggest + - name: Install Composer dependencies + run: composer install --no-progress - - run: psalm --output-format=github - if: ${{ matrix.php == '8.0' }} + - name: Run Psalm + run: psalm --output-format=github + if: ${{ matrix.php == '8.2' }} - - run: vendor/bin/phpunit + - name: Run PHPUnit + run: vendor/bin/phpunit diff --git a/README.md b/README.md index f4f17e9..ba88ba5 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ needs. ## Requirements -* PHP 7.2+ +* PHP 7.4+ * As per [Paragon Initiative Enterprise's commitment to open source](https://paragonie.com/blog/2016/04/go-php-7-our-commitment-maintaining-our-open-source-projects), all new software will no longer be written for PHP 5. diff --git a/composer.json b/composer.json index 7d1b411..ff8962c 100644 --- a/composer.json +++ b/composer.json @@ -32,13 +32,13 @@ "source": "https://github.com/paragonie/multi_factor" }, "require": { - "php": ">=7.2", + "php": ">=7.4", "bacon/bacon-qr-code": "^2", "paragonie/constant_time_encoding": "^2", - "paragonie/hidden-string": "^1" + "paragonie/hidden-string": "^2.0" }, "require-dev": { - "phpunit/phpunit": "^8", + "phpunit/phpunit": "^9.5", "psalm/plugin-phpunit": "^0.15", "vimeo/psalm": "^4.6.4" }, diff --git a/src/OTP/HOTP.php b/src/OTP/HOTP.php index 04035e3..dd7b427 100644 --- a/src/OTP/HOTP.php +++ b/src/OTP/HOTP.php @@ -14,15 +14,8 @@ */ class HOTP implements OTPInterface { - /** - * @var string - */ - protected $algo; - - /** - * @var int - */ - protected $length; + protected string $algo; + protected int $length; /** * @param int $length How many digits should each HOTP be? diff --git a/src/OTP/TOTP.php b/src/OTP/TOTP.php index 6ffa905..21f8292 100644 --- a/src/OTP/TOTP.php +++ b/src/OTP/TOTP.php @@ -11,29 +11,12 @@ */ class TOTP implements OTPInterface { - /** - * @var string - */ - protected $algo; - - /** - * @var int - */ - protected $length; - - /** - * @var int - */ - protected $timeStep; - - /** - * @var int - */ - protected $timeZero; + protected string $algo; + protected int $length; + protected int $timeStep; + protected int $timeZero; /** - * TOTP constructor. - * * @param int $timeZero The start time for calculating the TOTP * @param int $timeStep How many seconds should each TOTP live? * @param int $length How many digits should each TOTP be? diff --git a/src/OneTime.php b/src/OneTime.php index 63f5f92..adb0d49 100644 --- a/src/OneTime.php +++ b/src/OneTime.php @@ -15,19 +15,10 @@ */ class OneTime implements MultiFactorInterface { - /** - * @var OTPInterface - */ - protected $otp; - - /** - * @var HiddenString - */ - protected $secretKey; + protected OTPInterface $otp; + protected HiddenString $secretKey; /** - * FIDOU2F constructor. - * * @param string|HiddenString $secretKey * @param OTPInterface|null $otp */ @@ -36,7 +27,7 @@ public function __construct( ?OTPInterface $otp = null ) { $this->secretKey = ($secretKey instanceof HiddenString) ? $secretKey : new HiddenString($secretKey); - if (!$otp) { + if ($otp === null) { $otp = new TOTP(); } $this->otp = $otp; diff --git a/src/Vendor/GoogleAuth.php b/src/Vendor/GoogleAuth.php index 559ec6e..49490a2 100644 --- a/src/Vendor/GoogleAuth.php +++ b/src/Vendor/GoogleAuth.php @@ -19,10 +19,7 @@ */ class GoogleAuth extends OneTime { - /** - * @var int - */ - public $defaultQRCodeSize = 384; + public int $defaultQRCodeSize = 384; /** * Create a QR code to load the key onto the device From b2c768ad9df792094128f31ae221a0083d315781 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Mon, 2 Jan 2023 15:58:43 -0600 Subject: [PATCH 7/9] Remove unused rawOutput option --- src/OTP/HOTP.php | 10 ++++------ src/OTP/TOTP.php | 11 +++++------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/OTP/HOTP.php b/src/OTP/HOTP.php index dd7b427..a3d194c 100644 --- a/src/OTP/HOTP.php +++ b/src/OTP/HOTP.php @@ -39,7 +39,7 @@ public function __construct(int $length = 6, string $algo = 'sha1') public function getCode($sharedSecret, int $counterValue): string { $key = is_string($sharedSecret) ? $sharedSecret : $sharedSecret->getString(); - $msg = $this->getTValue($counterValue, true); + $msg = $this->getTValue($counterValue); return self::generateHOTPValue($this->length, $key, $this->algo, $msg); } @@ -51,7 +51,7 @@ public function getLength(): int /** * Get the binary T value */ - protected function getTValue(int $counter, bool $rawOutput = false): string + protected function getTValue(int $counter): string { $hex = \str_pad( \dechex($counter), @@ -59,10 +59,8 @@ protected function getTValue(int $counter, bool $rawOutput = false): string '0', STR_PAD_LEFT ); - if ($rawOutput) { - return Hex::decode($hex); - } - return $hex; + + return Hex::decode($hex); } /** diff --git a/src/OTP/TOTP.php b/src/OTP/TOTP.php index 21f8292..1d1e659 100644 --- a/src/OTP/TOTP.php +++ b/src/OTP/TOTP.php @@ -46,7 +46,7 @@ public function __construct( public function getCode($sharedSecret, int $counterValue): string { $key = is_string($sharedSecret) ? $sharedSecret : $sharedSecret->getString(); - $msg = $this->getTValue($counterValue, true); + $msg = $this->getTValue($counterValue); return HOTP::generateHOTPValue($this->length, $key, $this->algo, $msg); } @@ -63,7 +63,7 @@ public function getTimeStep(): int /** * Get the binary T value */ - protected function getTValue(int $unixTimestamp, bool $rawOutput = false): string + protected function getTValue(int $unixTimestamp): string { $value = \intdiv( $unixTimestamp - $this->timeZero, @@ -71,15 +71,14 @@ protected function getTValue(int $unixTimestamp, bool $rawOutput = false): strin ? $this->timeStep : 1 ); + $hex = \str_pad( \dechex($value), 16, '0', STR_PAD_LEFT ); - if ($rawOutput) { - return Hex::decode($hex); - } - return $hex; + + return Hex::decode($hex); } } From 36eafccd0e22fcc90cf7d207c8547649a451c6a0 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Mon, 2 Jan 2023 16:01:03 -0600 Subject: [PATCH 8/9] Use explicit nullable type for optional Writer parameter --- CHANGELOG.md | 5 ++++- composer.json | 4 ++-- src/Vendor/GoogleAuth.php | 14 +++++++++----- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cbcec9..42c80d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,19 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Support for PHP 8. +- Native property type declarations. - `GoogleAuth::getQRCode()` and `GoogleAuth::makeQRCodeMessage()` methods. - HiddenString support for secret key. - `GoogleAuth->defaultQRCodeSize` property (replaces the removed width and height properties). ### Changed -- PHP 7.2+ is now required. +- PHP 7.4+ is now required. - Renamed `FIDOU2F` class to `OneTime`. - Updated [BaconQrCode](https://github.com/Bacon/BaconQrCode) dependency to v2. This version has a slightly different API for rendering QR code images. - Test files are now excluded from Composer package. +- Unified internal code for HOTP value generation. ### Removed - `GoogleAuth->defaultQRCodeWidth` and `GoogleAuth->defaultQRCodeHeight` properties. +- Unused internal `rawOutput` option. ## [0.2.2] - 2016-06-17 diff --git a/composer.json b/composer.json index ff8962c..3dc943a 100644 --- a/composer.json +++ b/composer.json @@ -39,8 +39,8 @@ }, "require-dev": { "phpunit/phpunit": "^9.5", - "psalm/plugin-phpunit": "^0.15", - "vimeo/psalm": "^4.6.4" + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.4" }, "autoload": { "psr-4": { diff --git a/src/Vendor/GoogleAuth.php b/src/Vendor/GoogleAuth.php index 49490a2..a51ebd3 100644 --- a/src/Vendor/GoogleAuth.php +++ b/src/Vendor/GoogleAuth.php @@ -24,17 +24,16 @@ class GoogleAuth extends OneTime /** * Create a QR code to load the key onto the device * - * @param Writer $qrCodeWriter + * @param Writer|null $qrCodeWriter * @param string $outFile Where to store the QR code? * @param string $username Username or email address * @param string $issuer Optional * @param string $label Optional * @param int $initialCounter Initial counter value - * @return void * @throws \Exception */ public function makeQRCode( - Writer $qrCodeWriter = null, + ?Writer $qrCodeWriter = null, string $outFile = 'php://output', string $username = '', string $issuer = '', @@ -47,7 +46,7 @@ public function makeQRCode( } public function getQRCode( - Writer $qrCodeWriter = null, + ?Writer $qrCodeWriter = null, string $username = '', string $issuer = '', string $label = '', @@ -71,6 +70,7 @@ public function makeQRCodeMessage( } else { throw new \Exception('Not implemented'); } + if ($label) { $message .= \urlencode( \str_replace(':', '', $label) @@ -81,21 +81,25 @@ public function makeQRCodeMessage( $args = [ 'secret' => Base32::encode($this->secretKey->getString()) ]; + if ($issuer) { $args['issuer'] = $issuer; } + $args['digits'] = $this->otp->getLength(); + if ($this->otp instanceof TOTP) { $args['period'] = $this->otp->getTimeStep(); } else { $args['counter'] = $initialCounter; } + $message .= '?' . \http_build_query($args); return $message; } - protected function makeQRCodeWriteOrDefault(Writer $qrCodeWriter = null) : Writer + protected function makeQRCodeWriteOrDefault(?Writer $qrCodeWriter): Writer { // Sane default; You can dependency-inject a replacement: if (!$qrCodeWriter) { From 116f082b32a21b9b4c3dab13b2a32807fc632233 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Mon, 2 Jan 2023 16:16:07 -0600 Subject: [PATCH 9/9] Avoid Psalm-specific annotations --- test/GoogleAuthTest.php | 2 +- test/HOTPTest.php | 4 ++-- test/TOTPTest.php | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/test/GoogleAuthTest.php b/test/GoogleAuthTest.php index b139ef0..4b5cbc3 100644 --- a/test/GoogleAuthTest.php +++ b/test/GoogleAuthTest.php @@ -12,7 +12,7 @@ class GoogleAuthTest extends TestCase { /** - * @psalm-return Generator + * @return Generator */ public function dataProviderMakeQRCodeMessage() : Generator { diff --git a/test/HOTPTest.php b/test/HOTPTest.php index e89a178..e8fde30 100644 --- a/test/HOTPTest.php +++ b/test/HOTPTest.php @@ -35,7 +35,7 @@ public function testTOTP(): void /** * @dataProvider dataProviderFailureOfGetCode * - * @psalm-param class-string<\Throwable> $expectedException + * @param class-string $expectedException */ public function testFailureOfGetCode( int $length, @@ -55,7 +55,7 @@ public function testFailureOfGetCode( } /** - * @psalm-return array, 2:string, 3:string, 4:int}> + * @return array, 2:string, 3:string, 4:int}> */ public function dataProviderFailureOfGetCode(): array { diff --git a/test/TOTPTest.php b/test/TOTPTest.php index 151c3ba..56c41b7 100644 --- a/test/TOTPTest.php +++ b/test/TOTPTest.php @@ -9,7 +9,7 @@ /** * Class TOTPTest */ -class TOPTTest extends TestCase +class TOTPTest extends TestCase { /** * Test vectors from RFC 6238 @@ -32,7 +32,7 @@ public function testTOTP(): void ); /** - * @psalm-var array + * @var array $testVectors */ $testVectors = [ [ @@ -173,8 +173,7 @@ public function testTOTP(): void * @dataProvider dataProviderFailureOfGetCode * * @param array{0:int, 1:int, 2:int, 3:string} $constructorArgs - * - * @psalm-param class-string<\Throwable> $expectedException + * @param class-string $expectedException */ public function testFailureOfGetCode( array $constructorArgs, @@ -195,7 +194,7 @@ public function testFailureOfGetCode( } /** - * @psalm-return Generator, 2:string, 3:string, 4:int}, mixed, void> + * @return Generator, 2:string, 3:string, 4:int}, mixed, void> */ public function dataProviderFailureOfGetCode(): \Generator {