diff --git a/phpstan.neon b/phpstan.neon index 5f2b3faa8f0294fa4606e64dd7edff999c070cd3..4b0aa288751dcd108a62a197e086e3aacedb4358 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,6 +5,7 @@ parameters: - tests ignoreErrors: - '#Variable property access on \$this\(OTPHP\\OTP\)\.#' + includes: - vendor/phpstan/phpstan-strict-rules/rules.neon - vendor/phpstan/phpstan-phpunit/extension.neon diff --git a/src/Factory.php b/src/Factory.php index 42b5fbf79c2a7d7999b3e3726e4093532d60ac81..4b917749f33e120869b9bcf6ce4ea0c6aaa21d5e 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -7,6 +7,7 @@ namespace OTPHP; use Assert\Assertion; use function count; use InvalidArgumentException; +use function Safe\sprintf; use Throwable; /** diff --git a/src/HOTP.php b/src/HOTP.php index 49d5c232614e408102f0db4ef403cb204ac92a99..7c941877223dfb28c082e1329e39f5f559d03350 100644 --- a/src/HOTP.php +++ b/src/HOTP.php @@ -8,14 +8,14 @@ use Assert\Assertion; final class HOTP extends OTP implements HOTPInterface { - protected function __construct(?string $secret, int $counter, string $digest, int $digits) + protected function __construct(null|string $secret, int $counter, string $digest, int $digits) { parent::__construct($secret, $digest, $digits); $this->setCounter($counter); } public static function create( - ?string $secret = null, + null|string $secret = null, int $counter = 0, string $digest = 'sha1', int $digits = 6 @@ -41,7 +41,7 @@ final class HOTP extends OTP implements HOTPInterface /** * If the counter is not provided, the OTP is verified at the actual counter. */ - public function verify(string $otp, ?int $counter = null, ?int $window = null): bool + public function verify(string $otp, null|int $counter = null, null|int|float $window = null): bool { Assertion::greaterOrEqualThan($counter, 0, 'The counter must be at least 0.'); @@ -81,12 +81,12 @@ final class HOTP extends OTP implements HOTPInterface $this->setCounter($counter); } - private function getWindow(?int $window): int + private function getWindow(null|int|float $window): int|float { return abs($window ?? 0); } - private function verifyOtpWithWindow(string $otp, int $counter, ?int $window): bool + private function verifyOtpWithWindow(string $otp, int $counter, null|int|float $window): bool { $window = $this->getWindow($window); diff --git a/src/HOTPInterface.php b/src/HOTPInterface.php index a311cb29d85c9e99aa1bfa79cb8260bca32e65b7..1f9cdd7f8fd863db555beaccad5efbcce46d4b0e 100644 --- a/src/HOTPInterface.php +++ b/src/HOTPInterface.php @@ -17,7 +17,7 @@ interface HOTPInterface extends OTPInterface * If the secret is null, a random 64 bytes secret will be generated. */ public static function create( - ?string $secret = null, + null|string $secret = null, int $counter = 0, string $digest = 'sha1', int $digits = 6 diff --git a/src/OTP.php b/src/OTP.php index 2ff11dedc21d85de8cb950ce7f95330c5c6b3fc2..25fd4d62a98fddd1fa3bc621d22ac4d459ff0077 100644 --- a/src/OTP.php +++ b/src/OTP.php @@ -10,6 +10,8 @@ use function count; use Exception; use ParagonIE\ConstantTime\Base32; use RuntimeException; +use function Safe\ksort; +use function Safe\sprintf; use function Safe\unpack; use const STR_PAD_LEFT; @@ -17,7 +19,7 @@ abstract class OTP implements OTPInterface { use ParameterTrait; - protected function __construct(?string $secret, string $digest, int $digits) + protected function __construct(null|string $secret, string $digest, int $digits) { $this->setSecret($secret); $this->setDigest($digest); diff --git a/src/OTPInterface.php b/src/OTPInterface.php index 6c28a3f7549bfddf8cf79c4215a8bc1681df32c3..0d8d888d82b4f7245a71800fe3b6fdcbd22069b4 100644 --- a/src/OTPInterface.php +++ b/src/OTPInterface.php @@ -15,7 +15,7 @@ interface OTPInterface * Verify that the OTP is valid with the specified input. If no input is provided, the input is set to a default * value or false is returned. */ - public function verify(string $otp, ?int $input = null, ?int $window = null): bool; + public function verify(string $otp, null|int $input = null, null|int|float $window = null): bool; /** * @return string The secret of the OTP @@ -30,7 +30,7 @@ interface OTPInterface /** * @return string|null The label of the OTP */ - public function getLabel(): ?string; + public function getLabel(): null|string; /** * @return string|null The issuer @@ -56,10 +56,7 @@ interface OTPInterface */ public function getDigest(): string; - /** - * @return mixed|null - */ - public function getParameter(string $parameter); + public function getParameter(string $parameter): mixed; public function hasParameter(string $parameter): bool; @@ -68,10 +65,7 @@ interface OTPInterface */ public function getParameters(): array; - /** - * @param mixed|null $value - */ - public function setParameter(string $parameter, $value): void; + public function setParameter(string $parameter, mixed $value): void; /** * Get the provisioning URI. diff --git a/src/ParameterTrait.php b/src/ParameterTrait.php index 74c43d11b2571b65e35e4779572630e427da0688..cbc3e277a575749d4bf880c8e52472b8f369d18a 100644 --- a/src/ParameterTrait.php +++ b/src/ParameterTrait.php @@ -8,6 +8,7 @@ use function array_key_exists; use Assert\Assertion; use InvalidArgumentException; use ParagonIE\ConstantTime\Base32; +use function Safe\sprintf; trait ParameterTrait { @@ -44,7 +45,7 @@ trait ParameterTrait return $value; } - public function getLabel(): ?string + public function getLabel(): null|string { return $this->label; } @@ -54,7 +55,7 @@ trait ParameterTrait $this->setParameter('label', $label); } - public function getIssuer(): ?string + public function getIssuer(): null|string { return $this->issuer; } @@ -95,7 +96,7 @@ trait ParameterTrait return array_key_exists($parameter, $this->parameters); } - public function getParameter(string $parameter) + public function getParameter(string $parameter): mixed { if ($this->hasParameter($parameter)) { return $this->getParameters()[$parameter]; @@ -104,7 +105,7 @@ trait ParameterTrait throw new InvalidArgumentException(sprintf('Parameter "%s" does not exist', $parameter)); } - public function setParameter(string $parameter, $value): void + public function setParameter(string $parameter, mixed $value): void { $map = $this->getParameterMap(); @@ -157,7 +158,7 @@ trait ParameterTrait ]; } - private function setSecret(?string $secret): void + private function setSecret(null|string $secret): void { $this->setParameter('secret', $secret); } diff --git a/src/TOTP.php b/src/TOTP.php index 75805094e7fad2761194cd729105014ba1f0d972..2adf41f6a37a5dab6d4392e47a58b075a2364158 100644 --- a/src/TOTP.php +++ b/src/TOTP.php @@ -5,10 +5,11 @@ declare(strict_types=1); namespace OTPHP; use Assert\Assertion; +use function Safe\ksort; final class TOTP extends OTP implements TOTPInterface { - protected function __construct(?string $secret, int $period, string $digest, int $digits, int $epoch = 0) + protected function __construct(null|string $secret, int $period, string $digest, int $digits, int $epoch = 0) { parent::__construct($secret, $digest, $digits); $this->setPeriod($period); @@ -16,7 +17,7 @@ final class TOTP extends OTP implements TOTPInterface } public static function create( - ?string $secret = null, + null|string $secret = null, int $period = 30, string $digest = 'sha1', int $digits = 6, @@ -54,7 +55,7 @@ final class TOTP extends OTP implements TOTPInterface /** * If no timestamp is provided, the OTP is verified at the actual timestamp. */ - public function verify(string $otp, ?int $timestamp = null, ?int $window = null): bool + public function verify(string $otp, null|int $timestamp = null, null|int|float $window = null): bool { $timestamp = $this->getTimestamp($timestamp); @@ -125,7 +126,7 @@ final class TOTP extends OTP implements TOTPInterface $this->setParameter('epoch', $epoch); } - private function verifyOtpWithWindow(string $otp, int $timestamp, int $window): bool + private function verifyOtpWithWindow(string $otp, int $timestamp, int|float $window): bool { $window = abs($window); @@ -143,7 +144,7 @@ final class TOTP extends OTP implements TOTPInterface return false; } - private function getTimestamp(?int $timestamp): int + private function getTimestamp(null|int $timestamp): int { $timestamp = $timestamp ?? time(); Assertion::greaterOrEqualThan($timestamp, 0, 'Timestamp must be at least 0.'); diff --git a/src/TOTPInterface.php b/src/TOTPInterface.php index d79fd55991f818b1254b154862a49730e8b6052f..2d492f941b8180e8eaaee8bfec559b767d871f80 100644 --- a/src/TOTPInterface.php +++ b/src/TOTPInterface.php @@ -12,7 +12,7 @@ interface TOTPInterface extends OTPInterface * If the secret is null, a random 64 bytes secret will be generated. */ public static function create( - ?string $secret = null, + null|string $secret = null, int $period = 30, string $digest = 'sha1', int $digits = 6