Skip to content

Commit

Permalink
Fixed #9 - Added compatibility for refresh tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickbussmann committed Jul 15, 2020
1 parent 413d7dd commit 754769b
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 24 deletions.
50 changes: 26 additions & 24 deletions src/Token/AppleAccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,38 @@ class AppleAccessToken extends AccessToken
*/
public function __construct(array $options = [])
{
if (empty($options['id_token'])) {
throw new InvalidArgumentException('Required option not passed: "id_token"');
}
if (array_key_exists('refresh_token', $options)) {
if (empty($options['id_token'])) {
throw new InvalidArgumentException('Required option not passed: "id_token"');
}

$decoded = null;
$keys = $this->getAppleKey();
$last = end($keys);
foreach ($keys as $key) {
try {
$decoded = JWT::decode($options['id_token'], $key, ['RS256']);
break;
} catch (\Exception $exception) {
if ($last === $key) {
throw $exception;
$decoded = null;
$keys = $this->getAppleKey();
$last = end($keys);
foreach ($keys as $key) {
try {
$decoded = JWT::decode($options['id_token'], $key, ['RS256']);
break;
} catch (\Exception $exception) {
if ($last === $key) {
throw $exception;
}
}
}
}
if (null === $decoded) {
throw new \Exception('Got no data within "id_token"!');
}
$payload = json_decode(json_encode($decoded), true);
if (null === $decoded) {
throw new \Exception('Got no data within "id_token"!');
}
$payload = json_decode(json_encode($decoded), true);

$options['resource_owner_id'] = $payload['sub'];
$options['resource_owner_id'] = $payload['sub'];

if (isset($payload['email_verified']) && $payload['email_verified']) {
$options['email'] = $payload['email'];
}
if (isset($payload['email_verified']) && $payload['email_verified']) {
$options['email'] = $payload['email'];
}

if (isset($payload['is_private_email'])) {
$this->isPrivateEmail = $payload['is_private_email'];
if (isset($payload['is_private_email'])) {
$this->isPrivateEmail = $payload['is_private_email'];
}
}

parent::__construct($options);
Expand Down
57 changes: 57 additions & 0 deletions test/src/Token/AppleAccessTokenTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace League\OAuth2\Client\Test\Token;

use League\OAuth2\Client\Token\AppleAccessToken;
use PHPUnit\Framework\TestCase;
use Mockery as m;

class AppleAccessTokenTest extends TestCase
{
public function tearDown()
{
m::close();
parent::tearDown();
}

/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testCreatingAccessToken()
{
$externalJWTMock = m::mock('overload:Firebase\JWT\JWT');
$externalJWTMock->shouldReceive('decode')
->with('something', 'examplekey', ['RS256'])
->once()
->andReturn([
'sub' => '123.abc.123'
]);

$externalJWKMock = m::mock('overload:Firebase\JWT\JWK');
$externalJWKMock->shouldReceive('parseKeySet')
->once()
->andReturn(['examplekey']);

$accessToken = new AppleAccessToken([
'access_token' => 'access_token',
'token_type' => 'Bearer',
'expires_in' => 3600,
'refresh_token' => 'abc.0.def',
'id_token' => 'something'
]);
$this->assertEquals('something', $accessToken->getIdToken());
$this->assertEquals('123.abc.123', $accessToken->getResourceOwnerId());
$this->assertEquals('access_token', $accessToken->getToken());
}

public function testCreatingRefreshToken()
{
$refreshToken = new AppleAccessToken([
'access_token' => 'access_token',
'token_type' => 'Bearer',
'expires_in' => 3600
]);
$this->assertEquals('access_token', $refreshToken->getToken());
}
}

0 comments on commit 754769b

Please sign in to comment.