From b668f63d67be770c0114d1f0cef9699ba7a211ee Mon Sep 17 00:00:00 2001
From: Spomky <contact@spomky-labs.com>
Date: Wed, 2 Feb 2022 21:17:58 +0100
Subject: [PATCH] Bugs fixed

---
 phpstan.neon           |  1 +
 src/Factory.php        |  1 +
 src/HOTP.php           | 10 +++++-----
 src/HOTPInterface.php  |  2 +-
 src/OTP.php            |  4 +++-
 src/OTPInterface.php   | 14 ++++----------
 src/ParameterTrait.php | 11 ++++++-----
 src/TOTP.php           | 11 ++++++-----
 src/TOTPInterface.php  |  2 +-
 9 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/phpstan.neon b/phpstan.neon
index 5f2b3fa..4b0aa28 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 42b5fbf..4b91774 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 49d5c23..7c94187 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 a311cb2..1f9cdd7 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 2ff11de..25fd4d6 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 6c28a3f..0d8d888 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 74c43d1..cbc3e27 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 7580509..2adf41f 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 d79fd55..2d492f9 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
-- 
GitLab