agent foundation

This commit is contained in:
2026-03-06 00:44:52 +01:00
parent 9819cba733
commit 9a08f96c11
199 changed files with 8522 additions and 1880 deletions

View File

@@ -2,11 +2,14 @@
namespace MintyPHP\Service\Auth;
use MintyPHP\Http\SessionStoreInterface;
class MicrosoftOidcStateStoreService
{
private const SESSION_KEY = 'microsoft_oidc_states';
public function __construct(
private readonly SessionStoreInterface $sessionStore,
private readonly int $ttlSeconds = 600,
private readonly int $maxEntries = 50
) {
@@ -25,6 +28,7 @@ class MicrosoftOidcStateStoreService
$payload['created_at'] = (int) ($payload['created_at'] ?? time());
$states[$state] = $payload;
// Cap size to prevent session bloat from many unfinished authorization flows.
if (count($states) > $this->maxEntries) {
uasort($states, static function (array $a, array $b): int {
return ((int) ($a['created_at'] ?? 0)) <=> ((int) ($b['created_at'] ?? 0));
@@ -34,7 +38,7 @@ class MicrosoftOidcStateStoreService
}
}
$_SESSION[self::SESSION_KEY] = $states;
$this->sessionStore->set(self::SESSION_KEY, $states);
}
/**
@@ -53,8 +57,9 @@ class MicrosoftOidcStateStoreService
return ['ok' => false, 'error' => 'state_invalid'];
}
// Remove the state before checking TTL — prevents replay even if the check below rejects it.
unset($states[$state]);
$_SESSION[self::SESSION_KEY] = $states;
$this->sessionStore->set(self::SESSION_KEY, $states);
$createdAt = (int) ($entry['created_at'] ?? 0);
if ($createdAt <= 0 || (time() - $createdAt) > $this->ttlSeconds) {
@@ -66,12 +71,12 @@ class MicrosoftOidcStateStoreService
public function prune(): void
{
$_SESSION[self::SESSION_KEY] = $this->pruneExpiredStates($this->states());
$this->sessionStore->set(self::SESSION_KEY, $this->pruneExpiredStates($this->states()));
}
private function states(): array
{
$states = $_SESSION[self::SESSION_KEY] ?? [];
$states = $this->sessionStore->get(self::SESSION_KEY, []);
return is_array($states) ? $states : [];
}