From 8391c5efb09ba958c25f8b6596f973a1e983bed8 Mon Sep 17 00:00:00 2001
From: Nicolas CARPi
Date: Sat, 25 Feb 2023 13:05:01 +0100
Subject: [PATCH 01/48] fix build badge and codeclimate badge
see: https://github.com/badges/shields/issues/8671
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 23800ce..05084f3 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
#  PHP library for Two Factor Authentication
-[](https://github.com/RobThree/TwoFactorAuth/actions?query=branch%3Amaster) [](https://packagist.org/packages/robthree/twofactorauth) [](LICENSE) [](https://packagist.org/packages/robthree/twofactorauth) [](https://codeclimate.com/github/RobThree/TwoFactorAuth) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6MB5M2SQLP636 "Keep me off the streets")
+[](https://github.com/RobThree/TwoFactorAuth/actions?query=branch%3Amaster) [](https://packagist.org/packages/robthree/twofactorauth) [](LICENSE) [](https://packagist.org/packages/robthree/twofactorauth) [](https://codeclimate.com/github/RobThree/TwoFactorAuth) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6MB5M2SQLP636 "Keep me off the streets")
PHP library for [two-factor (or multi-factor) authentication](http://en.wikipedia.org/wiki/Multi-factor_authentication) using [TOTP](http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) and [QR-codes](http://en.wikipedia.org/wiki/QR_code). Inspired by, based on but most importantly an *improvement* on '[PHPGangsta/GoogleAuthenticator](https://github.com/PHPGangsta/GoogleAuthenticator)'. There's a [.Net implementation](https://github.com/RobThree/TwoFactorAuth.Net) of this library as well.
From 04e26c99617ea69db0d080e44baad8aa8acc8236 Mon Sep 17 00:00:00 2001
From: Nicolas CARPi
Date: Sat, 25 Feb 2023 13:07:20 +0100
Subject: [PATCH 02/48] remove codeclimate badge because coverage is not
uploaded there anyway
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 05084f3..8e9fbd0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
#  PHP library for Two Factor Authentication
-[](https://github.com/RobThree/TwoFactorAuth/actions?query=branch%3Amaster) [](https://packagist.org/packages/robthree/twofactorauth) [](LICENSE) [](https://packagist.org/packages/robthree/twofactorauth) [](https://codeclimate.com/github/RobThree/TwoFactorAuth) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6MB5M2SQLP636 "Keep me off the streets")
+[](https://github.com/RobThree/TwoFactorAuth/actions?query=branch%3Amaster) [](https://packagist.org/packages/robthree/twofactorauth) [](LICENSE) [](https://packagist.org/packages/robthree/twofactorauth) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6MB5M2SQLP636 "Keep me off the streets")
PHP library for [two-factor (or multi-factor) authentication](http://en.wikipedia.org/wiki/Multi-factor_authentication) using [TOTP](http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm) and [QR-codes](http://en.wikipedia.org/wiki/QR_code). Inspired by, based on but most importantly an *improvement* on '[PHPGangsta/GoogleAuthenticator](https://github.com/PHPGangsta/GoogleAuthenticator)'. There's a [.Net implementation](https://github.com/RobThree/TwoFactorAuth.Net) of this library as well.
From 6e71f43bb165e3c3b58cd36530c8c8e88744e0ca Mon Sep 17 00:00:00 2001
From: RMEngels
Date: Mon, 24 Apr 2023 15:32:40 +0200
Subject: [PATCH 03/48] Add warning of default QR Code provider to README.md
---
README.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/README.md b/README.md
index 8e9fbd0..96f566d 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,13 @@ PHP library for [two-factor (or multi-factor) authentication](http://en.wikipedi
+## Warning:
+
+By default, this package uses the `lib/Providers/QRServerProvider.php` as QR code generator. This provider is __not__ suggested for applications where absolute security is needed, because it uses an external service for the QR code generation.
+
+
+You can make use of the included [Endroid](https://robthree.github.io/TwoFactorAuth/qr-codes/endroid.html) or [Bacon](https://robthree.github.io/TwoFactorAuth/qr-codes/bacon.html) providers which generate locally.
+
## Requirements
* Requires PHP version >=8.1
From 098dce67354809c98036b637bf0ecf81519cfa6b Mon Sep 17 00:00:00 2001
From: William Hall
Date: Sun, 30 Apr 2023 14:36:00 +0100
Subject: [PATCH 04/48] =?UTF-8?q?=F0=9F=93=9A=20duplicate=20default=20prov?=
=?UTF-8?q?ider=20warning=20into=20docs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/qr-codes.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docs/qr-codes.md b/docs/qr-codes.md
index 01e8dad..5bd3490 100644
--- a/docs/qr-codes.md
+++ b/docs/qr-codes.md
@@ -22,6 +22,8 @@ You can also specify a size as a third argument which is 200 by default.
[QRServerProvider](qr-codes/qr-server.html) (default)
+**Warning:** Whilst it is the default, this provider is not suggested for applications where absolute security is needed, because it uses an external service for the QR code generation. You can make use of the included offline providers listed below which generate locally.
+
[ImageChartsQRCodeProvider](qr-codes/image-charts.html)
[QRicketProvider](qr-codes/qrickit.html)
From dfb5c1a113faf90ca70f57936b0a8870d3c30409 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:04:08 +0200
Subject: [PATCH 05/48] make $borderWidth readonly
---
lib/Providers/Qr/BaconQrCodeProvider.php | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/lib/Providers/Qr/BaconQrCodeProvider.php b/lib/Providers/Qr/BaconQrCodeProvider.php
index 2660e71..1a54dec 100644
--- a/lib/Providers/Qr/BaconQrCodeProvider.php
+++ b/lib/Providers/Qr/BaconQrCodeProvider.php
@@ -10,7 +10,6 @@
use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
use BaconQrCode\Renderer\ImageRenderer;
-
use BaconQrCode\Renderer\RendererStyle\EyeFill;
use BaconQrCode\Renderer\RendererStyle\Fill;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
@@ -23,10 +22,10 @@ class BaconQrCodeProvider implements IQRCodeProvider
* Ensure we using the latest Bacon QR Code and specify default options
*/
public function __construct(
- private int $borderWidth = 4,
+ private readonly int $borderWidth = 4,
private string|array $backgroundColour = '#ffffff',
private string|array $foregroundColour = '#000000',
- private string $format = 'png',
+ private string $format = 'png',
) {
$this->backgroundColour = $this->handleColour($this->backgroundColour);
$this->foregroundColour = $this->handleColour($this->foregroundColour);
From cc9400d9014b96f96bc199364a53abc44923d947 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:05:58 +0200
Subject: [PATCH 06/48] fix possible typo in parameter name
Interface's method signature:
```php
public function getQRCodeImage(string $qrtext, int $size): string;
```
---
lib/Providers/Qr/BaconQrCodeProvider.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Providers/Qr/BaconQrCodeProvider.php b/lib/Providers/Qr/BaconQrCodeProvider.php
index 1a54dec..b58841d 100644
--- a/lib/Providers/Qr/BaconQrCodeProvider.php
+++ b/lib/Providers/Qr/BaconQrCodeProvider.php
@@ -51,7 +51,7 @@ public function getMimeType(): string
throw new RuntimeException(sprintf('Unknown MIME-type: %s', $this->format));
}
- public function getQRCodeImage(string $qrText, int $size): string
+ public function getQRCodeImage(string $qrtext, int $size): string
{
switch ($this->format) {
case 'svg':
@@ -64,7 +64,7 @@ public function getQRCodeImage(string $qrText, int $size): string
$backend = new ImagickImageBackEnd($this->format);
}
- $output = $this->getQRCodeByBackend($qrText, $size, $backend);
+ $output = $this->getQRCodeByBackend($qrtext, $size, $backend);
if ($this->format == 'svg') {
$svg = explode("\n", $output);
From 9523b35d34ddd0d50f400f4118976c06bc669a2d Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:06:37 +0200
Subject: [PATCH 07/48] use strict comparison
---
lib/Providers/Qr/BaconQrCodeProvider.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Providers/Qr/BaconQrCodeProvider.php b/lib/Providers/Qr/BaconQrCodeProvider.php
index b58841d..e7305c8 100644
--- a/lib/Providers/Qr/BaconQrCodeProvider.php
+++ b/lib/Providers/Qr/BaconQrCodeProvider.php
@@ -66,7 +66,7 @@ public function getQRCodeImage(string $qrtext, int $size): string
$output = $this->getQRCodeByBackend($qrtext, $size, $backend);
- if ($this->format == 'svg') {
+ if ($this->format === 'svg') {
$svg = explode("\n", $output);
return $svg[1];
}
From 4c8a88224a5b432ad60673dc64e8bbb57bf3da85 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:14:33 +0200
Subject: [PATCH 08/48] replace switch with match
---
lib/Providers/Qr/BaconQrCodeProvider.php | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/lib/Providers/Qr/BaconQrCodeProvider.php b/lib/Providers/Qr/BaconQrCodeProvider.php
index e7305c8..7dc2313 100644
--- a/lib/Providers/Qr/BaconQrCodeProvider.php
+++ b/lib/Providers/Qr/BaconQrCodeProvider.php
@@ -53,16 +53,11 @@ public function getMimeType(): string
public function getQRCodeImage(string $qrtext, int $size): string
{
- switch ($this->format) {
- case 'svg':
- $backend = new SvgImageBackEnd();
- break;
- case 'eps':
- $backend = new EpsImageBackEnd();
- break;
- default:
- $backend = new ImagickImageBackEnd($this->format);
- }
+ $backend = match ($this->format) {
+ 'svg' => new SvgImageBackEnd(),
+ 'eps' => new EpsImageBackEnd(),
+ default => new ImagickImageBackEnd($this->format),
+ };
$output = $this->getQRCodeByBackend($qrtext, $size, $backend);
From 9a1aeb8c1fda5cfd17671936d9d1f3d1d75681a0 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:19:48 +0200
Subject: [PATCH 09/48] fix formatting
---
lib/Providers/Qr/QRicketProvider.php | 2 +-
lib/Providers/Time/HttpTimeProvider.php | 4 ++--
lib/Providers/Time/NTPTimeProvider.php | 2 +-
lib/TwoFactorAuth.php | 18 +++++++++---------
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/lib/Providers/Qr/QRicketProvider.php b/lib/Providers/Qr/QRicketProvider.php
index f72463d..8f4a7f7 100644
--- a/lib/Providers/Qr/QRicketProvider.php
+++ b/lib/Providers/Qr/QRicketProvider.php
@@ -35,7 +35,7 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
return 'http://qrickit.com/api/qr'
- . '?qrsize=' . (string) $size
+ . '?qrsize=' . (string)$size
. '&e=' . strtolower($this->errorcorrectionlevel)
. '&bgdcolor=' . $this->bgcolor
. '&fgdcolor=' . $this->color
diff --git a/lib/Providers/Time/HttpTimeProvider.php b/lib/Providers/Time/HttpTimeProvider.php
index 4131fee..ae72ce0 100644
--- a/lib/Providers/Time/HttpTimeProvider.php
+++ b/lib/Providers/Time/HttpTimeProvider.php
@@ -21,7 +21,7 @@ class HttpTimeProvider implements ITimeProvider
public function __construct(
public string $url = 'https://google.com',
public string $expectedtimeformat = 'D, d M Y H:i:s O+',
- array $options = null,
+ array $options = null,
) {
$this->url = $url;
$this->expectedtimeformat = $expectedtimeformat;
@@ -50,7 +50,7 @@ public function __construct(
public function getTime()
{
try {
- $context = stream_context_create($this->options);
+ $context = stream_context_create($this->options);
$fd = fopen($this->url, 'rb', false, $context);
$headers = stream_get_meta_data($fd);
fclose($fd);
diff --git a/lib/Providers/Time/NTPTimeProvider.php b/lib/Providers/Time/NTPTimeProvider.php
index 20db712..f1db3a3 100644
--- a/lib/Providers/Time/NTPTimeProvider.php
+++ b/lib/Providers/Time/NTPTimeProvider.php
@@ -47,7 +47,7 @@ public function getTime()
// Interpret response
$data = unpack('N12', $recv);
- $timestamp = (int) sprintf('%u', $data[9]);
+ $timestamp = (int)sprintf('%u', $data[9]);
// NTP is number of seconds since 0000 UT on 1 January 1900 Unix time is seconds since 0000 UT on 1 January 1970
return $timestamp - 2208988800;
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index ab9ee4b..8098c85 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -28,13 +28,13 @@ class TwoFactorAuth
private static array $_base32lookup = array();
public function __construct(
- private ?string $issuer = null,
- private int $digits = 6,
- private int $period = 30,
- private Algorithm $algorithm = Algorithm::Sha1,
+ private ?string $issuer = null,
+ private int $digits = 6,
+ private int $period = 30,
+ private Algorithm $algorithm = Algorithm::Sha1,
private ?IQRCodeProvider $qrcodeprovider = null,
- private ?IRNGProvider $rngprovider = null,
- private ?ITimeProvider $timeprovider = null
+ private ?IRNGProvider $rngprovider = null,
+ private ?ITimeProvider $timeprovider = null
) {
if ($this->digits <= 0) {
throw new TwoFactorAuthException('Digits must be > 0');
@@ -54,7 +54,7 @@ public function __construct(
public function createSecret(int $bits = 80, bool $requirecryptosecure = true): string
{
$secret = '';
- $bytes = (int) ceil($bits / 5); // We use 5 bits of each byte (since we have a 32-character 'alphabet' / BASE32)
+ $bytes = (int)ceil($bits / 5); // We use 5 bits of each byte (since we have a 32-character 'alphabet' / BASE32)
$rngprovider = $this->getRngProvider();
if ($requirecryptosecure && !$rngprovider->isCryptographicallySecure()) {
throw new TwoFactorAuthException('RNG provider is not cryptographically secure');
@@ -79,7 +79,7 @@ public function getCode(string $secret, ?int $time = null): string
$value = unpack('N', $hashpart); // Unpack binary value
$value = $value[1] & 0x7FFFFFFF; // Drop MSB, keep only 31 bits
- return str_pad((string) ($value % 10** $this->digits), $this->digits, '0', STR_PAD_LEFT);
+ return str_pad((string)($value % 10 ** $this->digits), $this->digits, '0', STR_PAD_LEFT);
}
/**
@@ -233,7 +233,7 @@ private function getTime(?int $time = null): int
private function getTimeSlice(?int $time = null, int $offset = 0): int
{
- return (int) floor($time / $this->period) + ($offset * $this->period);
+ return (int)floor($time / $this->period) + ($offset * $this->period);
}
private function base32Decode(string $value): string
From aadc32e85e4c554c0f0380871c3705c5c2f12ce6 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:21:36 +0200
Subject: [PATCH 10/48] make parameter explicitly nullable
---
lib/Providers/Time/HttpTimeProvider.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Providers/Time/HttpTimeProvider.php b/lib/Providers/Time/HttpTimeProvider.php
index ae72ce0..1d70ecf 100644
--- a/lib/Providers/Time/HttpTimeProvider.php
+++ b/lib/Providers/Time/HttpTimeProvider.php
@@ -21,7 +21,7 @@ class HttpTimeProvider implements ITimeProvider
public function __construct(
public string $url = 'https://google.com',
public string $expectedtimeformat = 'D, d M Y H:i:s O+',
- array $options = null,
+ array|null $options = null,
) {
$this->url = $url;
$this->expectedtimeformat = $expectedtimeformat;
From 1ca305ec4a320c42429032c339bf6732c6a8e26b Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:41:16 +0200
Subject: [PATCH 11/48] use spread syntax instead of array_merge
---
lib/Providers/Qr/BaconQrCodeProvider.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Providers/Qr/BaconQrCodeProvider.php b/lib/Providers/Qr/BaconQrCodeProvider.php
index 7dc2313..5ddbca6 100644
--- a/lib/Providers/Qr/BaconQrCodeProvider.php
+++ b/lib/Providers/Qr/BaconQrCodeProvider.php
@@ -78,7 +78,7 @@ private function getQRCodeByBackend($qrText, $size, ImageBackEndInterface $backe
$rendererStyleArgs = array($size, $this->borderWidth);
if (is_array($this->foregroundColour) && is_array($this->backgroundColour)) {
- $rendererStyleArgs = array_merge($rendererStyleArgs, array(
+ $rendererStyleArgs = array(...$rendererStyleArgs, ...array(
null,
null,
Fill::withForegroundColor(
From 7675282f454d90e171dbe0136402ae45602cf9b7 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:41:37 +0200
Subject: [PATCH 12/48] put scalar types to the right
---
lib/TwoFactorAuth.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index 8098c85..eccd258 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -168,7 +168,7 @@ public function getQRText(string $label, string $secret): string
public function getQrCodeProvider(): IQRCodeProvider
{
// Set default QR Code provider if none was specified
- if (null === $this->qrcodeprovider) {
+ if ($this->qrcodeprovider === null) {
return $this->qrcodeprovider = new QRServerProvider();
}
return $this->qrcodeprovider;
@@ -179,7 +179,7 @@ public function getQrCodeProvider(): IQRCodeProvider
*/
public function getRngProvider(): IRNGProvider
{
- if (null !== $this->rngprovider) {
+ if ($this->rngprovider !== null) {
return $this->rngprovider;
}
if (function_exists('random_bytes')) {
@@ -200,7 +200,7 @@ public function getRngProvider(): IRNGProvider
public function getTimeProvider(): ITimeProvider
{
// Set default time provider if none was specified
- if (null === $this->timeprovider) {
+ if ($this->timeprovider === null) {
return $this->timeprovider = new LocalMachineTimeProvider();
}
return $this->timeprovider;
From bdfa67d1f6a8464c8bc3897f46540c982241de19 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 20:42:40 +0200
Subject: [PATCH 13/48] use static keyword for anonymous function definition
---
lib/Providers/Qr/BaconQrCodeProvider.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Providers/Qr/BaconQrCodeProvider.php b/lib/Providers/Qr/BaconQrCodeProvider.php
index 5ddbca6..089ad0b 100644
--- a/lib/Providers/Qr/BaconQrCodeProvider.php
+++ b/lib/Providers/Qr/BaconQrCodeProvider.php
@@ -106,7 +106,7 @@ private function getQRCodeByBackend($qrText, $size, ImageBackEndInterface $backe
private function handleColour(array|string $colour): array|string
{
if (is_string($colour) && $colour[0] == '#') {
- $hexToRGB = function ($input) {
+ $hexToRGB = static function ($input) {
// ensure input no longer has a # for more predictable division
// PHP 8.1 does not like implicitly casting a float to an int
$input = trim($input, '#');
@@ -120,7 +120,7 @@ private function handleColour(array|string $colour): array|string
// cope with three character hex reference
if (strlen($input) == 3) {
- array_walk($split, function (&$character) {
+ array_walk($split, static function (&$character) {
$character = str_repeat($character, 2);
});
}
From c45f7a23c923e5cb52fb6fcb3d815c079f9dfc70 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:01:46 +0200
Subject: [PATCH 14/48] fix return types for v3, replace switch with match
---
lib/Providers/Qr/EndroidQrCodeProvider.php | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/lib/Providers/Qr/EndroidQrCodeProvider.php b/lib/Providers/Qr/EndroidQrCodeProvider.php
index 982b4f9..f6aacd4 100755
--- a/lib/Providers/Qr/EndroidQrCodeProvider.php
+++ b/lib/Providers/Qr/EndroidQrCodeProvider.php
@@ -64,7 +64,7 @@ protected function qrCodeInstance(string $qrtext, int $size): QrCode
return $qrCode;
}
- private function handleColor(string $color): Color
+ private function handleColor(string $color): Color|array
{
$split = str_split($color, 2);
$r = hexdec($split[0]);
@@ -74,18 +74,13 @@ private function handleColor(string $color): Color
return $this->endroid4 ? new Color($r, $g, $b, 0) : array('r' => $r, 'g' => $g, 'b' => $b, 'a' => 0);
}
- private function handleErrorCorrectionLevel(string $level): ErrorCorrectionLevelInterface
+ private function handleErrorCorrectionLevel(string $level): ErrorCorrectionLevelInterface|ErrorCorrectionLevel
{
- switch ($level) {
- case 'L':
- return $this->endroid4 ? new ErrorCorrectionLevelLow() : ErrorCorrectionLevel::LOW();
- case 'M':
- return $this->endroid4 ? new ErrorCorrectionLevelMedium() : ErrorCorrectionLevel::MEDIUM();
- case 'Q':
- return $this->endroid4 ? new ErrorCorrectionLevelQuartile() : ErrorCorrectionLevel::QUARTILE();
- case 'H':
- default:
- return $this->endroid4 ? new ErrorCorrectionLevelHigh() : ErrorCorrectionLevel::HIGH();
- }
+ return match ($level) {
+ 'L' => $this->endroid4 ? new ErrorCorrectionLevelLow() : ErrorCorrectionLevel::LOW(),
+ 'M' => $this->endroid4 ? new ErrorCorrectionLevelMedium() : ErrorCorrectionLevel::MEDIUM(),
+ 'Q' => $this->endroid4 ? new ErrorCorrectionLevelQuartile() : ErrorCorrectionLevel::QUARTILE(),
+ default => $this->endroid4 ? new ErrorCorrectionLevelHigh() : ErrorCorrectionLevel::HIGH(),
+ };
}
}
From 3adb3e54e52e06a65a265965b05422ff3632cfcf Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:13:02 +0200
Subject: [PATCH 15/48] add missing delimiter for proper escaping
---
lib/TwoFactorAuth.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index eccd258..a9820d1 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -242,7 +242,7 @@ private function base32Decode(string $value): string
return '';
}
- if (preg_match('/[^' . preg_quote(self::$_base32dict) . ']/', $value) !== 0) {
+ if (preg_match('/[^' . preg_quote(self::$_base32dict, '/') . ']/', $value) !== 0) {
throw new TwoFactorAuthException('Invalid base32 string');
}
From 26413e69f0f7574af5c2b5f5e69c91161df0a85f Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:14:31 +0200
Subject: [PATCH 16/48] extract strlen check from loop
---
lib/TwoFactorAuth.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index a9820d1..0c7534d 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -218,7 +218,8 @@ private function codeEquals(string $safe, string $user): bool
// we don't leak information about the difference of the two strings.
if (strlen($safe) === strlen($user)) {
$result = 0;
- for ($i = 0; $i < strlen($safe); $i++) {
+ $strlen = strlen($safe);
+ for ($i = 0; $i < $strlen; $i++) {
$result |= (ord($safe[$i]) ^ ord($user[$i]));
}
return $result === 0;
From 2fd60fad5eda3668fe9d733f458023ccdf394fb1 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:15:11 +0200
Subject: [PATCH 17/48] use type safe asserts
---
testsDependency/BaconQRCodeTest.php | 2 +-
testsDependency/EndroidQRCodeTest.php | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/testsDependency/BaconQRCodeTest.php b/testsDependency/BaconQRCodeTest.php
index 4c224c9..2a23061 100644
--- a/testsDependency/BaconQRCodeTest.php
+++ b/testsDependency/BaconQRCodeTest.php
@@ -22,7 +22,7 @@ public function testDependency(): void
$tfa = new TwoFactorAuth('Test&Issuer', 6, 30, Algorithm::Sha1, $qr);
$data = $this->DecodeDataUri($tfa->getQRCodeImageAsDataUri('Test&Label', 'VMR466AB62ZBOKHE'));
- $this->assertEquals('image/svg+xml', $data['mimetype']);
+ $this->assertSame('image/svg+xml', $data['mimetype']);
}
public function testBadTextColour(): void
diff --git a/testsDependency/EndroidQRCodeTest.php b/testsDependency/EndroidQRCodeTest.php
index 4b84dd2..6bd59fe 100644
--- a/testsDependency/EndroidQRCodeTest.php
+++ b/testsDependency/EndroidQRCodeTest.php
@@ -19,8 +19,8 @@ public function testDependency(): void
$qr = new EndroidQrCodeProvider();
$tfa = new TwoFactorAuth('Test&Issuer', 6, 30, Algorithm::Sha1, $qr);
$data = $this->DecodeDataUri($tfa->getQRCodeImageAsDataUri('Test&Label', 'VMR466AB62ZBOKHE'));
- $this->assertEquals('image/png', $data['mimetype']);
- $this->assertEquals('base64', $data['encoding']);
+ $this->assertSame('image/png', $data['mimetype']);
+ $this->assertSame('base64', $data['encoding']);
$this->assertNotEmpty($data['data']);
}
}
From 8bf880052335115bc76f249672ebe68c184c2c09 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:18:06 +0200
Subject: [PATCH 18/48] use empty string comparison instead of strlen call
---
lib/TwoFactorAuth.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index 0c7534d..88ea174 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -239,7 +239,7 @@ private function getTimeSlice(?int $time = null, int $offset = 0): int
private function base32Decode(string $value): string
{
- if (strlen($value) == 0) {
+ if ($value === '') {
return '';
}
From 5949a29b89190653ae7b9a0428f43c0008b1e401 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:18:20 +0200
Subject: [PATCH 19/48] use null coalescing operator instead of if checks
---
lib/TwoFactorAuth.php | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index 88ea174..14573ab 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -168,10 +168,7 @@ public function getQRText(string $label, string $secret): string
public function getQrCodeProvider(): IQRCodeProvider
{
// Set default QR Code provider if none was specified
- if ($this->qrcodeprovider === null) {
- return $this->qrcodeprovider = new QRServerProvider();
- }
- return $this->qrcodeprovider;
+ return $this->qrcodeprovider ?? ($this->qrcodeprovider = new QRServerProvider());
}
/**
@@ -200,10 +197,7 @@ public function getRngProvider(): IRNGProvider
public function getTimeProvider(): ITimeProvider
{
// Set default time provider if none was specified
- if ($this->timeprovider === null) {
- return $this->timeprovider = new LocalMachineTimeProvider();
- }
- return $this->timeprovider;
+ return $this->timeprovider ?? ($this->timeprovider = new LocalMachineTimeProvider());
}
/**
@@ -229,7 +223,7 @@ private function codeEquals(string $safe, string $user): bool
private function getTime(?int $time = null): int
{
- return ($time === null) ? $this->getTimeProvider()->getTime() : $time;
+ return $time ?? $this->getTimeProvider()->getTime();
}
private function getTimeSlice(?int $time = null, int $offset = 0): int
From e584f0c56a3a0079ac37dd7eddc01cb5c64c5a23 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:29:26 +0200
Subject: [PATCH 20/48] remove unnecessary type casts
---
lib/Providers/Qr/QRicketProvider.php | 2 +-
lib/TwoFactorAuth.php | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/Providers/Qr/QRicketProvider.php b/lib/Providers/Qr/QRicketProvider.php
index 8f4a7f7..65fc42d 100644
--- a/lib/Providers/Qr/QRicketProvider.php
+++ b/lib/Providers/Qr/QRicketProvider.php
@@ -35,7 +35,7 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
return 'http://qrickit.com/api/qr'
- . '?qrsize=' . (string)$size
+ . '?qrsize=' . $size
. '&e=' . strtolower($this->errorcorrectionlevel)
. '&bgdcolor=' . $this->bgcolor
. '&fgdcolor=' . $this->color
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index 14573ab..d9e0d6f 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -157,9 +157,9 @@ public function getQRText(string $label, string $secret): string
return 'otpauth://totp/' . rawurlencode($label)
. '?secret=' . rawurlencode($secret)
. '&issuer=' . rawurlencode((string)$this->issuer)
- . '&period=' . intval($this->period)
+ . '&period=' . $this->period
. '&algorithm=' . rawurlencode(strtoupper($this->algorithm->value))
- . '&digits=' . intval($this->digits);
+ . '&digits=' . $this->digits;
}
/**
From 955ce522f0decb04b812cdb954a4864f023b3b21 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:33:54 +0200
Subject: [PATCH 21/48] add readonly modifiers wherever possible
---
lib/Providers/Rng/HashRNGProvider.php | 2 +-
lib/Providers/Rng/OpenSSLRNGProvider.php | 2 +-
lib/TwoFactorAuth.php | 14 +++++++-------
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/lib/Providers/Rng/HashRNGProvider.php b/lib/Providers/Rng/HashRNGProvider.php
index 6d29755..20241da 100644
--- a/lib/Providers/Rng/HashRNGProvider.php
+++ b/lib/Providers/Rng/HashRNGProvider.php
@@ -8,7 +8,7 @@
class HashRNGProvider implements IRNGProvider
{
- public function __construct(private string $algorithm = 'sha256')
+ public function __construct(private readonly string $algorithm = 'sha256')
{
$algos = array_values(hash_algos());
if (!in_array($this->algorithm, $algos, true)) {
diff --git a/lib/Providers/Rng/OpenSSLRNGProvider.php b/lib/Providers/Rng/OpenSSLRNGProvider.php
index ef2aeb1..4063847 100644
--- a/lib/Providers/Rng/OpenSSLRNGProvider.php
+++ b/lib/Providers/Rng/OpenSSLRNGProvider.php
@@ -6,7 +6,7 @@
class OpenSSLRNGProvider implements IRNGProvider
{
- public function __construct(private bool $requirestrong = true)
+ public function __construct(private readonly bool $requirestrong = true)
{
}
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index d9e0d6f..2cd3c97 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -28,13 +28,13 @@ class TwoFactorAuth
private static array $_base32lookup = array();
public function __construct(
- private ?string $issuer = null,
- private int $digits = 6,
- private int $period = 30,
- private Algorithm $algorithm = Algorithm::Sha1,
- private ?IQRCodeProvider $qrcodeprovider = null,
- private ?IRNGProvider $rngprovider = null,
- private ?ITimeProvider $timeprovider = null
+ private readonly ?string $issuer = null,
+ private readonly int $digits = 6,
+ private readonly int $period = 30,
+ private readonly Algorithm $algorithm = Algorithm::Sha1,
+ private ?IQRCodeProvider $qrcodeprovider = null,
+ private ?IRNGProvider $rngprovider = null,
+ private ?ITimeProvider $timeprovider = null
) {
if ($this->digits <= 0) {
throw new TwoFactorAuthException('Digits must be > 0');
From d94ee9c7698675b53e381dd92a0469ee82ab1b25 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:36:04 +0200
Subject: [PATCH 22/48] remove useless @throws because it never throws
---
lib/TwoFactorAuth.php | 6 ------
1 file changed, 6 deletions(-)
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index 2cd3c97..3eef3e4 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -162,9 +162,6 @@ public function getQRText(string $label, string $secret): string
. '&digits=' . $this->digits;
}
- /**
- * @throws TwoFactorAuthException
- */
public function getQrCodeProvider(): IQRCodeProvider
{
// Set default QR Code provider if none was specified
@@ -191,9 +188,6 @@ public function getRngProvider(): IRNGProvider
throw new TwoFactorAuthException('Unable to find a suited RNGProvider');
}
- /**
- * @throws TwoFactorAuthException
- */
public function getTimeProvider(): ITimeProvider
{
// Set default time provider if none was specified
From 04ff3e7e3fe36dbeaa59083b02f2d66f072d39c5 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:37:44 +0200
Subject: [PATCH 23/48] fix nullable return type hint
---
lib/Providers/Qr/HandlesDataUri.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Providers/Qr/HandlesDataUri.php b/lib/Providers/Qr/HandlesDataUri.php
index 7ca425d..8b07845 100644
--- a/lib/Providers/Qr/HandlesDataUri.php
+++ b/lib/Providers/Qr/HandlesDataUri.php
@@ -10,7 +10,7 @@
trait HandlesDataUri
{
/**
- * @return array
+ * @return array|null
*/
private function DecodeDataUri(string $datauri): ?array
{
From d4f6aa1ee653ce049fa3777bbc40bf0f08949e4e Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:41:10 +0200
Subject: [PATCH 24/48] add missing @throws tag
---
lib/TwoFactorAuth.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index 3eef3e4..f6c68d1 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -123,6 +123,7 @@ public function getQRCodeImageAsDataUri(string $label, string $secret, int $size
/**
* Compare default timeprovider with specified timeproviders and ensure the time is within the specified number of seconds (leniency)
* @param array $timeproviders
+ * @throws TwoFactorAuthException
*/
public function ensureCorrectTime(?array $timeproviders = null, int $leniency = 5): void
{
From ab51d16de71dc529fd5de0288a6ac3af16ec40fb Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:43:04 +0200
Subject: [PATCH 25/48] remove redundant assignment, use shorthard for nullable
type
---
lib/Providers/Time/HttpTimeProvider.php | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lib/Providers/Time/HttpTimeProvider.php b/lib/Providers/Time/HttpTimeProvider.php
index 1d70ecf..47058c5 100644
--- a/lib/Providers/Time/HttpTimeProvider.php
+++ b/lib/Providers/Time/HttpTimeProvider.php
@@ -21,10 +21,8 @@ class HttpTimeProvider implements ITimeProvider
public function __construct(
public string $url = 'https://google.com',
public string $expectedtimeformat = 'D, d M Y H:i:s O+',
- array|null $options = null,
+ ?array $options = null,
) {
- $this->url = $url;
- $this->expectedtimeformat = $expectedtimeformat;
if ($options === null) {
$options = array(
'http' => array(
From f542788673f881a231e9b420f43ef0c923753ba5 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 21:59:55 +0200
Subject: [PATCH 26/48] fix formatting
---
tests/TwoFactorAuthTest.php | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/tests/TwoFactorAuthTest.php b/tests/TwoFactorAuthTest.php
index c24eb69..b192116 100644
--- a/tests/TwoFactorAuthTest.php
+++ b/tests/TwoFactorAuthTest.php
@@ -7,6 +7,8 @@
use PHPUnit\Framework\TestCase;
use ReflectionMethod;
use RobThree\Auth\Algorithm;
+use RobThree\Auth\Providers\Time\HttpTimeProvider;
+use RobThree\Auth\Providers\Time\NTPTimeProvider;
use RobThree\Auth\TwoFactorAuth;
use RobThree\Auth\TwoFactorAuthException;
@@ -37,11 +39,11 @@ public function testEnsureAllTimeProvidersReturnCorrectTime(): void
{
$tfa = new TwoFactorAuth('Test', 6, 30, Algorithm::Sha1);
$tfa->ensureCorrectTime(array(
- new \RobThree\Auth\Providers\Time\NTPTimeProvider(), // Uses pool.ntp.org by default
+ new NTPTimeProvider(), // Uses pool.ntp.org by default
//new \RobThree\Auth\Providers\Time\NTPTimeProvider('time.google.com'), // Somehow time.google.com and time.windows.com make travis timeout??
- new \RobThree\Auth\Providers\Time\HttpTimeProvider(), // Uses google.com by default
+ new HttpTimeProvider(), // Uses google.com by default
//new \RobThree\Auth\Providers\Time\HttpTimeProvider('https://github.com'), // github.com will periodically report times that are off by more than 5 sec
- new \RobThree\Auth\Providers\Time\HttpTimeProvider('https://yahoo.com'),
+ new HttpTimeProvider('https://yahoo.com'),
));
$this->expectNotToPerformAssertions();
}
@@ -50,19 +52,19 @@ public function testVerifyCodeWorksCorrectly(): void
{
$tfa = new TwoFactorAuth('Test', 6, 30);
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847190));
- $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 29)); //Test discrepancy
- $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 30)); //Test discrepancy
- $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 - 1)); //Test discrepancy
+ $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 29)); //Test discrepancy
+ $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 30)); //Test discrepancy
+ $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 - 1)); //Test discrepancy
- $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 0)); //Test discrepancy
- $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 35)); //Test discrepancy
- $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 35)); //Test discrepancy
+ $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 0)); //Test discrepancy
+ $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 35)); //Test discrepancy
+ $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 35)); //Test discrepancy
- $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 65)); //Test discrepancy
- $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 65)); //Test discrepancy
+ $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 65)); //Test discrepancy
+ $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 65)); //Test discrepancy
- $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 + 65)); //Test discrepancy
- $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 - 65)); //Test discrepancy
+ $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 + 65)); //Test discrepancy
+ $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 - 65)); //Test discrepancy
}
public function testVerifyCorrectTimeSliceIsReturned(): void
From b80431341e74863c84fec383265727f5c599bcc7 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 22:00:11 +0200
Subject: [PATCH 27/48] remove pointless +0
---
tests/TwoFactorAuthTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/TwoFactorAuthTest.php b/tests/TwoFactorAuthTest.php
index b192116..33015c7 100644
--- a/tests/TwoFactorAuthTest.php
+++ b/tests/TwoFactorAuthTest.php
@@ -56,7 +56,7 @@ public function testVerifyCodeWorksCorrectly(): void
$this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 30)); //Test discrepancy
$this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 - 1)); //Test discrepancy
- $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 0)); //Test discrepancy
+ $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205)); //Test discrepancy
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 35)); //Test discrepancy
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 35)); //Test discrepancy
From 8bf962ecee0cf78247bb3563b8203bdb30cbbdb3 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 22:00:48 +0200
Subject: [PATCH 28/48] add readonly identifier
---
tests/Providers/Rng/TestRNGProvider.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Providers/Rng/TestRNGProvider.php b/tests/Providers/Rng/TestRNGProvider.php
index 78ceec1..c166c66 100644
--- a/tests/Providers/Rng/TestRNGProvider.php
+++ b/tests/Providers/Rng/TestRNGProvider.php
@@ -8,7 +8,7 @@
class TestRNGProvider implements IRNGProvider
{
- public function __construct(private bool $isSecure = false)
+ public function __construct(private readonly bool $isSecure = false)
{
}
From 3f3327e2a168e3848797f6ede7fbeeaa21837d1e Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 22:01:34 +0200
Subject: [PATCH 29/48] use type safe assertions
---
tests/Providers/Qr/IQRCodeProviderTest.php | 12 +--
tests/Providers/Rng/CSRNGProviderTest.php | 2 +-
tests/Providers/Rng/HashRNGProviderTest.php | 2 +-
tests/Providers/Rng/IRNGProviderTest.php | 16 ++--
.../Providers/Rng/OpenSSLRNGProviderTest.php | 4 +-
tests/TwoFactorAuthTest.php | 84 +++++++++----------
6 files changed, 60 insertions(+), 60 deletions(-)
diff --git a/tests/Providers/Qr/IQRCodeProviderTest.php b/tests/Providers/Qr/IQRCodeProviderTest.php
index bfab066..a9f7e82 100644
--- a/tests/Providers/Qr/IQRCodeProviderTest.php
+++ b/tests/Providers/Qr/IQRCodeProviderTest.php
@@ -20,9 +20,9 @@ public function testTotpUriIsCorrect(): void
$tfa = new TwoFactorAuth('Test&Issuer', 6, 30, Algorithm::Sha1, $qr);
$data = $this->DecodeDataUri($tfa->getQRCodeImageAsDataUri('Test&Label', 'VMR466AB62ZBOKHE'));
- $this->assertEquals('test/test', $data['mimetype']);
- $this->assertEquals('base64', $data['encoding']);
- $this->assertEquals('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=Test%26Issuer&period=30&algorithm=SHA1&digits=6@200', $data['data']);
+ $this->assertSame('test/test', $data['mimetype']);
+ $this->assertSame('base64', $data['encoding']);
+ $this->assertSame('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=Test%26Issuer&period=30&algorithm=SHA1&digits=6@200', $data['data']);
}
public function testTotpUriIsCorrectNoIssuer(): void
@@ -36,9 +36,9 @@ public function testTotpUriIsCorrectNoIssuer(): void
$tfa = new TwoFactorAuth(null, 6, 30, Algorithm::Sha1, $qr);
$data = $this->DecodeDataUri($tfa->getQRCodeImageAsDataUri('Test&Label', 'VMR466AB62ZBOKHE'));
- $this->assertEquals('test/test', $data['mimetype']);
- $this->assertEquals('base64', $data['encoding']);
- $this->assertEquals('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=&period=30&algorithm=SHA1&digits=6@200', $data['data']);
+ $this->assertSame('test/test', $data['mimetype']);
+ $this->assertSame('base64', $data['encoding']);
+ $this->assertSame('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=&period=30&algorithm=SHA1&digits=6@200', $data['data']);
}
public function testGetQRCodeImageAsDataUriThrowsOnInvalidSize(): void
diff --git a/tests/Providers/Rng/CSRNGProviderTest.php b/tests/Providers/Rng/CSRNGProviderTest.php
index 0d4898b..64f66e8 100644
--- a/tests/Providers/Rng/CSRNGProviderTest.php
+++ b/tests/Providers/Rng/CSRNGProviderTest.php
@@ -19,7 +19,7 @@ public function testCSRNGProvidersReturnExpectedNumberOfBytes(): void
if (function_exists('random_bytes')) {
$rng = new CSRNGProvider();
foreach ($this->rngTestLengths as $l) {
- $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+ $this->assertSame($l, strlen($rng->getRandomBytes($l)));
}
$this->assertTrue($rng->isCryptographicallySecure());
} else {
diff --git a/tests/Providers/Rng/HashRNGProviderTest.php b/tests/Providers/Rng/HashRNGProviderTest.php
index d54b9ae..4a71930 100644
--- a/tests/Providers/Rng/HashRNGProviderTest.php
+++ b/tests/Providers/Rng/HashRNGProviderTest.php
@@ -18,7 +18,7 @@ public function testHashRNGProvidersReturnExpectedNumberOfBytes()
{
$rng = new HashRNGProvider();
foreach ($this->rngTestLengths as $l) {
- $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+ $this->assertSame($l, strlen($rng->getRandomBytes($l)));
}
$this->assertFalse($rng->isCryptographicallySecure());
diff --git a/tests/Providers/Rng/IRNGProviderTest.php b/tests/Providers/Rng/IRNGProviderTest.php
index a55a56d..7ff40c8 100644
--- a/tests/Providers/Rng/IRNGProviderTest.php
+++ b/tests/Providers/Rng/IRNGProviderTest.php
@@ -26,7 +26,7 @@ public function testCreateSecretOverrideSecureDoesNotThrowOnInsecureRNG(): void
$rng = new TestRNGProvider();
$tfa = new TwoFactorAuth('Test', 6, 30, Algorithm::Sha1, null, $rng);
- $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false));
+ $this->assertSame('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false));
}
public function testCreateSecretDoesNotThrowOnSecureRNGProvider(): void
@@ -34,7 +34,7 @@ public function testCreateSecretDoesNotThrowOnSecureRNGProvider(): void
$rng = new TestRNGProvider(true);
$tfa = new TwoFactorAuth('Test', 6, 30, Algorithm::Sha1, null, $rng);
- $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret());
+ $this->assertSame('ABCDEFGHIJKLMNOP', $tfa->createSecret());
}
public function testCreateSecretGeneratesDesiredAmountOfEntropy(): void
@@ -42,11 +42,11 @@ public function testCreateSecretGeneratesDesiredAmountOfEntropy(): void
$rng = new TestRNGProvider(true);
$tfa = new TwoFactorAuth('Test', 6, 30, Algorithm::Sha1, null, $rng);
- $this->assertEquals('A', $tfa->createSecret(5));
- $this->assertEquals('AB', $tfa->createSecret(6));
- $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $tfa->createSecret(128));
- $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(160));
- $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(320));
- $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567A', $tfa->createSecret(321));
+ $this->assertSame('A', $tfa->createSecret(5));
+ $this->assertSame('AB', $tfa->createSecret(6));
+ $this->assertSame('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $tfa->createSecret(128));
+ $this->assertSame('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(160));
+ $this->assertSame('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(320));
+ $this->assertSame('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567A', $tfa->createSecret(321));
}
}
diff --git a/tests/Providers/Rng/OpenSSLRNGProviderTest.php b/tests/Providers/Rng/OpenSSLRNGProviderTest.php
index 18fdb29..368c7cc 100644
--- a/tests/Providers/Rng/OpenSSLRNGProviderTest.php
+++ b/tests/Providers/Rng/OpenSSLRNGProviderTest.php
@@ -18,7 +18,7 @@ public function testStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes()
{
$rng = new OpenSSLRNGProvider(true);
foreach ($this->rngTestLengths as $l) {
- $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+ $this->assertSame($l, strlen($rng->getRandomBytes($l)));
}
$this->assertTrue($rng->isCryptographicallySecure());
@@ -31,7 +31,7 @@ public function testNonStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes()
{
$rng = new OpenSSLRNGProvider(false);
foreach ($this->rngTestLengths as $l) {
- $this->assertEquals($l, strlen($rng->getRandomBytes($l)));
+ $this->assertSame($l, strlen($rng->getRandomBytes($l)));
}
$this->assertFalse($rng->isCryptographicallySecure());
diff --git a/tests/TwoFactorAuthTest.php b/tests/TwoFactorAuthTest.php
index 33015c7..1b1feca 100644
--- a/tests/TwoFactorAuthTest.php
+++ b/tests/TwoFactorAuthTest.php
@@ -31,8 +31,8 @@ public function testConstructorThrowsOnInvalidPeriod(): void
public function testGetCodeReturnsCorrectResults(): void
{
$tfa = new TwoFactorAuth('Test');
- $this->assertEquals('543160', $tfa->getCode('VMR466AB62ZBOKHE', 1426847216));
- $this->assertEquals('538532', $tfa->getCode('VMR466AB62ZBOKHE', 0));
+ $this->assertSame('543160', $tfa->getCode('VMR466AB62ZBOKHE', 1426847216));
+ $this->assertSame('538532', $tfa->getCode('VMR466AB62ZBOKHE', 0));
}
public function testEnsureAllTimeProvidersReturnCorrectTime(): void
@@ -74,23 +74,23 @@ public function testVerifyCorrectTimeSliceIsReturned(): void
// We test with discrepancy 3 (so total of 7 codes: c-3, c-2, c-1, c, c+1, c+2, c+3
// Ensure each corresponding timeslice is returned correctly
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '534113', 3, 1426847190, $timeslice1));
- $this->assertEquals(47561570, $timeslice1);
+ $this->assertSame(47561570, $timeslice1);
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '819652', 3, 1426847190, $timeslice2));
- $this->assertEquals(47561571, $timeslice2);
+ $this->assertSame(47561571, $timeslice2);
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '915954', 3, 1426847190, $timeslice3));
- $this->assertEquals(47561572, $timeslice3);
+ $this->assertSame(47561572, $timeslice3);
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 3, 1426847190, $timeslice4));
- $this->assertEquals(47561573, $timeslice4);
+ $this->assertSame(47561573, $timeslice4);
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '348401', 3, 1426847190, $timeslice5));
- $this->assertEquals(47561574, $timeslice5);
+ $this->assertSame(47561574, $timeslice5);
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '648525', 3, 1426847190, $timeslice6));
- $this->assertEquals(47561575, $timeslice6);
+ $this->assertSame(47561575, $timeslice6);
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '170645', 3, 1426847190, $timeslice7));
- $this->assertEquals(47561576, $timeslice7);
+ $this->assertSame(47561576, $timeslice7);
// Incorrect code should return false and a 0 timeslice
$this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '111111', 3, 1426847190, $timeslice8));
- $this->assertEquals(0, $timeslice8);
+ $this->assertSame(0, $timeslice8);
}
public function testGetCodeThrowsOnInvalidBase32String1(): void
@@ -130,13 +130,13 @@ public function testKnownBase32DecodeTestVectors(): void
$method->setAccessible(true);
// Test vectors from: https://tools.ietf.org/html/rfc4648#page-12
- $this->assertEquals('', $method->invoke($tfa, ''));
- $this->assertEquals('f', $method->invoke($tfa, 'MY======'));
- $this->assertEquals('fo', $method->invoke($tfa, 'MZXQ===='));
- $this->assertEquals('foo', $method->invoke($tfa, 'MZXW6==='));
- $this->assertEquals('foob', $method->invoke($tfa, 'MZXW6YQ='));
- $this->assertEquals('fooba', $method->invoke($tfa, 'MZXW6YTB'));
- $this->assertEquals('foobar', $method->invoke($tfa, 'MZXW6YTBOI======'));
+ $this->assertSame('', $method->invoke($tfa, ''));
+ $this->assertSame('f', $method->invoke($tfa, 'MY======'));
+ $this->assertSame('fo', $method->invoke($tfa, 'MZXQ===='));
+ $this->assertSame('foo', $method->invoke($tfa, 'MZXW6==='));
+ $this->assertSame('foob', $method->invoke($tfa, 'MZXW6YQ='));
+ $this->assertSame('fooba', $method->invoke($tfa, 'MZXW6YTB'));
+ $this->assertSame('foobar', $method->invoke($tfa, 'MZXW6YTBOI======'));
}
public function testKnownBase32DecodeUnpaddedTestVectors(): void
@@ -151,13 +151,13 @@ public function testKnownBase32DecodeUnpaddedTestVectors(): void
$method->setAccessible(true);
// Test vectors from: https://tools.ietf.org/html/rfc4648#page-12
- $this->assertEquals('', $method->invoke($tfa, ''));
- $this->assertEquals('f', $method->invoke($tfa, 'MY'));
- $this->assertEquals('fo', $method->invoke($tfa, 'MZXQ'));
- $this->assertEquals('foo', $method->invoke($tfa, 'MZXW6'));
- $this->assertEquals('foob', $method->invoke($tfa, 'MZXW6YQ'));
- $this->assertEquals('fooba', $method->invoke($tfa, 'MZXW6YTB'));
- $this->assertEquals('foobar', $method->invoke($tfa, 'MZXW6YTBOI'));
+ $this->assertSame('', $method->invoke($tfa, ''));
+ $this->assertSame('f', $method->invoke($tfa, 'MY'));
+ $this->assertSame('fo', $method->invoke($tfa, 'MZXQ'));
+ $this->assertSame('foo', $method->invoke($tfa, 'MZXW6'));
+ $this->assertSame('foob', $method->invoke($tfa, 'MZXW6YQ'));
+ $this->assertSame('fooba', $method->invoke($tfa, 'MZXW6YTB'));
+ $this->assertSame('foobar', $method->invoke($tfa, 'MZXW6YTBOI'));
}
public function testKnownTestVectors_sha1(): void
@@ -165,12 +165,12 @@ public function testKnownTestVectors_sha1(): void
//Known test vectors for SHA1: https://tools.ietf.org/html/rfc6238#page-15
$secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ'; //== base32encode('12345678901234567890')
$tfa = new TwoFactorAuth('Test', 8, 30, Algorithm::Sha1);
- $this->assertEquals('94287082', $tfa->getCode($secret, 59));
- $this->assertEquals('07081804', $tfa->getCode($secret, 1111111109));
- $this->assertEquals('14050471', $tfa->getCode($secret, 1111111111));
- $this->assertEquals('89005924', $tfa->getCode($secret, 1234567890));
- $this->assertEquals('69279037', $tfa->getCode($secret, 2000000000));
- $this->assertEquals('65353130', $tfa->getCode($secret, 20000000000));
+ $this->assertSame('94287082', $tfa->getCode($secret, 59));
+ $this->assertSame('07081804', $tfa->getCode($secret, 1111111109));
+ $this->assertSame('14050471', $tfa->getCode($secret, 1111111111));
+ $this->assertSame('89005924', $tfa->getCode($secret, 1234567890));
+ $this->assertSame('69279037', $tfa->getCode($secret, 2000000000));
+ $this->assertSame('65353130', $tfa->getCode($secret, 20000000000));
}
public function testKnownTestVectors_sha256(): void
@@ -178,12 +178,12 @@ public function testKnownTestVectors_sha256(): void
//Known test vectors for SHA256: https://tools.ietf.org/html/rfc6238#page-15
$secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZA'; //== base32encode('12345678901234567890123456789012')
$tfa = new TwoFactorAuth('Test', 8, 30, Algorithm::Sha256);
- $this->assertEquals('46119246', $tfa->getCode($secret, 59));
- $this->assertEquals('68084774', $tfa->getCode($secret, 1111111109));
- $this->assertEquals('67062674', $tfa->getCode($secret, 1111111111));
- $this->assertEquals('91819424', $tfa->getCode($secret, 1234567890));
- $this->assertEquals('90698825', $tfa->getCode($secret, 2000000000));
- $this->assertEquals('77737706', $tfa->getCode($secret, 20000000000));
+ $this->assertSame('46119246', $tfa->getCode($secret, 59));
+ $this->assertSame('68084774', $tfa->getCode($secret, 1111111109));
+ $this->assertSame('67062674', $tfa->getCode($secret, 1111111111));
+ $this->assertSame('91819424', $tfa->getCode($secret, 1234567890));
+ $this->assertSame('90698825', $tfa->getCode($secret, 2000000000));
+ $this->assertSame('77737706', $tfa->getCode($secret, 20000000000));
}
public function testKnownTestVectors_sha512(): void
@@ -191,11 +191,11 @@ public function testKnownTestVectors_sha512(): void
//Known test vectors for SHA512: https://tools.ietf.org/html/rfc6238#page-15
$secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNA'; //== base32encode('1234567890123456789012345678901234567890123456789012345678901234')
$tfa = new TwoFactorAuth('Test', 8, 30, Algorithm::Sha512);
- $this->assertEquals('90693936', $tfa->getCode($secret, 59));
- $this->assertEquals('25091201', $tfa->getCode($secret, 1111111109));
- $this->assertEquals('99943326', $tfa->getCode($secret, 1111111111));
- $this->assertEquals('93441116', $tfa->getCode($secret, 1234567890));
- $this->assertEquals('38618901', $tfa->getCode($secret, 2000000000));
- $this->assertEquals('47863826', $tfa->getCode($secret, 20000000000));
+ $this->assertSame('90693936', $tfa->getCode($secret, 59));
+ $this->assertSame('25091201', $tfa->getCode($secret, 1111111109));
+ $this->assertSame('99943326', $tfa->getCode($secret, 1111111111));
+ $this->assertSame('93441116', $tfa->getCode($secret, 1234567890));
+ $this->assertSame('38618901', $tfa->getCode($secret, 2000000000));
+ $this->assertSame('47863826', $tfa->getCode($secret, 20000000000));
}
}
From d60113a77a054a67162f30072e0c4d073d5d9aab Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sat, 27 May 2023 22:02:10 +0200
Subject: [PATCH 30/48] drop setAccessible calls as they its NOOP since PHP 8.1
---
tests/TwoFactorAuthTest.php | 2 --
1 file changed, 2 deletions(-)
diff --git a/tests/TwoFactorAuthTest.php b/tests/TwoFactorAuthTest.php
index 1b1feca..0fa9f11 100644
--- a/tests/TwoFactorAuthTest.php
+++ b/tests/TwoFactorAuthTest.php
@@ -127,7 +127,6 @@ public function testKnownBase32DecodeTestVectors(): void
$tfa = new TwoFactorAuth('Test');
$method = new ReflectionMethod(TwoFactorAuth::class, 'base32Decode');
- $method->setAccessible(true);
// Test vectors from: https://tools.ietf.org/html/rfc4648#page-12
$this->assertSame('', $method->invoke($tfa, ''));
@@ -148,7 +147,6 @@ public function testKnownBase32DecodeUnpaddedTestVectors(): void
$tfa = new TwoFactorAuth('Test');
$method = new ReflectionMethod(TwoFactorAuth::class, 'base32Decode');
- $method->setAccessible(true);
// Test vectors from: https://tools.ietf.org/html/rfc4648#page-12
$this->assertSame('', $method->invoke($tfa, ''));
From 4d91d6ae27e3b23d0af3be550956b8248a57ac5b Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sun, 28 May 2023 01:13:12 +0200
Subject: [PATCH 31/48] use sprintf instead of concatenating
---
.../Qr/GoogleChartsQrCodeProvider.php | 13 ++++++------
.../Qr/ImageChartsQRCodeProvider.php | 11 ++++++----
lib/Providers/Qr/QRServerProvider.php | 20 ++++++++++---------
lib/Providers/Qr/QRicketProvider.php | 16 ++++++++-------
4 files changed, 34 insertions(+), 26 deletions(-)
diff --git a/lib/Providers/Qr/GoogleChartsQrCodeProvider.php b/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
index fd59dff..60356cb 100644
--- a/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
+++ b/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
@@ -23,11 +23,12 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
- return 'https://chart.googleapis.com/chart'
- . '?chs=' . $size . 'x' . $size
- . '&chld=' . urlencode(strtoupper($this->errorcorrectionlevel) . '|' . $this->margin)
- . '&cht=' . 'qr'
- . '&choe=' . $this->encoding
- . '&chl=' . rawurlencode($qrtext);
+ return sprintf(
+ 'https://chart.googleapis.com/chart?chs=%1$sx%1$s&chld=%2$s&cht=qr&choe=%3$s&chl=%4$s',
+ $size,
+ urlencode(strtoupper($this->errorcorrectionlevel) . '|' . $this->margin),
+ $this->encoding,
+ rawurlencode($qrtext)
+ );
}
}
diff --git a/lib/Providers/Qr/ImageChartsQRCodeProvider.php b/lib/Providers/Qr/ImageChartsQRCodeProvider.php
index d62a96a..f6d972e 100644
--- a/lib/Providers/Qr/ImageChartsQRCodeProvider.php
+++ b/lib/Providers/Qr/ImageChartsQRCodeProvider.php
@@ -25,9 +25,12 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
- return 'https://image-charts.com/chart?cht=qr'
- . '&chs=' . ceil($size / 2) . 'x' . ceil($size / 2)
- . '&chld=' . $this->errorcorrectionlevel . '|' . $this->margin
- . '&chl=' . rawurlencode($qrtext);
+ return sprintf(
+ 'https://image-charts.com/chart?cht=qr&chs=%1$dx%1$d&chld=%2$s|%3$s&chl=%4$s',
+ ceil($size / 2),
+ $this->errorcorrectionlevel,
+ $this->margin,
+ rawurlencode($qrtext)
+ );
}
}
diff --git a/lib/Providers/Qr/QRServerProvider.php b/lib/Providers/Qr/QRServerProvider.php
index b223d91..c41b1dd 100644
--- a/lib/Providers/Qr/QRServerProvider.php
+++ b/lib/Providers/Qr/QRServerProvider.php
@@ -38,15 +38,17 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
- return 'https://api.qrserver.com/v1/create-qr-code/'
- . '?size=' . $size . 'x' . $size
- . '&ecc=' . strtoupper($this->errorcorrectionlevel)
- . '&margin=' . $this->margin
- . '&qzone=' . $this->qzone
- . '&bgcolor=' . $this->decodeColor($this->bgcolor)
- . '&color=' . $this->decodeColor($this->color)
- . '&format=' . strtolower($this->format)
- . '&data=' . rawurlencode($qrtext);
+ return sprintf(
+ 'https://api.qrserver.com/v1/create-qr-code/?size=%1$sx%1$s&ecc=%2$s&margin=%3$s&qzone=%4$s&bgcolor=%5$s&color=%6$s&format=%7$s&data=%8$s',
+ $size,
+ strtoupper($this->errorcorrectionlevel),
+ $this->margin,
+ $this->qzone,
+ $this->decodeColor($this->bgcolor),
+ $this->decodeColor($this->color),
+ strtolower($this->format),
+ rawurlencode($qrtext)
+ );
}
private function decodeColor(string $value): string
diff --git a/lib/Providers/Qr/QRicketProvider.php b/lib/Providers/Qr/QRicketProvider.php
index 65fc42d..fe19d28 100644
--- a/lib/Providers/Qr/QRicketProvider.php
+++ b/lib/Providers/Qr/QRicketProvider.php
@@ -34,12 +34,14 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
- return 'http://qrickit.com/api/qr'
- . '?qrsize=' . $size
- . '&e=' . strtolower($this->errorcorrectionlevel)
- . '&bgdcolor=' . $this->bgcolor
- . '&fgdcolor=' . $this->color
- . '&t=' . strtolower($this->format)
- . '&d=' . rawurlencode($qrtext);
+ return sprintf(
+ 'http://qrickit.com/api/qr?qrsize=%s&e=%s&bgdcolor=%s&fgdcolor=%s&t=%s&d=%s',
+ $size,
+ strtolower($this->errorcorrectionlevel),
+ $this->bgcolor,
+ $this->color,
+ strtolower($this->format),
+ rawurlencode($qrtext)
+ );
}
}
From cf84371dad11591b77b14c5dea5ac7c52a288b22 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sun, 28 May 2023 01:58:44 +0200
Subject: [PATCH 32/48] use http_build_query instead of sprintf to improve
readability
---
.../Qr/GoogleChartsQrCodeProvider.php | 14 +++++++------
.../Qr/ImageChartsQRCodeProvider.php | 13 ++++++------
lib/Providers/Qr/QRServerProvider.php | 21 ++++++++++---------
lib/Providers/Qr/QRicketProvider.php | 17 ++++++++-------
4 files changed, 35 insertions(+), 30 deletions(-)
diff --git a/lib/Providers/Qr/GoogleChartsQrCodeProvider.php b/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
index 60356cb..bbcb7ac 100644
--- a/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
+++ b/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
@@ -23,12 +23,14 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
- return sprintf(
- 'https://chart.googleapis.com/chart?chs=%1$sx%1$s&chld=%2$s&cht=qr&choe=%3$s&chl=%4$s',
- $size,
- urlencode(strtoupper($this->errorcorrectionlevel) . '|' . $this->margin),
- $this->encoding,
- rawurlencode($qrtext)
+ $queryParameters = array(
+ 'chs' => $size . 'x' . $size,
+ 'chld' => strtoupper($this->errorcorrectionlevel) . '|' . $this->margin,
+ 'cht' => 'qr',
+ 'choe' => $this->encoding,
+ 'chl' => $qrtext,
);
+
+ return 'https://chart.googleapis.com/chart?' . http_build_query($queryParameters);
}
}
diff --git a/lib/Providers/Qr/ImageChartsQRCodeProvider.php b/lib/Providers/Qr/ImageChartsQRCodeProvider.php
index f6d972e..6460e13 100644
--- a/lib/Providers/Qr/ImageChartsQRCodeProvider.php
+++ b/lib/Providers/Qr/ImageChartsQRCodeProvider.php
@@ -25,12 +25,13 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
- return sprintf(
- 'https://image-charts.com/chart?cht=qr&chs=%1$dx%1$d&chld=%2$s|%3$s&chl=%4$s',
- ceil($size / 2),
- $this->errorcorrectionlevel,
- $this->margin,
- rawurlencode($qrtext)
+ $queryParameters = array(
+ 'cht' => 'qr',
+ 'chs' => ceil($size / 2) . 'x' . ceil($size / 2),
+ 'chld' => $this->errorcorrectionlevel . '|' . $this->margin,
+ 'chl' => $qrtext,
);
+
+ return 'https://image-charts.com/chart?' . http_build_query($queryParameters);
}
}
diff --git a/lib/Providers/Qr/QRServerProvider.php b/lib/Providers/Qr/QRServerProvider.php
index c41b1dd..96cb3fd 100644
--- a/lib/Providers/Qr/QRServerProvider.php
+++ b/lib/Providers/Qr/QRServerProvider.php
@@ -38,17 +38,18 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
- return sprintf(
- 'https://api.qrserver.com/v1/create-qr-code/?size=%1$sx%1$s&ecc=%2$s&margin=%3$s&qzone=%4$s&bgcolor=%5$s&color=%6$s&format=%7$s&data=%8$s',
- $size,
- strtoupper($this->errorcorrectionlevel),
- $this->margin,
- $this->qzone,
- $this->decodeColor($this->bgcolor),
- $this->decodeColor($this->color),
- strtolower($this->format),
- rawurlencode($qrtext)
+ $queryParameters = array(
+ 'size' => $size . 'x' . $size,
+ 'ecc' => strtoupper($this->errorcorrectionlevel),
+ 'margin' => $this->margin,
+ 'qzone' => $this->qzone,
+ 'bgcolor' => $this->decodeColor($this->bgcolor),
+ 'color' => $this->decodeColor($this->color),
+ 'format' => strtolower($this->format),
+ 'data' => $qrtext,
);
+
+ return 'https://api.qrserver.com/v1/create-qr-code/?' . http_build_query($queryParameters);
}
private function decodeColor(string $value): string
diff --git a/lib/Providers/Qr/QRicketProvider.php b/lib/Providers/Qr/QRicketProvider.php
index fe19d28..a56088a 100644
--- a/lib/Providers/Qr/QRicketProvider.php
+++ b/lib/Providers/Qr/QRicketProvider.php
@@ -34,14 +34,15 @@ public function getQRCodeImage(string $qrtext, int $size): string
public function getUrl(string $qrtext, int $size): string
{
- return sprintf(
- 'http://qrickit.com/api/qr?qrsize=%s&e=%s&bgdcolor=%s&fgdcolor=%s&t=%s&d=%s',
- $size,
- strtolower($this->errorcorrectionlevel),
- $this->bgcolor,
- $this->color,
- strtolower($this->format),
- rawurlencode($qrtext)
+ $queryParameters = array(
+ 'qrsize' => $size,
+ 'e' => strtolower($this->errorcorrectionlevel),
+ 'bgdcolor' => $this->bgcolor,
+ 'fgdcolor' => $this->color,
+ 't' => strtolower($this->format),
+ 'd' => $qrtext,
);
+
+ return 'http://qrickit.com/api/qr?' . http_build_query($queryParameters);
}
}
From c2183e16b372bf7c3303d437f00a326ca964771e Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sun, 28 May 2023 18:46:07 +0200
Subject: [PATCH 33/48] use property promotion for options
---
lib/Providers/Time/HttpTimeProvider.php | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/lib/Providers/Time/HttpTimeProvider.php b/lib/Providers/Time/HttpTimeProvider.php
index 47058c5..55c20f6 100644
--- a/lib/Providers/Time/HttpTimeProvider.php
+++ b/lib/Providers/Time/HttpTimeProvider.php
@@ -12,19 +12,16 @@
*/
class HttpTimeProvider implements ITimeProvider
{
- /** @var array */
- public array $options;
-
/**
* @param array $options
*/
public function __construct(
public string $url = 'https://google.com',
public string $expectedtimeformat = 'D, d M Y H:i:s O+',
- ?array $options = null,
+ public ?array $options = null,
) {
- if ($options === null) {
- $options = array(
+ if ($this->options === null) {
+ $this->options = array(
'http' => array(
'method' => 'HEAD',
'follow_location' => false,
@@ -39,7 +36,6 @@ public function __construct(
),
);
}
- $this->options = $options;
}
/**
From 9bc454f42501a89ce98860e1e9b7b774e555bf38 Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sun, 28 May 2023 18:58:39 +0200
Subject: [PATCH 34/48] use null coalescing assignment instead of just null
coalescing
---
lib/TwoFactorAuth.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/TwoFactorAuth.php b/lib/TwoFactorAuth.php
index f6c68d1..f3f867e 100644
--- a/lib/TwoFactorAuth.php
+++ b/lib/TwoFactorAuth.php
@@ -166,7 +166,7 @@ public function getQRText(string $label, string $secret): string
public function getQrCodeProvider(): IQRCodeProvider
{
// Set default QR Code provider if none was specified
- return $this->qrcodeprovider ?? ($this->qrcodeprovider = new QRServerProvider());
+ return $this->qrcodeprovider ??= new QRServerProvider();
}
/**
@@ -192,7 +192,7 @@ public function getRngProvider(): IRNGProvider
public function getTimeProvider(): ITimeProvider
{
// Set default time provider if none was specified
- return $this->timeprovider ?? ($this->timeprovider = new LocalMachineTimeProvider());
+ return $this->timeprovider ??= new LocalMachineTimeProvider();
}
/**
From e554a9b5e482d9e8e9b72353d8e23501e663607c Mon Sep 17 00:00:00 2001
From: Mark Magyar <14284867+xHeaven@users.noreply.github.com>
Date: Sun, 28 May 2023 19:47:10 +0200
Subject: [PATCH 35/48] change all $qrtext to camelCase version
---
lib/Providers/Qr/BaconQrCodeProvider.php | 4 ++--
lib/Providers/Qr/EndroidQrCodeProvider.php | 10 +++++-----
lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php | 10 +++++-----
lib/Providers/Qr/GoogleChartsQrCodeProvider.php | 8 ++++----
lib/Providers/Qr/IQRCodeProvider.php | 4 ++--
lib/Providers/Qr/ImageChartsQRCodeProvider.php | 8 ++++----
lib/Providers/Qr/QRServerProvider.php | 8 ++++----
lib/Providers/Qr/QRicketProvider.php | 8 ++++----
tests/Providers/Qr/TestQrProvider.php | 4 ++--
9 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/lib/Providers/Qr/BaconQrCodeProvider.php b/lib/Providers/Qr/BaconQrCodeProvider.php
index 089ad0b..4b53445 100644
--- a/lib/Providers/Qr/BaconQrCodeProvider.php
+++ b/lib/Providers/Qr/BaconQrCodeProvider.php
@@ -51,7 +51,7 @@ public function getMimeType(): string
throw new RuntimeException(sprintf('Unknown MIME-type: %s', $this->format));
}
- public function getQRCodeImage(string $qrtext, int $size): string
+ public function getQRCodeImage(string $qrText, int $size): string
{
$backend = match ($this->format) {
'svg' => new SvgImageBackEnd(),
@@ -59,7 +59,7 @@ public function getQRCodeImage(string $qrtext, int $size): string
default => new ImagickImageBackEnd($this->format),
};
- $output = $this->getQRCodeByBackend($qrtext, $size, $backend);
+ $output = $this->getQRCodeByBackend($qrText, $size, $backend);
if ($this->format === 'svg') {
$svg = explode("\n", $output);
diff --git a/lib/Providers/Qr/EndroidQrCodeProvider.php b/lib/Providers/Qr/EndroidQrCodeProvider.php
index f6aacd4..3750df5 100755
--- a/lib/Providers/Qr/EndroidQrCodeProvider.php
+++ b/lib/Providers/Qr/EndroidQrCodeProvider.php
@@ -41,19 +41,19 @@ public function getMimeType(): string
return 'image/png';
}
- public function getQRCodeImage(string $qrtext, int $size): string
+ public function getQRCodeImage(string $qrText, int $size): string
{
if (!$this->endroid4) {
- return $this->qrCodeInstance($qrtext, $size)->writeString();
+ return $this->qrCodeInstance($qrText, $size)->writeString();
}
$writer = new PngWriter();
- return $writer->write($this->qrCodeInstance($qrtext, $size))->getString();
+ return $writer->write($this->qrCodeInstance($qrText, $size))->getString();
}
- protected function qrCodeInstance(string $qrtext, int $size): QrCode
+ protected function qrCodeInstance(string $qrText, int $size): QrCode
{
- $qrCode = new QrCode($qrtext);
+ $qrCode = new QrCode($qrText);
$qrCode->setSize($size);
$qrCode->setErrorCorrectionLevel($this->errorcorrectionlevel);
diff --git a/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php b/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php
index 71a5559..0a0b2d2 100755
--- a/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php
+++ b/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php
@@ -25,10 +25,10 @@ public function setLogo($path, $size = null)
$this->logoSize = (array)$size;
}
- public function getQRCodeImage(string $qrtext, int $size): string
+ public function getQRCodeImage(string $qrText, int $size): string
{
if (!$this->endroid4) {
- return $this->qrCodeInstance($qrtext, $size)->writeString();
+ return $this->qrCodeInstance($qrText, $size)->writeString();
}
$logo = null;
@@ -42,12 +42,12 @@ public function getQRCodeImage(string $qrtext, int $size): string
}
}
$writer = new PngWriter();
- return $writer->write($this->qrCodeInstance($qrtext, $size), $logo)->getString();
+ return $writer->write($this->qrCodeInstance($qrText, $size), $logo)->getString();
}
- protected function qrCodeInstance(string $qrtext, int $size): QrCode
+ protected function qrCodeInstance(string $qrText, int $size): QrCode
{
- $qrCode = parent::qrCodeInstance($qrtext, $size);
+ $qrCode = parent::qrCodeInstance($qrText, $size);
if (!$this->endroid4 && $this->logoPath) {
$qrCode->setLogoPath($this->logoPath);
diff --git a/lib/Providers/Qr/GoogleChartsQrCodeProvider.php b/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
index bbcb7ac..4dd6c2f 100644
--- a/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
+++ b/lib/Providers/Qr/GoogleChartsQrCodeProvider.php
@@ -16,19 +16,19 @@ public function getMimeType(): string
return 'image/png';
}
- public function getQRCodeImage(string $qrtext, int $size): string
+ public function getQRCodeImage(string $qrText, int $size): string
{
- return $this->getContent($this->getUrl($qrtext, $size));
+ return $this->getContent($this->getUrl($qrText, $size));
}
- public function getUrl(string $qrtext, int $size): string
+ public function getUrl(string $qrText, int $size): string
{
$queryParameters = array(
'chs' => $size . 'x' . $size,
'chld' => strtoupper($this->errorcorrectionlevel) . '|' . $this->margin,
'cht' => 'qr',
'choe' => $this->encoding,
- 'chl' => $qrtext,
+ 'chl' => $qrText,
);
return 'https://chart.googleapis.com/chart?' . http_build_query($queryParameters);
diff --git a/lib/Providers/Qr/IQRCodeProvider.php b/lib/Providers/Qr/IQRCodeProvider.php
index dc53365..9240741 100644
--- a/lib/Providers/Qr/IQRCodeProvider.php
+++ b/lib/Providers/Qr/IQRCodeProvider.php
@@ -9,12 +9,12 @@ interface IQRCodeProvider
/**
* Generate and return the QR code to embed in a web page
*
- * @param string $qrtext the value to encode in the QR code
+ * @param string $qrText the value to encode in the QR code
* @param int $size the desired size of the QR code
*
* @return string file contents of the QR code
*/
- public function getQRCodeImage(string $qrtext, int $size): string;
+ public function getQRCodeImage(string $qrText, int $size): string;
/**
* Returns the appropriate mime type for the QR code
diff --git a/lib/Providers/Qr/ImageChartsQRCodeProvider.php b/lib/Providers/Qr/ImageChartsQRCodeProvider.php
index 6460e13..2f1079e 100644
--- a/lib/Providers/Qr/ImageChartsQRCodeProvider.php
+++ b/lib/Providers/Qr/ImageChartsQRCodeProvider.php
@@ -18,18 +18,18 @@ public function getMimeType(): string
return 'image/png';
}
- public function getQRCodeImage(string $qrtext, int $size): string
+ public function getQRCodeImage(string $qrText, int $size): string
{
- return $this->getContent($this->getUrl($qrtext, $size));
+ return $this->getContent($this->getUrl($qrText, $size));
}
- public function getUrl(string $qrtext, int $size): string
+ public function getUrl(string $qrText, int $size): string
{
$queryParameters = array(
'cht' => 'qr',
'chs' => ceil($size / 2) . 'x' . ceil($size / 2),
'chld' => $this->errorcorrectionlevel . '|' . $this->margin,
- 'chl' => $qrtext,
+ 'chl' => $qrText,
);
return 'https://image-charts.com/chart?' . http_build_query($queryParameters);
diff --git a/lib/Providers/Qr/QRServerProvider.php b/lib/Providers/Qr/QRServerProvider.php
index 96cb3fd..9244795 100644
--- a/lib/Providers/Qr/QRServerProvider.php
+++ b/lib/Providers/Qr/QRServerProvider.php
@@ -31,12 +31,12 @@ public function getMimeType(): string
throw new QRException(sprintf('Unknown MIME-type: %s', $this->format));
}
- public function getQRCodeImage(string $qrtext, int $size): string
+ public function getQRCodeImage(string $qrText, int $size): string
{
- return $this->getContent($this->getUrl($qrtext, $size));
+ return $this->getContent($this->getUrl($qrText, $size));
}
- public function getUrl(string $qrtext, int $size): string
+ public function getUrl(string $qrText, int $size): string
{
$queryParameters = array(
'size' => $size . 'x' . $size,
@@ -46,7 +46,7 @@ public function getUrl(string $qrtext, int $size): string
'bgcolor' => $this->decodeColor($this->bgcolor),
'color' => $this->decodeColor($this->color),
'format' => strtolower($this->format),
- 'data' => $qrtext,
+ 'data' => $qrText,
);
return 'https://api.qrserver.com/v1/create-qr-code/?' . http_build_query($queryParameters);
diff --git a/lib/Providers/Qr/QRicketProvider.php b/lib/Providers/Qr/QRicketProvider.php
index a56088a..d976b5f 100644
--- a/lib/Providers/Qr/QRicketProvider.php
+++ b/lib/Providers/Qr/QRicketProvider.php
@@ -27,12 +27,12 @@ public function getMimeType(): string
throw new QRException(sprintf('Unknown MIME-type: %s', $this->format));
}
- public function getQRCodeImage(string $qrtext, int $size): string
+ public function getQRCodeImage(string $qrText, int $size): string
{
- return $this->getContent($this->getUrl($qrtext, $size));
+ return $this->getContent($this->getUrl($qrText, $size));
}
- public function getUrl(string $qrtext, int $size): string
+ public function getUrl(string $qrText, int $size): string
{
$queryParameters = array(
'qrsize' => $size,
@@ -40,7 +40,7 @@ public function getUrl(string $qrtext, int $size): string
'bgdcolor' => $this->bgcolor,
'fgdcolor' => $this->color,
't' => strtolower($this->format),
- 'd' => $qrtext,
+ 'd' => $qrText,
);
return 'http://qrickit.com/api/qr?' . http_build_query($queryParameters);
diff --git a/tests/Providers/Qr/TestQrProvider.php b/tests/Providers/Qr/TestQrProvider.php
index f7b790c..2f46954 100644
--- a/tests/Providers/Qr/TestQrProvider.php
+++ b/tests/Providers/Qr/TestQrProvider.php
@@ -8,9 +8,9 @@
class TestQrProvider implements IQRCodeProvider
{
- public function getQRCodeImage(string $qrtext, int $size): string
+ public function getQRCodeImage(string $qrText, int $size): string
{
- return $qrtext . '@' . $size;
+ return $qrText . '@' . $size;
}
public function getMimeType(): string
From 241dfec585e3faf68ae9476650432aeb8c5a21c7 Mon Sep 17 00:00:00 2001
From: Jan <96944229+modelrailroader@users.noreply.github.com>
Date: Mon, 5 Jun 2023 16:09:42 +0200
Subject: [PATCH 36/48] fix: fixed docs
---
docs/qr-codes.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/qr-codes.md b/docs/qr-codes.md
index 5bd3490..bf7b6c8 100644
--- a/docs/qr-codes.md
+++ b/docs/qr-codes.md
@@ -48,6 +48,7 @@ If you do not want to use the default QR code provider, you can specify the one
```php
use RobThree\Auth\TwoFactorAuth;
+use RobThree\Auth\Algorithm;
$qrCodeProvider = new YourChosenProvider();
@@ -55,7 +56,7 @@ $tfa = new TwoFactorAuth(
null,
6,
30,
- 'sha1',
+ Algorithm::Sha1,
$qrCodeProvider
);
```
From dd0ecaeed1452a020c28434a5f1e68c5cb650907 Mon Sep 17 00:00:00 2001
From: Jan <96944229+modelrailroader@users.noreply.github.com>
Date: Thu, 8 Jun 2023 16:56:08 +0200
Subject: [PATCH 37/48] Fix: Changes for > PHP 8
---
docs/qr-codes.md | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/docs/qr-codes.md b/docs/qr-codes.md
index bf7b6c8..83e9b5d 100644
--- a/docs/qr-codes.md
+++ b/docs/qr-codes.md
@@ -50,14 +50,12 @@ If you do not want to use the default QR code provider, you can specify the one
use RobThree\Auth\TwoFactorAuth;
use RobThree\Auth\Algorithm;
-$qrCodeProvider = new YourChosenProvider();
-
$tfa = new TwoFactorAuth(
null,
6,
30,
Algorithm::Sha1,
- $qrCodeProvider
+ YourChosenProvider: $qrCodeProvider
);
```
From 83611592db62a115a4ed6c4d757475bb64fa08b3 Mon Sep 17 00:00:00 2001
From: Jan <96944229+modelrailroader@users.noreply.github.com>
Date: Sun, 11 Jun 2023 12:20:59 +0200
Subject: [PATCH 38/48] fix: fixed documentation
---
docs/optional-configuration.md | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/docs/optional-configuration.md b/docs/optional-configuration.md
index 346d6cd..4016e76 100644
--- a/docs/optional-configuration.md
+++ b/docs/optional-configuration.md
@@ -7,15 +7,15 @@ title: Optional Configuration
The instance (`new TwoFactorAuth()`) can only be configured by the constructor with the following optional arguments
-Argument | Default value | Use
-------------------|---------------|-----
-`$issuer` | `null` | Will be displayed in the users app as the default issuer name when using QR code to import the secret
-`$digits` | `6` | The number of digits the resulting codes will be
-`$period` | `30` | The number of seconds a code will be valid
-`$algorithm` | `'sha1'` | The algorithm used (one of `sha1`, `sha256`, `sha512`, `md5`)
-`$qrcodeprovider` | `null` | QR-code provider
-`$rngprovider` | `null` | Random Number Generator provider
-`$timeprovider` | `null` | Time provider
+Argument | Default value | Use
+------------------|-------------------|-----
+`$issuer` | `null` | Will be displayed in the users app as the default issuer name when using QR code to import the secret
+`$digits` | `6` | The number of digits the resulting codes will be
+`$period` | `30` | The number of seconds a code will be valid
+`$algorithm` | `Algorithm::Sha1` | The algorithm used (one of `Algorithm::Sha1`, `Algorithm::Sha256`, `Algorithm::Sha512`, `Algorithm::md5`)
+`$qrcodeprovider` | `null` | QR-code provider
+`$rngprovider` | `null` | Random Number Generator provider
+`$timeprovider` | `null` | Time provider
**Note:** the default values for `$digits`, `$period`, and `$algorithm` provide the widest variety of support amongst common authenticator apps such as Google Authenticator. If you choose to use different values for these arguments you will likely have to instruct your users to use a specific app which supports your chosen configuration.
From 6416e79c3e2339075e02d886bb05a619f0b79d5e Mon Sep 17 00:00:00 2001
From: Jan <96944229+modelrailroader@users.noreply.github.com>
Date: Sun, 11 Jun 2023 12:22:26 +0200
Subject: [PATCH 39/48] fix: fixed typing
---
docs/optional-configuration.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/optional-configuration.md b/docs/optional-configuration.md
index 4016e76..d3e2556 100644
--- a/docs/optional-configuration.md
+++ b/docs/optional-configuration.md
@@ -12,7 +12,7 @@ Argument | Default value | Use
`$issuer` | `null` | Will be displayed in the users app as the default issuer name when using QR code to import the secret
`$digits` | `6` | The number of digits the resulting codes will be
`$period` | `30` | The number of seconds a code will be valid
-`$algorithm` | `Algorithm::Sha1` | The algorithm used (one of `Algorithm::Sha1`, `Algorithm::Sha256`, `Algorithm::Sha512`, `Algorithm::md5`)
+`$algorithm` | `Algorithm::Sha1` | The algorithm used (one of `Algorithm::Sha1`, `Algorithm::Sha256`, `Algorithm::Sha512`, `Algorithm::Md5`)
`$qrcodeprovider` | `null` | QR-code provider
`$rngprovider` | `null` | Random Number Generator provider
`$timeprovider` | `null` | Time provider
From a6f7735b9fbd1143625cdb4292e28720dab5760d Mon Sep 17 00:00:00 2001
From: Jan <96944229+modelrailroader@users.noreply.github.com>
Date: Fri, 23 Jun 2023 17:54:58 +0200
Subject: [PATCH 40/48] fix: docs for new PHP Version
---
docs/qr-codes.md | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/docs/qr-codes.md b/docs/qr-codes.md
index 83e9b5d..25fdd3c 100644
--- a/docs/qr-codes.md
+++ b/docs/qr-codes.md
@@ -48,14 +48,10 @@ If you do not want to use the default QR code provider, you can specify the one
```php
use RobThree\Auth\TwoFactorAuth;
-use RobThree\Auth\Algorithm;
$tfa = new TwoFactorAuth(
- null,
- 6,
- 30,
- Algorithm::Sha1,
- YourChosenProvider: $qrCodeProvider
+ issuer: "Your Company Or App Name",
+ qrcodeprovider: $qrCodeProvider
);
```
From d5aa22a96f7b0b0f33a935cbe0821930f0c72bfa Mon Sep 17 00:00:00 2001
From: Jan <96944229+modelrailroader@users.noreply.github.com>
Date: Fri, 23 Jun 2023 17:56:25 +0200
Subject: [PATCH 41/48] fix: hyperlinks for new file extensions
---
docs/qr-codes.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/docs/qr-codes.md b/docs/qr-codes.md
index 25fdd3c..672262d 100644
--- a/docs/qr-codes.md
+++ b/docs/qr-codes.md
@@ -20,19 +20,19 @@ You can also specify a size as a third argument which is 200 by default.
## Online Providers
-[QRServerProvider](qr-codes/qr-server.html) (default)
+[QRServerProvider](qr-codes/qr-server.md) (default)
**Warning:** Whilst it is the default, this provider is not suggested for applications where absolute security is needed, because it uses an external service for the QR code generation. You can make use of the included offline providers listed below which generate locally.
-[ImageChartsQRCodeProvider](qr-codes/image-charts.html)
+[ImageChartsQRCodeProvider](qr-codes/image-charts.md)
-[QRicketProvider](qr-codes/qrickit.html)
+[QRicketProvider](qr-codes/qrickit.md)
## Offline Providers
-[EndroidQrCodeProvider](qr-codes/endroid.html) and EndroidQrCodeWithLogoProvider
+[EndroidQrCodeProvider](qr-codes/endroid.md) and EndroidQrCodeWithLogoProvider
-[BaconQRCodeProvider](qr-codes/bacon.html)
+[BaconQRCodeProvider](qr-codes/bacon.md)
**Note:** offline providers may have additional PHP requirements in order to function, you should study what is required before trying to make use of them.
From 0565d63e6aacce62f03b94a26e0a328031423c46 Mon Sep 17 00:00:00 2001
From: Jan <96944229+modelrailroader@users.noreply.github.com>
Date: Fri, 23 Jun 2023 21:21:37 +0200
Subject: [PATCH 42/48] fix: better understanding for QrCodeProvider class
---
docs/qr-codes.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docs/qr-codes.md b/docs/qr-codes.md
index 672262d..7236198 100644
--- a/docs/qr-codes.md
+++ b/docs/qr-codes.md
@@ -49,6 +49,8 @@ If you do not want to use the default QR code provider, you can specify the one
```php
use RobThree\Auth\TwoFactorAuth;
+$qrCodeProvider = new YourChosenProvider();
+
$tfa = new TwoFactorAuth(
issuer: "Your Company Or App Name",
qrcodeprovider: $qrCodeProvider
From 137df4dd3cd998e7096705cd0b3aed17b4c25d53 Mon Sep 17 00:00:00 2001
From: William Hall
Date: Sat, 29 Jul 2023 15:46:20 +0100
Subject: [PATCH 43/48] =?UTF-8?q?=F0=9F=94=A7=20remove=20deprecated=20rule?=
=?UTF-8?q?=20https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/7066?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.php-cs-fixer.dist.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 32d4c5b..86d3e30 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -39,7 +39,6 @@
'semicolon_after_instruction' => true,
'short_scalar_cast' => true,
'simplified_null_return' => true,
- 'single_blank_line_before_namespace' => true,
'single_class_element_per_statement' => true,
'single_line_comment_style' => true,
'single_quote' => true,
From 63f6259db2a61b99091a9f370f5d9d583774041f Mon Sep 17 00:00:00 2001
From: Matthijs van Schooten
Date: Fri, 10 Nov 2023 13:27:45 +0100
Subject: [PATCH 44/48] Added support for EndroidQR v5
---
composer.json | 3 ++-
lib/Providers/Qr/EndroidQrCodeProvider.php | 30 +++++++++++++++++++---
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/composer.json b/composer.json
index a3264a0..4a87de4 100644
--- a/composer.json
+++ b/composer.json
@@ -27,7 +27,8 @@
"source": "https://github.com/RobThree/TwoFactorAuth"
},
"require": {
- "php": ">=8.1.0"
+ "php": ">=8.1.0",
+ "endroid/qr-code": "^5.0"
},
"require-dev": {
"phpunit/phpunit": "^9",
diff --git a/lib/Providers/Qr/EndroidQrCodeProvider.php b/lib/Providers/Qr/EndroidQrCodeProvider.php
index 3750df5..8f8c4ac 100755
--- a/lib/Providers/Qr/EndroidQrCodeProvider.php
+++ b/lib/Providers/Qr/EndroidQrCodeProvider.php
@@ -26,9 +26,12 @@ class EndroidQrCodeProvider implements IQRCodeProvider
protected $endroid4 = false;
+ protected $endroid5 = false;
+
public function __construct($bgcolor = 'ffffff', $color = '000000', $margin = 0, $errorcorrectionlevel = 'H')
{
$this->endroid4 = method_exists(QrCode::class, 'create');
+ $this->endroid5 = enum_exists(ErrorCorrectionLevel::class);
$this->bgcolor = $this->handleColor($bgcolor);
$this->color = $this->handleColor($color);
@@ -76,11 +79,30 @@ private function handleColor(string $color): Color|array
private function handleErrorCorrectionLevel(string $level): ErrorCorrectionLevelInterface|ErrorCorrectionLevel
{
+ if ($this->endroid4) {
+ return match ($level) {
+ 'L' => new ErrorCorrectionLevelLow(),
+ 'M' => new ErrorCorrectionLevelMedium(),
+ 'Q' => new ErrorCorrectionLevelQuartile(),
+ default => new ErrorCorrectionLevelHigh(),
+ };
+ }
+
+ if ($this->endroid5) {
+ return match ($level) {
+ 'L' => ErrorCorrectionLevel::Low,
+ 'M' => ErrorCorrectionLevel::Medium,
+ 'Q' => ErrorCorrectionLevel::Quartile,
+ default => ErrorCorrectionLevel::High,
+ };
+ }
+
+ // Assuming this is for version EndroidQR < 4
return match ($level) {
- 'L' => $this->endroid4 ? new ErrorCorrectionLevelLow() : ErrorCorrectionLevel::LOW(),
- 'M' => $this->endroid4 ? new ErrorCorrectionLevelMedium() : ErrorCorrectionLevel::MEDIUM(),
- 'Q' => $this->endroid4 ? new ErrorCorrectionLevelQuartile() : ErrorCorrectionLevel::QUARTILE(),
- default => $this->endroid4 ? new ErrorCorrectionLevelHigh() : ErrorCorrectionLevel::HIGH(),
+ 'L' => ErrorCorrectionLevel::LOW(),
+ 'M' => ErrorCorrectionLevel::MEDIUM(),
+ 'Q' => ErrorCorrectionLevel::QUARTILE(),
+ default => ErrorCorrectionLevel::HIGH(),
};
}
}
From 126afe4c25ed82bbade984459ef4db63ec8ff50f Mon Sep 17 00:00:00 2001
From: Matthijs van Schooten
Date: Fri, 10 Nov 2023 13:32:44 +0100
Subject: [PATCH 45/48] Removed dependency again from composer
---
composer.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/composer.json b/composer.json
index 4a87de4..a3264a0 100644
--- a/composer.json
+++ b/composer.json
@@ -27,8 +27,7 @@
"source": "https://github.com/RobThree/TwoFactorAuth"
},
"require": {
- "php": ">=8.1.0",
- "endroid/qr-code": "^5.0"
+ "php": ">=8.1.0"
},
"require-dev": {
"phpunit/phpunit": "^9",
From 4b6b0601b74eb5276b60f4070521460376cdb2f6 Mon Sep 17 00:00:00 2001
From: Matthijs van Schooten
Date: Fri, 10 Nov 2023 13:41:25 +0100
Subject: [PATCH 46/48] Fixed check ordering
---
lib/Providers/Qr/EndroidQrCodeProvider.php | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/lib/Providers/Qr/EndroidQrCodeProvider.php b/lib/Providers/Qr/EndroidQrCodeProvider.php
index 8f8c4ac..842bf45 100755
--- a/lib/Providers/Qr/EndroidQrCodeProvider.php
+++ b/lib/Providers/Qr/EndroidQrCodeProvider.php
@@ -79,15 +79,7 @@ private function handleColor(string $color): Color|array
private function handleErrorCorrectionLevel(string $level): ErrorCorrectionLevelInterface|ErrorCorrectionLevel
{
- if ($this->endroid4) {
- return match ($level) {
- 'L' => new ErrorCorrectionLevelLow(),
- 'M' => new ErrorCorrectionLevelMedium(),
- 'Q' => new ErrorCorrectionLevelQuartile(),
- default => new ErrorCorrectionLevelHigh(),
- };
- }
-
+ // First check for version 5 (using consts)
if ($this->endroid5) {
return match ($level) {
'L' => ErrorCorrectionLevel::Low,
@@ -97,7 +89,17 @@ private function handleErrorCorrectionLevel(string $level): ErrorCorrectionLevel
};
}
- // Assuming this is for version EndroidQR < 4
+ // If not check for version 4 (using classes)
+ if ($this->endroid4) {
+ return match ($level) {
+ 'L' => new ErrorCorrectionLevelLow(),
+ 'M' => new ErrorCorrectionLevelMedium(),
+ 'Q' => new ErrorCorrectionLevelQuartile(),
+ default => new ErrorCorrectionLevelHigh(),
+ };
+ }
+
+ // Any other version will be using strings
return match ($level) {
'L' => ErrorCorrectionLevel::LOW(),
'M' => ErrorCorrectionLevel::MEDIUM(),
From 13a56018f443736503929039bdb6d5e2e81a20a2 Mon Sep 17 00:00:00 2001
From: Matthijs van Schooten
Date: Fri, 10 Nov 2023 13:43:28 +0100
Subject: [PATCH 47/48] Fixed typo
---
lib/Providers/Qr/EndroidQrCodeProvider.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Providers/Qr/EndroidQrCodeProvider.php b/lib/Providers/Qr/EndroidQrCodeProvider.php
index 842bf45..4d42c18 100755
--- a/lib/Providers/Qr/EndroidQrCodeProvider.php
+++ b/lib/Providers/Qr/EndroidQrCodeProvider.php
@@ -79,7 +79,7 @@ private function handleColor(string $color): Color|array
private function handleErrorCorrectionLevel(string $level): ErrorCorrectionLevelInterface|ErrorCorrectionLevel
{
- // First check for version 5 (using consts)
+ // First check for version 5 (using enums)
if ($this->endroid5) {
return match ($level) {
'L' => ErrorCorrectionLevel::Low,
From ec35073c061b724eb98a1c8e82a614b4dfc302ac Mon Sep 17 00:00:00 2001
From: William Hall
Date: Tue, 14 Nov 2023 12:49:15 +0000
Subject: [PATCH 48/48] =?UTF-8?q?=F0=9F=94=A7=20test=20all=20endroid=20ver?=
=?UTF-8?q?sions=20we=20can=20care=20about?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/test-endroid.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/test-endroid.yml b/.github/workflows/test-endroid.yml
index 79958cb..23b3867 100644
--- a/.github/workflows/test-endroid.yml
+++ b/.github/workflows/test-endroid.yml
@@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
php-version: ['8.1', '8.2']
- endroid-version: ["^4"]
+ endroid-version: ["^3","^4","^5"]
steps:
- uses: actions/checkout@v3
@@ -25,7 +25,7 @@ jobs:
- uses: ramsey/composer-install@v2
- - run: composer require endroid/qrcode:${{ matrix.endroid-version }}
+ - run: composer require endroid/qrcode:${{ matrix.endroid-version }} -W
- run: composer lint-ci
- run: composer test testsDependency/EndroidQRCodeTest.php