mirror of
https://github.com/anikeen-com/id.git
synced 2026-11-03 06:09:31 +00:00
- $user->appSubscriptions(): create (idempotency_key), find, all, checkout, revoke, pause, resume, update against /v1/client/subscriptions with a client credentials token, so apps don't depend on the user's login - user id from the billable's anikeen_id (AnikeenId::useUserIdField()) - ApiException with status, stable error code, isNotFound/isConflict/isTemporary; network errors no longer escape as raw Guzzle exceptions - rejected app tokens are renewed once; asApp() never changes the shared client's token - tests (testbench + Guzzle mock) and CI Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
1.5 KiB
PHP
65 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace Anikeen\Id\Repository;
|
|
|
|
use Anikeen\Id\AnikeenId;
|
|
use Anikeen\Id\Contracts\AppTokenRepository as Repository;
|
|
use Anikeen\Id\Exceptions\RequestFreshAccessTokenException;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
class AppTokenRepository implements Repository
|
|
{
|
|
public const ACCESS_TOKEN_CACHE_KEY = 'anikeen-id:access_token';
|
|
|
|
private AnikeenId $client;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->client = app(AnikeenId::class);
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
public function getAccessToken(): string
|
|
{
|
|
$accessToken = Cache::get(self::ACCESS_TOKEN_CACHE_KEY);
|
|
|
|
if ($accessToken) {
|
|
return $accessToken;
|
|
}
|
|
|
|
return $this->requestFreshAccessToken('*');
|
|
}
|
|
|
|
/**
|
|
* Drop the cached token, e.g. after the ID service rejected it.
|
|
*/
|
|
public function forgetAccessToken(): void
|
|
{
|
|
Cache::forget(self::ACCESS_TOKEN_CACHE_KEY);
|
|
}
|
|
|
|
/**
|
|
* @throws RequestFreshAccessTokenException
|
|
*/
|
|
private function requestFreshAccessToken(string $scope): mixed
|
|
{
|
|
$result = $this->getClient()->retrievingToken('client_credentials', [
|
|
'scope' => $scope,
|
|
]);
|
|
|
|
if (!$result->success()) {
|
|
throw RequestFreshAccessTokenException::fromResponse($result->response());
|
|
}
|
|
|
|
Cache::put(self::ACCESS_TOKEN_CACHE_KEY, $accessToken = $result->data()->access_token, now()->addWeek());
|
|
|
|
return $accessToken;
|
|
}
|
|
|
|
private function getClient(): AnikeenId
|
|
{
|
|
return $this->client;
|
|
}
|
|
} |