Files
landing-api/app/Services/Pireon/TokenStore.php
Josep Piguillem 3897113313 Initial commit: Pireon Admin — headless admin panel and public API
Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer
collective, backed by the Pireon OAuth identity server. The public site is a
separate, server-rendered application consuming /api/public/v1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 17:55:27 +02:00

82 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Pireon;
use Illuminate\Contracts\Session\Session;
/**
* Keeps the signed-in panel user's token set in the session and transparently
* refreshes it when it ages out.
*
* Tokens live in the session rather than the database on purpose: they are
* per-session credentials, and logging out or the session expiring should take
* them with it.
*/
class TokenStore
{
protected const KEY = 'pireon.token';
public function __construct(
protected Session $session,
protected PireonClient $client,
) {}
public function put(AccessToken $token): void
{
$this->session->put(self::KEY, $token->toArray());
}
public function get(): ?AccessToken
{
$state = $this->session->get(self::KEY);
return is_array($state) ? AccessToken::fromArray($state) : null;
}
public function forget(): void
{
$this->session->forget(self::KEY);
}
/**
* The current access token, refreshed first if it has expired.
*
* Returns null when there is no token, or when the refresh failed — the
* caller should treat that as "this session is no longer authenticated"
* and send the user back through the login flow.
*/
public function accessToken(): ?string
{
$token = $this->get();
if ($token === null) {
return null;
}
if (! $token->hasExpired()) {
return $token->accessToken;
}
if (! $token->isRefreshable()) {
$this->forget();
return null;
}
try {
$refreshed = $this->client->refresh($token->refreshToken);
} catch (PireonException) {
// The refresh token was revoked or expired upstream.
$this->forget();
return null;
}
$this->put($refreshed);
return $refreshed->accessToken;
}
}