Skip to content

Commit 08b47a1

Browse files
committed
Add issuedAt property
1 parent 7077862 commit 08b47a1

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

src/Entities/AccessTokenEntityInterface.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace League\OAuth2\Server\Entities;
1414

15+
use DateTimeImmutable;
1516
use League\OAuth2\Server\CryptKeyInterface;
1617

1718
interface AccessTokenEntityInterface extends TokenInterface
@@ -21,6 +22,16 @@ interface AccessTokenEntityInterface extends TokenInterface
2122
*/
2223
public function setPrivateKey(CryptKeyInterface $privateKey): void;
2324

25+
/**
26+
* Set a datetime value for the issued at value.
27+
*/
28+
public function setIssuedAt(DateTimeImmutable $issuedAt): void;
29+
30+
/**
31+
* Get the issued at datetime value.
32+
*/
33+
public function getIssuedAt(): ?DateTimeImmutable;
34+
2435
/**
2536
* Generate a string representation of the access token.
2637
*/

src/Entities/Traits/AccessTokenTrait.php

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424

2525
trait AccessTokenTrait
2626
{
27-
private CryptKeyInterface $privateKey;
28-
2927
private Configuration $jwtConfiguration;
28+
private CryptKeyInterface $privateKey;
29+
private ?DateTimeImmutable $issuedAt = null;
3030

3131
/**
3232
* Set the private key used to encrypt this access token.
@@ -36,6 +36,22 @@ public function setPrivateKey(CryptKeyInterface $privateKey): void
3636
$this->privateKey = $privateKey;
3737
}
3838

39+
/**
40+
* Set the datetime value the access token was issued at.
41+
*/
42+
public function setIssuedAt(DateTimeImmutable $issuedAt): void
43+
{
44+
$this->issuedAt = $issuedAt;
45+
}
46+
47+
/**
48+
* Get the datetime value the access token was issued at.
49+
*/
50+
public function getIssuedAt(): ?DateTimeImmutable
51+
{
52+
return $this->issuedAt;
53+
}
54+
3955
/**
4056
* Initialise the JWT Configuration.
4157
*/
@@ -61,11 +77,15 @@ private function convertToJWT(): Token
6177
{
6278
$this->initJwtConfiguration();
6379

80+
if ($this->getIssuedAt() === null) {
81+
$this->setIssuedAt(new DateTimeImmutable());
82+
}
83+
6484
return $this->jwtConfiguration->builder()
6585
->permittedFor($this->getClient()->getIdentifier())
6686
->identifiedBy($this->getIdentifier())
67-
->issuedAt(new DateTimeImmutable())
68-
->canOnlyBeUsedAfter(new DateTimeImmutable())
87+
->issuedAt($this->getIssuedAt())
88+
->canOnlyBeUsedAfter($this->getIssuedAt())
6989
->expiresAt($this->getExpiryDateTime())
7090
->relatedTo($this->getSubjectIdentifier())
7191
->withClaim('scopes', $this->getScopes())

tests/ResponseTypes/BearerResponseTypeTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,46 @@ public function testDetermineMissingBearerInHeader(): void
292292
);
293293
}
294294
}
295+
296+
public function testAccessTokenShouldIssueSameTokenIfRequestedTwice(): void
297+
{
298+
$responseType = new BearerTokenResponse();
299+
$responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
300+
$responseType->setEncryptionKey(base64_encode(random_bytes(36)));
301+
302+
$client = new ClientEntity();
303+
$client->setIdentifier('clientName');
304+
305+
$scope = new ScopeEntity();
306+
$scope->setIdentifier('basic');
307+
308+
$accessToken = new AccessTokenEntity();
309+
$accessToken->setIdentifier('abcdef');
310+
$accessToken->setExpiryDateTime((new DateTimeImmutable())->add(new DateInterval('PT1H')));
311+
$accessToken->setClient($client);
312+
$accessToken->addScope($scope);
313+
$accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
314+
$accessToken->setUserIdentifier('userId');
315+
316+
$refreshToken = new RefreshTokenEntity();
317+
$refreshToken->setIdentifier('abcdef');
318+
$refreshToken->setAccessToken($accessToken);
319+
$refreshToken->setExpiryDateTime((new DateTimeImmutable())->add(new DateInterval('PT1H')));
320+
321+
$responseType->setAccessToken($accessToken);
322+
$responseType->setRefreshToken($refreshToken);
323+
324+
$firstResponse = $responseType->generateHttpResponse(new Response());
325+
326+
$firstResponse->getBody()->rewind();
327+
$firstJson = json_decode($firstResponse->getBody()->getContents());
328+
329+
330+
$secondResponse = $responseType->generateHttpResponse(new Response());
331+
332+
$secondResponse->getBody()->rewind();
333+
$secondJson = json_decode($secondResponse->getBody()->getContents());
334+
335+
self::assertEquals($firstJson->access_token, $secondJson->access_token);
336+
}
295337
}

0 commit comments

Comments
 (0)