Skip to content

Commit 86593de

Browse files
committed
:octocat: PHP 8.4+
1 parent 409782a commit 86593de

15 files changed

Lines changed: 95 additions & 133 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ A generator for counter based ([RFC 4226](https://tools.ietf.org/html/rfc4226))
2727

2828
# Documentation
2929
## Requirements
30-
- PHP 8.2+
30+
- PHP 8.4+
3131
- [`ext-curl`](https://www.php.net/manual/book.curl) for Steam Guard server time synchronization
3232
- [`ext-sodium`](https://www.php.net/manual/book.sodium) for constant time implementations of base64 encode/decode and hex2bin/bin2hex
3333
([`paragonie/constant_time_encoding`](https://github.com/paragonie/constant_time_encoding) is used as fallback)
@@ -41,7 +41,7 @@ via terminal: `composer require chillerlan/php-authenticator`
4141
```json
4242
{
4343
"require": {
44-
"php": "^8.2",
44+
"php": "^8.4",
4545
"chillerlan/php-authenticator": "dev-main"
4646
}
4747
}

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@
3232
"prefer-stable": true,
3333
"require": {
3434
"php": "^8.4",
35-
"chillerlan/php-settings-container": "^3.2.1",
35+
"chillerlan/php-settings-container": "^4.0",
3636
"paragonie/constant_time_encoding": "^3.0"
3737
},
3838
"require-dev": {
3939
"ext-curl": "*",
4040
"ext-json": "*",
4141
"ext-sodium": "*",
42-
"phan/phan": "^6.0.1",
42+
"phan/phan": "^6.0.2",
4343
"phpmd/phpmd": "^2.15",
44-
"phpstan/phpstan": "^2.1.40",
44+
"phpstan/phpstan": "^2.1.42",
4545
"phpstan/phpstan-deprecation-rules": "^2.0.4",
4646
"phpunit/phpunit": "^13.0",
4747
"slevomat/coding-standard": "^8.28",

phpcs.xml.dist

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
<rule ref="SlevomatCodingStandard.Classes.ClassConstantVisibility"/>
3838
<rule ref="SlevomatCodingStandard.Classes.DisallowConstructorPropertyPromotion"/>
39-
<rule ref="SlevomatCodingStandard.Classes.ForbiddenPublicProperty"/>
39+
<!--<rule ref="SlevomatCodingStandard.Classes.ForbiddenPublicProperty"/>-->
4040
<rule ref="SlevomatCodingStandard.Classes.ModernClassNameReference"/>
4141

4242
<rule ref="SlevomatCodingStandard.Commenting.DeprecatedAnnotationDeclaration"/>
@@ -162,7 +162,7 @@
162162
<rule ref="Generic.Strings.UnnecessaryStringConcat"/>
163163
<!--<rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/>-->
164164
<rule ref="Generic.WhiteSpace.IncrementDecrementSpacing"/>
165-
<rule ref="Generic.WhiteSpace.ScopeIndent"/>
165+
<!--<rule ref="Generic.WhiteSpace.ScopeIndent"/>-->
166166
<rule ref="Generic.WhiteSpace.SpreadOperatorSpacingAfter"/>
167167

168168
<rule ref="PSR2.ControlStructures.ElseIfDeclaration"/>
@@ -198,7 +198,7 @@
198198
<rule ref="Squiz.PHP.InnerFunctions"/>
199199
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
200200
<rule ref="Squiz.PHP.NonExecutableCode"/>
201-
<rule ref="Squiz.Scope.MemberVarScope"/>
201+
<!--<rule ref="Squiz.Scope.MemberVarScope"/>-->
202202
<rule ref="Squiz.Scope.MethodScope"/>
203203
<rule ref="Squiz.Scope.StaticThisUsage"/>
204204
<rule ref="Squiz.Strings.DoubleQuoteUsage"/>
@@ -270,7 +270,7 @@
270270
<property name="ignoreNewlines" value="true" />
271271
</properties>
272272
</rule>
273-
273+
<!--
274274
<rule ref="Generic.WhiteSpace.ScopeIndent">
275275
<properties>
276276
<property name="tabIndent" value="true" />
@@ -280,7 +280,7 @@
280280
</property>
281281
</properties>
282282
</rule>
283-
283+
-->
284284
<rule ref="PSR12.ControlStructures.BooleanOperatorPlacement">
285285
<properties>
286286
<property name="allowOnly" value="first" />

src/Authenticator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
/**
2020
* Yet another Google authenticator implementation!
2121
*
22-
* Note: This class has been reduced oover time to a front-end to the several authenticator classes
22+
* Note: This class has been reduced over time to a front-end to the several authenticator classes
2323
* (`HOTP`, `TOTP`, ...), which can be invoked on their own. `Authenticator` will remain for convenience.
2424
*
2525
* @link https://tools.ietf.org/html/rfc4226

src/AuthenticatorOptionsTrait.php

Lines changed: 69 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
* @author smiley <smiley@chillerlan.net>
77
* @copyright 2019 smiley
88
* @license MIT
9+
*
10+
* @see https://github.com/phan/phan/issues/5491
11+
* @phan-file-suppress PhanUnreferencedUseNormal, PhanUnreferencedUseFunction, PhanPropertyHookWithDefaultValue
912
*/
1013
declare(strict_types=1);
1114

@@ -17,36 +20,51 @@
1720
use function strtolower;
1821
use function strtoupper;
1922

20-
/**
21-
* @property int $digits
22-
* @property int $period
23-
* @property int $secret_length
24-
* @property string $algorithm
25-
* @property string $mode
26-
* @property int $adjacent
27-
* @property int $time_offset
28-
* @property bool $useLocalTime
29-
* @property bool $forceTimeRefresh
30-
* @property bool $omitUriSettings
31-
*/
3223
trait AuthenticatorOptionsTrait{
3324

3425
/**
3526
* Code length: either 6 or 8
3627
*/
37-
protected int $digits = 6;
28+
public int $digits = 6 {
29+
set{
30+
31+
if(!in_array($value, [6, 8], true)){
32+
throw new InvalidArgumentException('Invalid code length: '.$value);
33+
}
34+
35+
$this->digits = $value;
36+
}
37+
}
3838

3939
/**
4040
* Validation period (seconds): 15 - 60
4141
*/
42-
protected int $period = 30;
42+
public int $period = 30 {
43+
set{
44+
45+
if($value < 15 || $value > 60){
46+
throw new InvalidArgumentException('Invalid period: '.$value);
47+
}
48+
49+
$this->period = $value;
50+
}
51+
}
4352

4453
/**
4554
* Length of the secret phrase (bytes, unencoded binary)
4655
*
4756
* @see \random_bytes()
4857
*/
49-
protected int $secret_length = 20;
58+
public int $secret_length = 20 {
59+
set{
60+
61+
if($value < 16 || $value > 1024){
62+
throw new InvalidArgumentException('Invalid secret length: '.$value);
63+
}
64+
65+
$this->secret_length = $value;
66+
}
67+
}
5068

5169
/**
5270
* Hash algorithm:
@@ -55,7 +73,17 @@ trait AuthenticatorOptionsTrait{
5573
* - `AuthenticatorInterface::ALGO_SHA256`
5674
* - `AuthenticatorInterface::ALGO_SHA512`
5775
*/
58-
protected string $algorithm = AuthenticatorInterface::ALGO_SHA1;
76+
public string $algorithm = AuthenticatorInterface::ALGO_SHA1 {
77+
set{
78+
$value = strtoupper($value);
79+
80+
if(!in_array($value, AuthenticatorInterface::HASH_ALGOS, true)){
81+
throw new InvalidArgumentException('Invalid algorithm: '.$value);
82+
}
83+
84+
$this->algorithm = $value;
85+
}
86+
}
5987

6088
/**
6189
* Authenticator mode:
@@ -64,19 +92,38 @@ trait AuthenticatorOptionsTrait{
6492
* - `AuthenticatorInterface::TOTP` = time based
6593
* - `AuthenticatorInterface::STEAM` = time based (Steam Guard)
6694
*/
67-
protected string $mode = AuthenticatorInterface::TOTP;
95+
public string $mode = AuthenticatorInterface::TOTP {
96+
set{
97+
$value = strtolower($value);
98+
99+
if(!isset(AuthenticatorInterface::MODES[$value])){
100+
throw new InvalidArgumentException('Invalid mode: '.$value);
101+
}
102+
103+
$this->mode = $value;
104+
}
105+
}
68106

69107
/**
70108
* Number of allowed adjacent codes
71109
*/
72-
protected int $adjacent = 1;
110+
public int $adjacent = 1 {
111+
set{
112+
// limit to a sane amount
113+
if($value < 0 || $value > 20){
114+
throw new InvalidArgumentException('Invalid number of adjacent codes: '.$value);
115+
}
116+
117+
$this->adjacent = $value;
118+
}
119+
}
73120

74121
/**
75122
* A fixed time offset that will be added to the current time value
76123
*
77124
* @see \chillerlan\Authenticator\Authenticators\AuthenticatorInterface::getCounter()
78125
*/
79-
protected int $time_offset = 0;
126+
public int $time_offset = 0;
80127

81128
/**
82129
* Whether to use local time or request server time from the API
@@ -85,102 +132,18 @@ trait AuthenticatorOptionsTrait{
85132
*
86133
* note: API requests needs ext-curl installed
87134
*/
88-
protected bool $useLocalTime = true;
135+
public bool $useLocalTime = true;
89136

90137
/**
91138
* Whether to force refreshing server time on each call or use the time returned from the last request
92139
*/
93-
protected bool $forceTimeRefresh = false;
140+
public bool $forceTimeRefresh = false;
94141

95142
/**
96143
* Whether to omit the additional settings in the URI for an authenticator app (algo, digits, period)
97144
*
98145
* @link https://github.com/google/google-authenticator/wiki/Key-Uri-Format#parameters
99146
*/
100-
protected bool $omitUriSettings = true;
101-
102-
/**
103-
* Sets the code length to either 6 or 8
104-
*
105-
* @throws \InvalidArgumentException
106-
*/
107-
protected function set_digits(int $digits):void{
108-
109-
if(!in_array($digits, [6, 8], true)){
110-
throw new InvalidArgumentException('Invalid code length: '.$digits);
111-
}
112-
113-
$this->digits = $digits;
114-
}
115-
116-
/**
117-
* Sets the period to a value between 15 and 60 seconds
118-
*
119-
* @throws \InvalidArgumentException
120-
*/
121-
protected function set_period(int $period):void{
122-
123-
if($period < 15 || $period > 60){
124-
throw new InvalidArgumentException('Invalid period: '.$period);
125-
}
126-
127-
$this->period = $period;
128-
}
129-
130-
/**
131-
* Sets the hash algorithm
132-
*
133-
* @throws \InvalidArgumentException
134-
*/
135-
protected function set_algorithm(string $algorithm):void{
136-
$algorithm = strtoupper($algorithm);
137-
138-
if(!in_array($algorithm, AuthenticatorInterface::HASH_ALGOS, true)){
139-
throw new InvalidArgumentException('Invalid algorithm: '.$algorithm);
140-
}
141-
142-
$this->algorithm = $algorithm;
143-
}
144-
145-
/**
146-
* Sets the authenticator mode
147-
*
148-
* @throws \InvalidArgumentException
149-
*/
150-
protected function set_mode(string $mode):void{
151-
$mode = strtolower($mode);
152-
153-
if(!isset(AuthenticatorInterface::MODES[$mode])){
154-
throw new InvalidArgumentException('Invalid mode: '.$mode);
155-
}
156-
157-
$this->mode = $mode;
158-
}
159-
160-
/**
161-
* Sets the adjacent amount
162-
*
163-
* @throws \InvalidArgumentException
164-
*/
165-
protected function set_adjacent(int $adjacent):void{
166-
// limit to a sane amount
167-
if($adjacent < 0 || $adjacent > 20){
168-
throw new InvalidArgumentException('Invalid number of adjacent codes: '.$adjacent);
169-
}
170-
171-
$this->adjacent = $adjacent;
172-
}
173-
174-
/**
175-
* @throws \InvalidArgumentException
176-
*/
177-
protected function set_secret_length(int $secret_length):void{
178-
179-
if($secret_length < 16 || $secret_length > 1024){
180-
throw new InvalidArgumentException('Invalid secret length: '.$secret_length);
181-
}
182-
183-
$this->secret_length = $secret_length;
184-
}
147+
public bool $omitUriSettings = true;
185148

186149
}

src/Authenticators/AuthenticatorAbstract.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
abstract class AuthenticatorAbstract implements AuthenticatorInterface{
3030

31-
protected const string userAgent = 'chillerlanAuthenticator/5.0 +https://github.com/chillerlan/php-authenticator';
31+
protected const string userAgent = 'chillerlanAuthenticator/6.0 +https://github.com/chillerlan/php-authenticator';
3232

3333
protected SettingsContainerInterface|AuthenticatorOptions $options;
3434
protected string|null $secret = null;
@@ -88,7 +88,6 @@ public function getRawSecret():string{
8888
return $this->secret;
8989
}
9090

91-
9291
public function createSecret(int|null $length = null):string{
9392
$length ??= $this->options->secret_length;
9493

src/Authenticators/AuthenticatorInterface.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616

1717
interface AuthenticatorInterface{
1818

19-
public const string TOTP = 'totp';
20-
public const string HOTP = 'hotp';
21-
public const string STEAM_GUARD = 'steam';
19+
final public const string TOTP = 'totp';
20+
final public const string HOTP = 'hotp';
21+
final public const string STEAM_GUARD = 'steam';
2222

23-
public const string ALGO_SHA1 = 'SHA1';
24-
public const string ALGO_SHA256 = 'SHA256';
25-
public const string ALGO_SHA512 = 'SHA512';
23+
final public const string ALGO_SHA1 = 'SHA1';
24+
final public const string ALGO_SHA256 = 'SHA256';
25+
final public const string ALGO_SHA512 = 'SHA512';
2626

2727
public const array MODES = [
2828
self::HOTP => HOTP::class,

src/Common/Base64.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
/**
2020
* Class to provide base64 encoding/decoding of strings using constant time functions
2121
*/
22-
class Base64 implements EncoderInterface{
22+
final class Base64 implements EncoderInterface{
2323

2424
/**
2525
* The Base64 character set as defined by RFC3548

src/Common/Hex.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*
2222
* (class is currently unused)
2323
*/
24-
class Hex implements EncoderInterface{
24+
final class Hex implements EncoderInterface{
2525

2626
public const string CHARSET = '1234567890ABCDEFabcdef';
2727

tests/Authenticators/HOTPTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class HOTPTest extends AuthenticatorInterfaceTestAbstract{
2222
/**
2323
* @see https://tools.ietf.org/html/rfc4226#page-32
2424
*/
25-
protected const array rfc4226Vectors = [
25+
final protected const array rfc4226Vectors = [
2626
[0, 'cc93cf18508d94934c64b65d8ba7667fb7cde4b0', 1284755224, '755224'],
2727
[1, '75a48a19d4cbe100644e8ac1397eea747a2d33ab', 1094287082, '287082'],
2828
[2, '0bacb7fa082fef30782211938bc1c5e70416ff44', 137359152, '359152'],

0 commit comments

Comments
 (0)