nhance/app/Libraries/DigitMotor/DigitAuthClient.php
2026-07-21 09:32:13 +05:30

111 lines
3.3 KiB
PHP

<?php
namespace App\Libraries\DigitMotor;
use App\Models\MotorTokenModel;
use Config\DigitMotor as DigitMotorConfig;
/**
* Owns Digit OneAPI token lifecycle (cache + refresh).
*/
class DigitAuthClient
{
protected DigitMotorConfig $config;
protected MotorTokenModel $tokenModel;
public function __construct(?DigitMotorConfig $config = null)
{
$this->config = $config ?? config('DigitMotor');
$this->tokenModel = new MotorTokenModel();
helper('api');
}
/**
* Return a valid Bearer access token, refreshing from Digit when needed.
*
* @throws DigitApiException
*/
public function getToken(bool $forceRefresh = false): string
{
if (!$forceRefresh) {
$cached = $this->tokenModel->getByEnvironment($this->config->environment);
if ($cached && !empty($cached['access_token']) && !empty($cached['expires_at'])) {
$expiresAt = strtotime($cached['expires_at']);
if ($expiresAt !== false && ($expiresAt - $this->config->tokenLeewaySec) > time()) {
return $cached['access_token'];
}
}
}
return $this->fetchAndStoreToken();
}
/**
* Force refresh (e.g. after 401).
*
* @throws DigitApiException
*/
public function refreshToken(): string
{
return $this->getToken(true);
}
/**
* @throws DigitApiException
*/
protected function fetchAndStoreToken(): string
{
if ($this->config->username === '' || $this->config->password === '') {
throw new DigitApiException(
'Digit Motor credentials are not configured. Set DIGIT_MOTOR_USERNAME and DIGIT_MOTOR_PASSWORD in .env.',
'CONFIG',
0
);
}
$url = $this->config->baseUrl . $this->config->authPath;
$headers = ['Content-Type: application/json'];
$body = [
'username' => $this->config->username,
'password' => $this->config->password,
];
$response = call_third_party_api($url, 'POST', $headers, $body);
$httpCode = (int) ($response['code'] ?? 0);
$data = $response['data'] ?? [];
if (is_string($data)) {
$decoded = json_decode($data, true);
$data = is_array($decoded) ? $decoded : [];
}
$accessToken = $data['access_token']
?? $data['accessToken']
?? $data['token']
?? null;
if (empty($accessToken) || empty($response['status'])) {
$msg = $data['message'] ?? $data['error'] ?? 'Digit token generation failed.';
throw new DigitApiException(
is_string($msg) ? $msg : 'Digit token generation failed.',
$data['code'] ?? (string) $httpCode,
$httpCode,
$data
);
}
$expiresIn = (int) ($data['expires_in'] ?? $data['expiresIn'] ?? 900);
$refreshToken = $data['refresh_token'] ?? $data['refreshToken'] ?? null;
$expiresAt = date('Y-m-d H:i:s', time() + max(60, $expiresIn));
$this->tokenModel->upsertToken(
$this->config->environment,
$accessToken,
$refreshToken,
$expiresAt
);
return $accessToken;
}
}