Skip to content

Commit 30de803

Browse files
byjgclaude
andauthored
JWT Session 6.0 - Major Version Update (#19)
* Claude/update legacy config 011 c uy cef h lgxfv x zm77h5 c6 (#18) * Update legacy configuration files - Update phpunit.xml.dist to PHPUnit 10+ format with new attributes and source tag - Create psalm.xml with static analysis configuration - Update composer.json: PHP >=8.1 <8.5, byjg/jwt-wrapper ^6.0, phpunit ^10|^11, vimeo/psalm ^5.9|^6.12 - Add composer scripts for test and psalm - Update GitHub workflow to test PHP 8.1-8.4 - Update .gitignore with additional patterns * Fix compatibility with jwt-wrapper 6.0 - Update namespace imports from ByJG\Util to ByJG\JwtWrapper - Update class names: JwtKeySecret -> JwtHashHmacSecret, JwtRsaKey -> JwtOpenSSLKey - Update JwtWrapper::createJwtData() call to pass array instead of string - Make test data providers static for PHPUnit 10+ compatibility - Convert @dataProvider annotations to PHP attributes - Suppress unserialize warnings in session parser (expected behavior) * Fix psalm static analysis errors - Add #[Override] attributes to SessionHandlerInterface methods - Fix gc() return type from bool to int|false per interface - Remove redundant null coalescing for getCookiePath() calls --------- Co-authored-by: Claude <[email protected]> * Update PHPUnit GitHub Actions workflow with container options and checkout version --------- Co-authored-by: Claude <[email protected]>
1 parent 26f06fa commit 30de803

File tree

8 files changed

+83
-53
lines changed

8 files changed

+83
-53
lines changed

.github/workflows/phpunit.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@ on:
1212
jobs:
1313
Build:
1414
runs-on: 'ubuntu-latest'
15-
container: 'byjg/php:${{ matrix.php-version }}-cli'
15+
container:
16+
image: 'byjg/php:${{ matrix.php-version }}-cli'
17+
options: --user root --privileged
1618
strategy:
1719
matrix:
1820
php-version:
21+
- "8.4"
22+
- "8.3"
1923
- "8.2"
2024
- "8.1"
21-
- "8.0"
2225

2326
steps:
24-
- uses: actions/checkout@v4
27+
- uses: actions/checkout@v5
2528
- run: composer install
2629
- run: ./vendor/bin/phpunit
2730

@@ -32,5 +35,6 @@ jobs:
3235
with:
3336
folder: php
3437
project: ${{ github.event.repository.name }}
35-
secrets: inherit
38+
secrets:
39+
DOC_TOKEN: ${{ secrets.DOC_TOKEN }}
3640

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
composer.lock
33
vendor
44
/.phpunit.result.cache
5+
phpunit.coverage.xml
6+
phpunit.report.xml
7+
*.bak

composer.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@
99
"minimum-stability": "dev",
1010
"prefer-stable": true,
1111
"require": {
12-
"php": ">=8.0",
13-
"byjg/jwt-wrapper": "4.9.*"
12+
"php": ">=8.1 <8.5",
13+
"byjg/jwt-wrapper": "^6.0"
1414
},
1515
"require-dev": {
16-
"phpunit/phpunit": "5.7.*|7.4.*|^9.6"
16+
"phpunit/phpunit": "^10|^11",
17+
"vimeo/psalm": "^5.9|^6.12"
18+
},
19+
"scripts": {
20+
"test": "vendor/bin/phpunit",
21+
"psalm": "vendor/bin/psalm"
1722
},
1823
"license": "MIT"
1924
}

phpunit.xml.dist

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,33 @@ and open the template in the editor.
66
-->
77

88
<!-- see http://www.phpunit.de/wiki/Documentation -->
9-
<phpunit bootstrap="./vendor/autoload.php"
9+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
bootstrap="./vendor/autoload.php"
1011
colors="true"
1112
testdox="true"
12-
convertErrorsToExceptions="true"
13-
convertNoticesToExceptions="true"
14-
convertWarningsToExceptions="true"
15-
convertDeprecationsToExceptions="true"
16-
stopOnFailure="false">
13+
displayDetailsOnTestsThatTriggerDeprecations="true"
14+
displayDetailsOnTestsThatTriggerErrors="true"
15+
displayDetailsOnTestsThatTriggerNotices="true"
16+
displayDetailsOnTestsThatTriggerWarnings="true"
17+
displayDetailsOnPhpunitDeprecations="true"
18+
failOnWarning="true"
19+
failOnNotice="true"
20+
failOnDeprecation="true"
21+
failOnPhpunitDeprecation="true"
22+
stopOnFailure="false"
23+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd">
1724

1825
<php>
1926
<ini name="display_errors" value="On" />
2027
<ini name="display_startup_errors" value="On" />
2128
<ini name="error_reporting" value="E_ALL" />
2229
</php>
2330

24-
<filter>
25-
<whitelist>
31+
<source>
32+
<include>
2633
<directory>./src</directory>
27-
</whitelist>
28-
</filter>
34+
</include>
35+
</source>
2936

3037
<testsuites>
3138
<testsuite name="Test Suite">

psalm.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0"?>
2+
<psalm
3+
errorLevel="4"
4+
resolveFromConfigFile="true"
5+
findUnusedBaselineEntry="true"
6+
findUnusedCode="false"
7+
cacheDirectory="/tmp/psalm"
8+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xmlns="https://getpsalm.org/schema/config"
10+
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd">
11+
12+
<projectFiles>
13+
<directory name="src"/>
14+
<ignoreFiles>
15+
<directory name="vendor"/>
16+
</ignoreFiles>
17+
</projectFiles>
18+
</psalm>

src/JwtSession.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
namespace ByJG\Session;
44

5-
use ByJG\Util\JwtWrapper;
6-
use ByJG\Util\JwtWrapperException;
5+
use ByJG\JwtWrapper\JwtWrapper;
6+
use ByJG\JwtWrapper\JwtWrapperException;
77
use Exception;
88
use SessionHandlerInterface;
99

@@ -64,6 +64,7 @@ protected function replaceSessionHandler(): void
6464
* </p>
6565
* @since 5.4.0
6666
*/
67+
#[\Override]
6768
public function close(): bool
6869
{
6970
return true;
@@ -80,14 +81,15 @@ public function close(): bool
8081
* </p>
8182
* @since 5.4.0
8283
*/
84+
#[\Override]
8385
public function destroy(string $id): bool
8486
{
8587
if (!headers_sent()) {
8688
setcookie(
8789
self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext(),
8890
"",
8991
(time()-3000),
90-
$this->sessionConfig->getCookiePath() ?? "",
92+
$this->sessionConfig->getCookiePath(),
9193
$this->sessionConfig->getCookieDomain() ?? "",
9294
);
9395
}
@@ -99,19 +101,20 @@ public function destroy(string $id): bool
99101
* Cleanup old sessions
100102
*
101103
* @link http://php.net/manual/en/sessionhandlerinterface.gc.php
104+
*
102105
* @param int $max_lifetime <p>
103106
* Sessions that have not updated for
104107
* the last maxlifetime seconds will be removed.
105108
* </p>
106-
* @return int|false <p>
107-
* The return value (usually TRUE on success, FALSE on failure).
108-
* Note this value is returned internally to PHP for processing.
109-
* </p>
109+
*
110+
* @return int|false <p> The return value (usually TRUE on success, FALSE on failure). Note this value is returned internally to PHP for processing. </p>
111+
*
110112
* @since 5.4.0
111113
*/
114+
#[\Override]
112115
public function gc(int $max_lifetime): int|false
113116
{
114-
return true;
117+
return 1;
115118
}
116119

117120
/**
@@ -126,6 +129,7 @@ public function gc(int $max_lifetime): int|false
126129
* </p>
127130
* @since 5.4.0
128131
*/
132+
#[\Override]
129133
public function open(string $path, string $name): bool
130134
{
131135
return true;
@@ -143,6 +147,7 @@ public function open(string $path, string $name): bool
143147
* </p>
144148
* @since 5.4.0
145149
*/
150+
#[\Override]
146151
public function read(string $id): string
147152
{
148153
try {
@@ -184,21 +189,22 @@ public function read(string $id): string
184189
* @throws JwtWrapperException
185190
* @since 5.4.0
186191
*/
192+
#[\Override]
187193
public function write(string $id, string $data): bool
188194
{
189195
$jwt = new JwtWrapper(
190196
$this->sessionConfig->getServerName(),
191197
$this->sessionConfig->getKey()
192198
);
193-
$session_data = $jwt->createJwtData($data, $this->sessionConfig->getTimeoutMinutes() * 60);
199+
$session_data = $jwt->createJwtData(['data' => $data], $this->sessionConfig->getTimeoutMinutes() * 60, 0, null);
194200
$token = $jwt->generateToken($session_data);
195201

196202
if (!headers_sent()) {
197203
setcookie(
198204
self::COOKIE_PREFIX . $this->sessionConfig->getSessionContext(),
199205
$token,
200206
(time()+$this->sessionConfig->getTimeoutMinutes()*60) ,
201-
$this->sessionConfig->getCookiePath() ?? "",
207+
$this->sessionConfig->getCookiePath(),
202208
$this->sessionConfig->getCookieDomain() ?? "",
203209
false,
204210
true
@@ -236,7 +242,7 @@ public function unSerializeSessionData($session_data): array
236242
$num = $pos - $offset;
237243
$varname = substr($session_data, $offset, $num);
238244
$offset += $num + 1;
239-
$data = unserialize(substr($session_data, $offset));
245+
$data = @unserialize(substr($session_data, $offset), ['allowed_classes' => true]);
240246
$return_data[$varname] = $data;
241247
$offset += strlen(serialize($data));
242248
}

src/SessionConfig.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace ByJG\Session;
44

5-
use ByJG\Util\JwtKeyInterface;
6-
use ByJG\Util\JwtKeySecret;
7-
use ByJG\Util\JwtRsaKey;
5+
use ByJG\JwtWrapper\JwtKeyInterface;
6+
use ByJG\JwtWrapper\JwtHashHmacSecret;
7+
use ByJG\JwtWrapper\JwtOpenSSLKey;
88

99
class SessionConfig
1010
{
@@ -53,13 +53,13 @@ public function withCookie($domain, $path = "/"): static
5353

5454
public function withSecret($secret): static
5555
{
56-
$this->jwtKey = new JwtKeySecret($secret);
56+
$this->jwtKey = new JwtHashHmacSecret($secret);
5757
return $this;
5858
}
59-
59+
6060
public function withRsaSecret($private, $public): static
6161
{
62-
$this->jwtKey = new JwtRsaKey($private, $public);
62+
$this->jwtKey = new JwtOpenSSLKey($private, $public);
6363
return $this;
6464
}
6565

tests/JwtSessionTest.php

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<?php
22

3+
use ByJG\JwtWrapper\JwtWrapperException;
34
use ByJG\Session\JwtSession;
45
use ByJG\Session\JwtSessionException;
56
use ByJG\Session\SessionConfig;
6-
use ByJG\Util\JwtWrapperException;
77
use PHPUnit\Framework\TestCase;
8+
use PHPUnit\Framework\Attributes\DataProvider;
89

910
ob_start();
1011
define("SETCOOKIE_FORTEST", "TESTCASE");
@@ -57,7 +58,7 @@ public function testClose()
5758
$this->assertTrue($this->object->close());
5859
}
5960

60-
public function dataProvider(): array
61+
public static function dataProvider(): array
6162
{
6263
$obj = new stdClass();
6364
$obj->prop1 = "value1";
@@ -119,35 +120,21 @@ public function dataProvider(): array
119120
];
120121
}
121122

122-
/**
123-
* @dataProvider dataProvider
124-
* @param $input
125-
* @param $expected
126-
*/
123+
#[DataProvider('dataProvider')]
127124
public function testSerializeSessionData($input, $expected)
128125
{
129126
$result = $this->object->serializeSessionData($input);
130127
$this->assertEquals($expected, $result);
131128
}
132129

133-
/**
134-
* @dataProvider dataProvider
135-
* @param $expected
136-
* @param $input
137-
* @throws Exception
138-
*/
130+
#[DataProvider('dataProvider')]
139131
public function testUnserializeData($expected, $input)
140132
{
141133
$result = $this->object->unSerializeSessionData($input);
142134
$this->assertEquals($expected, $result);
143135
}
144136

145-
/**
146-
* @dataProvider dataProvider
147-
* @param $object
148-
* @param $serialize
149-
* @throws JwtWrapperException
150-
*/
137+
#[DataProvider('dataProvider')]
151138
public function testReadWrite($object, $serialize)
152139
{
153140
$this->object->write("SESSID", $serialize);

0 commit comments

Comments
 (0)