Skip to content

Commit 02fc40f

Browse files
committed
Fix for token refresh: Always store scopes in tokens file, as they are also used in refreshToken()
1 parent be7d4b6 commit 02fc40f

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

src/Bexio/AbstractClient.php

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Bexio;
44

5+
use Bexio\Exception\BexioClientException;
56
use Jumbojett\OpenIDConnectClient;
67

78
abstract class AbstractClient
@@ -26,11 +27,12 @@ abstract class AbstractClient
2627

2728
private ?string $refreshToken = null;
2829

30+
private array $scopes = [];
31+
2932
public function __construct(
3033
public string $clientId,
3134
public string $clientSecret
32-
) {
33-
}
35+
) {}
3436

3537
public function setAccessToken(string $accessToken): self
3638
{
@@ -54,11 +56,23 @@ public function getRefreshToken(): ?string
5456
return $this->refreshToken;
5557
}
5658

59+
public function setScopes(array|string $scopes): self
60+
{
61+
$this->scopes = is_array($scopes) ? $scopes : explode(' ', $scopes);
62+
return $this;
63+
}
64+
65+
public function getScopes(): array
66+
{
67+
return $this->scopes;
68+
}
69+
5770
public function persistTokens(string $tokensFile): bool
5871
{
5972
return file_put_contents($tokensFile, json_encode([
6073
'accessToken' => $this->getAccessToken(),
6174
'refreshToken' => $this->getRefreshToken(),
75+
'scope' => implode(' ', $this->getScopes()),
6276
])) !== false;
6377
}
6478

@@ -71,6 +85,7 @@ public function loadTokens(string $tokensFile): self
7185

7286
$this->setAccessToken($tokens->accessToken);
7387
$this->setRefreshToken($tokens->refreshToken);
88+
$this->setScopes($tokens->scope ?? []);
7489

7590
// Refresh access token if it is expired
7691
if ($this->isAccessTokenExpired()) {
@@ -88,23 +103,22 @@ public function getOpenIDConnectClient(): OpenIDConnectClient
88103
$this->clientId,
89104
$this->clientSecret
90105
);
106+
$oidc->addScope($this->scopes);
91107
$oidc->setAccessToken($this->accessToken);
92108
return $oidc;
93109
}
94110

95111
public function authenticate(string|array $scopes, string $redirectUrl): self
96112
{
97-
if (! is_array($scopes)) {
98-
$scopes = explode(' ', $scopes);
99-
}
113+
$this->setScopes($scopes);
100114

101115
$oidc = $this->getOpenIDConnectClient();
102116
$oidc->setRedirectURL($redirectUrl);
103-
$oidc->addScope($scopes);
104117
$oidc->authenticate();
105118

106119
$this->setAccessToken($oidc->getAccessToken());
107120
$this->setRefreshToken($oidc->getRefreshToken());
121+
$this->setScopes($oidc->getScopes());
108122

109123
return $this;
110124
}
@@ -122,9 +136,13 @@ public function isAccessTokenExpired($gracePeriod = 30): bool
122136
public function refreshToken(): self
123137
{
124138
$oidc = $this->getOpenIDConnectClient();
125-
$oidc->refreshToken($this->getRefreshToken());
139+
$json = $oidc->refreshToken($this->getRefreshToken());
140+
if ($json->error ?? null) {
141+
throw new BexioClientException("$json->error: ".($json->error_description ?? '(no description)'));
142+
}
126143
$this->setAccessToken($oidc->getAccessToken());
127144
$this->setRefreshToken($oidc->getRefreshToken());
145+
$this->setScopes($oidc->getScopes());
128146
return $this;
129147
}
130148

0 commit comments

Comments
 (0)