Skip to content

Commit a6d0ba0

Browse files
committed
Auth0 Reset fix for worker mode
1 parent c5426df commit a6d0ba0

File tree

4 files changed

+50
-26
lines changed

4 files changed

+50
-26
lines changed

config/reference.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,8 +1877,8 @@
18771877
* }
18781878
* @psalm-type MercureConfig = array{
18791879
* hubs?: array<string, array{ // Default: []
1880-
* url?: scalar|null, // URL of the hub's publish endpoint // Default: null
1881-
* public_url?: scalar|null, // URL of the hub's public endpoint
1880+
* url?: scalar|null, // URL of the hub's publish endpoint
1881+
* public_url?: scalar|null, // URL of the hub's public endpoint // Default: null
18821882
* jwt?: string|array{ // JSON Web Token configuration.
18831883
* value?: scalar|null, // JSON Web Token to use to publish to this hub.
18841884
* provider?: scalar|null, // The ID of a service to call to provide the JSON Web Token.

src/Query/GetRanking.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
use SpeedPuzzling\Web\Exceptions\PlayerNotFound;
1010
use SpeedPuzzling\Web\Exceptions\PuzzleNotFound;
1111
use SpeedPuzzling\Web\Results\PlayerRanking;
12+
use Symfony\Contracts\Service\ResetInterface;
1213

13-
final class GetRanking
14+
final class GetRanking implements ResetInterface
1415
{
1516
/** @var array<string, array<string, PlayerRanking>> */
1617
private array $allForPlayerCache = [];
@@ -221,4 +222,10 @@ public function ofPuzzleForPlayer(string $puzzleId, string $playerId): null|Play
221222

222223
return $ranking;
223224
}
225+
226+
public function reset(): void
227+
{
228+
$this->allForPlayerCache = [];
229+
$this->ofPuzzleForPlayerCache = [];
230+
}
224231
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SpeedPuzzling\Web\Services;
6+
7+
use Auth0\Symfony\Service;
8+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
9+
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
10+
use Symfony\Component\HttpKernel\Event\RequestEvent;
11+
use Symfony\Component\HttpKernel\KernelEvents;
12+
13+
/**
14+
* Resets Auth0 SDK at the start of each request.
15+
*
16+
* This is critical for FrankenPHP worker mode where PHP processes persist between requests.
17+
* Without this reset, the Auth0 SDK caches user credentials in memory, causing session leakage
18+
* where one user's authentication bleeds into another user's request.
19+
*/
20+
#[AsEventListener(event: KernelEvents::REQUEST, priority: 512)]
21+
final class Auth0SdkResetListener
22+
{
23+
public function __construct(
24+
#[Autowire(service: 'auth0')]
25+
private readonly Service $auth0Service,
26+
) {
27+
}
28+
29+
public function __invoke(RequestEvent $event): void
30+
{
31+
if ($event->isMainRequest() === false) {
32+
return;
33+
}
34+
35+
// Reset Auth0 SDK to force fresh credentials check from session
36+
$reflection = new \ReflectionClass($this->auth0Service);
37+
$property = $reflection->getProperty('sdk');
38+
$property->setValue($this->auth0Service, null);
39+
}
40+
}

src/Services/Auth0ServiceResetter.php

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)