aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/spomky-labs/otphp/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/spomky-labs/otphp/src')
-rw-r--r--vendor/spomky-labs/otphp/src/Factory.php12
-rw-r--r--vendor/spomky-labs/otphp/src/FactoryInterface.php2
-rw-r--r--vendor/spomky-labs/otphp/src/HOTP.php15
-rw-r--r--vendor/spomky-labs/otphp/src/HOTPInterface.php7
-rw-r--r--vendor/spomky-labs/otphp/src/OTP.php27
-rw-r--r--vendor/spomky-labs/otphp/src/OTPInterface.php43
-rw-r--r--vendor/spomky-labs/otphp/src/ParameterTrait.php32
-rw-r--r--vendor/spomky-labs/otphp/src/TOTP.php19
-rw-r--r--vendor/spomky-labs/otphp/src/TOTPInterface.php18
-rw-r--r--vendor/spomky-labs/otphp/src/Url.php19
10 files changed, 161 insertions, 33 deletions
diff --git a/vendor/spomky-labs/otphp/src/Factory.php b/vendor/spomky-labs/otphp/src/Factory.php
index d5c60cc34..409d8751e 100644
--- a/vendor/spomky-labs/otphp/src/Factory.php
+++ b/vendor/spomky-labs/otphp/src/Factory.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace OTPHP;
+use function assert;
use function count;
use InvalidArgumentException;
use Throwable;
@@ -55,6 +56,9 @@ final class Factory implements FactoryInterface
);
$otp->setIssuerIncludedAsParameter(true);
}
+
+ assert($result[0] !== '');
+
$otp->setIssuer($result[0]);
}
@@ -76,10 +80,16 @@ final class Factory implements FactoryInterface
}
}
+ /**
+ * @param non-empty-string $data
+ * @return non-empty-string
+ */
private static function getLabel(string $data): string
{
$result = explode(':', rawurldecode(mb_substr($data, 1)));
+ $label = count($result) === 2 ? $result[1] : $result[0];
+ assert($label !== '');
- return count($result) === 2 ? $result[1] : $result[0];
+ return $label;
}
}
diff --git a/vendor/spomky-labs/otphp/src/FactoryInterface.php b/vendor/spomky-labs/otphp/src/FactoryInterface.php
index 74386adeb..dd14e45f9 100644
--- a/vendor/spomky-labs/otphp/src/FactoryInterface.php
+++ b/vendor/spomky-labs/otphp/src/FactoryInterface.php
@@ -9,6 +9,8 @@ interface FactoryInterface
/**
* This method is the unique public method of the class. It can load a provisioning Uri and convert it into an OTP
* object.
+ *
+ * @param non-empty-string $uri
*/
public static function loadFromProvisioningUri(string $uri): OTPInterface;
}
diff --git a/vendor/spomky-labs/otphp/src/HOTP.php b/vendor/spomky-labs/otphp/src/HOTP.php
index aa5a22754..1588d48aa 100644
--- a/vendor/spomky-labs/otphp/src/HOTP.php
+++ b/vendor/spomky-labs/otphp/src/HOTP.php
@@ -49,7 +49,7 @@ final class HOTP extends OTP implements HOTPInterface
public function getCounter(): int
{
$value = $this->getParameter('counter');
- is_int($value) || throw new InvalidArgumentException('Invalid "counter" parameter.');
+ (is_int($value) && $value >= 0) || throw new InvalidArgumentException('Invalid "counter" parameter.');
return $value;
}
@@ -83,7 +83,7 @@ final class HOTP extends OTP implements HOTPInterface
}
/**
- * @return array<string, callable>
+ * @return array<non-empty-string, callable>
*/
protected function getParameterMap(): array
{
@@ -97,16 +97,27 @@ final class HOTP extends OTP implements HOTPInterface
]];
}
+ /**
+ * @param positive-int $counter
+ */
private function updateCounter(int $counter): void
{
$this->setCounter($counter);
}
+ /**
+ * @param null|0|positive-int $window
+ */
private function getWindow(null|int $window): int
{
return abs($window ?? self::DEFAULT_WINDOW);
}
+ /**
+ * @param non-empty-string $otp
+ * @param 0|positive-int $counter
+ * @param null|0|positive-int $window
+ */
private function verifyOtpWithWindow(string $otp, int $counter, null|int $window): bool
{
$window = $this->getWindow($window);
diff --git a/vendor/spomky-labs/otphp/src/HOTPInterface.php b/vendor/spomky-labs/otphp/src/HOTPInterface.php
index 853e76c07..449e9383b 100644
--- a/vendor/spomky-labs/otphp/src/HOTPInterface.php
+++ b/vendor/spomky-labs/otphp/src/HOTPInterface.php
@@ -10,6 +10,8 @@ interface HOTPInterface extends OTPInterface
/**
* The initial counter (a positive integer).
+ *
+ * @return 0|positive-int
*/
public function getCounter(): int;
@@ -19,7 +21,9 @@ interface HOTPInterface extends OTPInterface
* If the secret is null, a random 64 bytes secret will be generated.
*
* @param null|non-empty-string $secret
+ * @param 0|positive-int $counter
* @param non-empty-string $digest
+ * @param positive-int $digits
*
* @deprecated Deprecated since v11.1, use ::createFromSecret or ::generate instead
*/
@@ -30,5 +34,8 @@ interface HOTPInterface extends OTPInterface
int $digits = 6
): self;
+ /**
+ * @param 0|positive-int $counter
+ */
public function setCounter(int $counter): void;
}
diff --git a/vendor/spomky-labs/otphp/src/OTP.php b/vendor/spomky-labs/otphp/src/OTP.php
index 2cba067b3..4765d49eb 100644
--- a/vendor/spomky-labs/otphp/src/OTP.php
+++ b/vendor/spomky-labs/otphp/src/OTP.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace OTPHP;
+use function assert;
use function chr;
use function count;
use Exception;
@@ -49,6 +50,10 @@ abstract class OTP implements OTPInterface
/**
* The OTP at the specified input.
+ *
+ * @param 0|positive-int $input
+ *
+ * @return non-empty-string
*/
protected function generateOTP(int $input): string
{
@@ -65,7 +70,7 @@ abstract class OTP implements OTPInterface
}
/**
- * @param array<string, mixed> $options
+ * @param array<non-empty-string, mixed> $options
*/
protected function filterOptions(array &$options): void
{
@@ -83,7 +88,10 @@ abstract class OTP implements OTPInterface
}
/**
- * @param array<string, mixed> $options
+ * @param non-empty-string $type
+ * @param array<non-empty-string, mixed> $options
+ *
+ * @return non-empty-string
*/
protected function generateURI(string $type, array $options): string
{
@@ -102,20 +110,33 @@ abstract class OTP implements OTPInterface
);
}
+ /**
+ * @param non-empty-string $safe
+ * @param non-empty-string $user
+ */
protected function compareOTP(string $safe, string $user): bool
{
return hash_equals($safe, $user);
}
+ /**
+ * @return non-empty-string
+ */
private function getDecodedSecret(): string
{
try {
- return Base32::decodeUpper($this->getSecret());
+ $decoded = Base32::decodeUpper($this->getSecret());
} catch (Exception) {
throw new RuntimeException('Unable to decode the secret. Is it correctly base32 encoded?');
}
+ assert($decoded !== '');
+
+ return $decoded;
}
+ /**
+ * @param 0|positive-int $int
+ */
private function intToByteString(int $int): string
{
$result = [];
diff --git a/vendor/spomky-labs/otphp/src/OTPInterface.php b/vendor/spomky-labs/otphp/src/OTPInterface.php
index 3b27f5456..f14eef9f4 100644
--- a/vendor/spomky-labs/otphp/src/OTPInterface.php
+++ b/vendor/spomky-labs/otphp/src/OTPInterface.php
@@ -27,6 +27,9 @@ interface OTPInterface
*/
public function setSecret(string $secret): void;
+ /**
+ * @param positive-int $digits
+ */
public function setDigits(int $digits): void;
/**
@@ -35,36 +38,45 @@ interface OTPInterface
public function setDigest(string $digest): void;
/**
- * @return string Return the OTP at the specified timestamp
+ * @param 0|positive-int $input
+ *
+ * @return non-empty-string Return the OTP at the specified timestamp
*/
public function at(int $input): string;
/**
* 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.
+ *
+ * @param non-empty-string $otp
+ * @param null|0|positive-int $input
+ * @param null|0|positive-int $window
*/
public function verify(string $otp, null|int $input = null, null|int $window = null): bool;
/**
- * @return string The secret of the OTP
+ * @return non-empty-string The secret of the OTP
*/
public function getSecret(): string;
/**
- * @param string $label The label of the OTP
+ * @param non-empty-string $label The label of the OTP
*/
public function setLabel(string $label): void;
/**
- * @return string|null The label of the OTP
+ * @return non-empty-string|null The label of the OTP
*/
public function getLabel(): null|string;
/**
- * @return string|null The issuer
+ * @return non-empty-string|null The issuer
*/
public function getIssuer(): ?string;
+ /**
+ * @param non-empty-string $issuer
+ */
public function setIssuer(string $issuer): void;
/**
@@ -75,36 +87,47 @@ interface OTPInterface
public function setIssuerIncludedAsParameter(bool $issuer_included_as_parameter): void;
/**
- * @return int Number of digits in the OTP
+ * @return positive-int Number of digits in the OTP
*/
public function getDigits(): int;
/**
- * @return string Digest algorithm used to calculate the OTP. Possible values are 'md5', 'sha1', 'sha256' and 'sha512'
+ * @return non-empty-string Digest algorithm used to calculate the OTP. Possible values are 'md5', 'sha1', 'sha256' and 'sha512'
*/
public function getDigest(): string;
+ /**
+ * @param non-empty-string $parameter
+ */
public function getParameter(string $parameter): mixed;
+ /**
+ * @param non-empty-string $parameter
+ */
public function hasParameter(string $parameter): bool;
/**
- * @return array<string, mixed>
+ * @return array<non-empty-string, mixed>
*/
public function getParameters(): array;
+ /**
+ * @param non-empty-string $parameter
+ */
public function setParameter(string $parameter, mixed $value): void;
/**
* Get the provisioning URI.
+ *
+ * @return non-empty-string
*/
public function getProvisioningUri(): string;
/**
* Get the provisioning URI.
*
- * @param string $uri The Uri of the QRCode generator with all parameters. This Uri MUST contain a placeholder that will be replaced by the method.
- * @param string $placeholder the placeholder to be replaced in the QR Code generator URI
+ * @param non-empty-string $uri The Uri of the QRCode generator with all parameters. This Uri MUST contain a placeholder that will be replaced by the method.
+ * @param non-empty-string $placeholder the placeholder to be replaced in the QR Code generator URI
*/
public function getQrCodeUri(string $uri, string $placeholder): string;
}
diff --git a/vendor/spomky-labs/otphp/src/ParameterTrait.php b/vendor/spomky-labs/otphp/src/ParameterTrait.php
index b05092351..3b2641e0c 100644
--- a/vendor/spomky-labs/otphp/src/ParameterTrait.php
+++ b/vendor/spomky-labs/otphp/src/ParameterTrait.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace OTPHP;
use function array_key_exists;
+use function assert;
use function in_array;
use InvalidArgumentException;
use function is_int;
@@ -13,18 +14,24 @@ use function is_string;
trait ParameterTrait
{
/**
- * @var array<string, mixed>
+ * @var array<non-empty-string, mixed>
*/
private array $parameters = [];
+ /**
+ * @var non-empty-string|null
+ */
private null|string $issuer = null;
+ /**
+ * @var non-empty-string|null
+ */
private null|string $label = null;
private bool $issuer_included_as_parameter = true;
/**
- * @return array<string, mixed>
+ * @return array<non-empty-string, mixed>
*/
public function getParameters(): array
{
@@ -40,7 +47,7 @@ trait ParameterTrait
public function getSecret(): string
{
$value = $this->getParameter('secret');
- is_string($value) || throw new InvalidArgumentException('Invalid "secret" parameter.');
+ (is_string($value) && $value !== '') || throw new InvalidArgumentException('Invalid "secret" parameter.');
return $value;
}
@@ -78,7 +85,7 @@ trait ParameterTrait
public function getDigits(): int
{
$value = $this->getParameter('digits');
- is_int($value) || throw new InvalidArgumentException('Invalid "digits" parameter.');
+ (is_int($value) && $value > 0) || throw new InvalidArgumentException('Invalid "digits" parameter.');
return $value;
}
@@ -86,7 +93,7 @@ trait ParameterTrait
public function getDigest(): string
{
$value = $this->getParameter('algorithm');
- is_string($value) || throw new InvalidArgumentException('Invalid "algorithm" parameter.');
+ (is_string($value) && $value !== '') || throw new InvalidArgumentException('Invalid "algorithm" parameter.');
return $value;
}
@@ -137,20 +144,21 @@ trait ParameterTrait
}
/**
- * @return array<string, callable>
+ * @return array<non-empty-string, callable>
*/
protected function getParameterMap(): array
{
return [
- 'label' => function ($value) {
+ 'label' => function (string $value): string {
+ assert($value !== '');
$this->hasColon($value) === false || throw new InvalidArgumentException(
'Label must not contain a colon.'
);
return $value;
},
- 'secret' => static fn ($value): string => mb_strtoupper(trim((string) $value, '=')),
- 'algorithm' => static function ($value): string {
+ 'secret' => static fn (string $value): string => mb_strtoupper(trim($value, '=')),
+ 'algorithm' => static function (string $value): string {
$value = mb_strtolower($value);
in_array($value, hash_algos(), true) || throw new InvalidArgumentException(sprintf(
'The "%s" digest is not supported.',
@@ -164,7 +172,8 @@ trait ParameterTrait
return (int) $value;
},
- 'issuer' => function ($value) {
+ 'issuer' => function (string $value): string {
+ assert($value !== '');
$this->hasColon($value) === false || throw new InvalidArgumentException(
'Issuer must not contain a colon.'
);
@@ -174,6 +183,9 @@ trait ParameterTrait
];
}
+ /**
+ * @param non-empty-string $value
+ */
private function hasColon(string $value): bool
{
$colons = [':', '%3A', '%3a'];
diff --git a/vendor/spomky-labs/otphp/src/TOTP.php b/vendor/spomky-labs/otphp/src/TOTP.php
index e9bce9e14..3a7d72870 100644
--- a/vendor/spomky-labs/otphp/src/TOTP.php
+++ b/vendor/spomky-labs/otphp/src/TOTP.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace OTPHP;
+use function assert;
use InvalidArgumentException;
use function is_int;
@@ -50,7 +51,7 @@ final class TOTP extends OTP implements TOTPInterface
public function getPeriod(): int
{
$value = $this->getParameter('period');
- is_int($value) || throw new InvalidArgumentException('Invalid "period" parameter.');
+ (is_int($value) && $value > 0) || throw new InvalidArgumentException('Invalid "period" parameter.');
return $value;
}
@@ -58,7 +59,7 @@ final class TOTP extends OTP implements TOTPInterface
public function getEpoch(): int
{
$value = $this->getParameter('epoch');
- is_int($value) || throw new InvalidArgumentException('Invalid "epoch" parameter.');
+ (is_int($value) && $value >= 0) || throw new InvalidArgumentException('Invalid "epoch" parameter.');
return $value;
}
@@ -128,7 +129,7 @@ final class TOTP extends OTP implements TOTPInterface
}
/**
- * @return array<string, callable>
+ * @return array<non-empty-string, callable>
*/
protected function getParameterMap(): array
{
@@ -152,7 +153,7 @@ final class TOTP extends OTP implements TOTPInterface
}
/**
- * @param array<string, mixed> $options
+ * @param array<non-empty-string, mixed> $options
*/
protected function filterOptions(array &$options): void
{
@@ -165,8 +166,16 @@ final class TOTP extends OTP implements TOTPInterface
ksort($options);
}
+ /**
+ * @param 0|positive-int $timestamp
+ *
+ * @return 0|positive-int
+ */
private function timecode(int $timestamp): int
{
- return (int) floor(($timestamp - $this->getEpoch()) / $this->getPeriod());
+ $timecode = (int) floor(($timestamp - $this->getEpoch()) / $this->getPeriod());
+ assert($timecode >= 0);
+
+ return $timecode;
}
}
diff --git a/vendor/spomky-labs/otphp/src/TOTPInterface.php b/vendor/spomky-labs/otphp/src/TOTPInterface.php
index afb54e8e9..47ef16ac0 100644
--- a/vendor/spomky-labs/otphp/src/TOTPInterface.php
+++ b/vendor/spomky-labs/otphp/src/TOTPInterface.php
@@ -16,7 +16,9 @@ interface TOTPInterface extends OTPInterface
* If the secret is null, a random 64 bytes secret will be generated.
*
* @param null|non-empty-string $secret
+ * @param positive-int $period
* @param non-empty-string $digest
+ * @param positive-int $digits
*
* @deprecated Deprecated since v11.1, use ::createFromSecret or ::generate instead
*/
@@ -27,21 +29,37 @@ interface TOTPInterface extends OTPInterface
int $digits = self::DEFAULT_DIGITS
): self;
+ /**
+ * @param positive-int $period
+ */
public function setPeriod(int $period): void;
+ /**
+ * @param 0|positive-int $epoch
+ */
public function setEpoch(int $epoch): void;
/**
* Return the TOTP at the current time.
+ *
+ * @return non-empty-string
*/
public function now(): string;
/**
* Get the period of time for OTP generation (a non-null positive integer, in second).
+ *
+ * @return positive-int
*/
public function getPeriod(): int;
+ /**
+ * @return 0|positive-int
+ */
public function expiresIn(): int;
+ /**
+ * @return 0|positive-int
+ */
public function getEpoch(): int;
}
diff --git a/vendor/spomky-labs/otphp/src/Url.php b/vendor/spomky-labs/otphp/src/Url.php
index 56ad979c5..76919d27a 100644
--- a/vendor/spomky-labs/otphp/src/Url.php
+++ b/vendor/spomky-labs/otphp/src/Url.php
@@ -14,8 +14,11 @@ use function is_string;
final class Url
{
/**
+ * @param non-empty-string $scheme
+ * @param non-empty-string $host
+ * @param non-empty-string $path
* @param non-empty-string $secret
- * @param array<string, mixed> $query
+ * @param array<non-empty-string, mixed> $query
*/
public function __construct(
private readonly string $scheme,
@@ -26,16 +29,25 @@ final class Url
) {
}
+ /**
+ * @return non-empty-string
+ */
public function getScheme(): string
{
return $this->scheme;
}
+ /**
+ * @return non-empty-string
+ */
public function getHost(): string
{
return $this->host;
}
+ /**
+ * @return non-empty-string
+ */
public function getPath(): string
{
return $this->path;
@@ -50,13 +62,16 @@ final class Url
}
/**
- * @return array<string, mixed>
+ * @return array<non-empty-string, mixed>
*/
public function getQuery(): array
{
return $this->query;
}
+ /**
+ * @param non-empty-string $uri
+ */
public static function fromString(string $uri): self
{
$parsed_url = parse_url($uri);