diff --git a/src/HttpClient/OAuth2HttpClient.php b/src/HttpClient/OAuth2HttpClient.php index 4ef8e3d..95c4cc5 100644 --- a/src/HttpClient/OAuth2HttpClient.php +++ b/src/HttpClient/OAuth2HttpClient.php @@ -25,7 +25,6 @@ public function __construct( private readonly HttpClientInterface $client, private readonly OAuth2Configuration $configuration, private readonly Serializer $serializer, - ) { } diff --git a/src/Util/HttpUtil.php b/src/Util/HttpUtil.php index cc597ad..8d32c55 100644 --- a/src/Util/HttpUtil.php +++ b/src/Util/HttpUtil.php @@ -110,16 +110,9 @@ public function storeJwtOnResponse(Response $response, Token $token, DateTimeImm $signature, $lifetime ); - $refreshTokenExistenceCookie = $this->createCookie( - $this->cookieConfiguration->getRefreshTokenExistenceCookieName(), - '1', - $this->cookieConfiguration->getRefreshTokenLifetime(), - false - ); $response->headers->setCookie($payloadCookie); $response->headers->setCookie($signatureCookie); - $response->headers->setCookie($refreshTokenExistenceCookie); } public function storeRefreshTokenOnResponse(Response $response, RefreshTokenDto $refreshTokenDto): void @@ -130,7 +123,15 @@ public function storeRefreshTokenOnResponse(Response $response, RefreshTokenDto $this->cookieConfiguration->getRefreshTokenLifetime(), ); + $refreshTokenExistenceCookie = $this->createCookie( + $this->cookieConfiguration->getRefreshTokenExistenceCookieName(), + '1', + $this->cookieConfiguration->getRefreshTokenLifetime(), + false + ); + $response->headers->setCookie($refreshTokenCookie); + $response->headers->setCookie($refreshTokenExistenceCookie); } public function storeDeviceIdOnResponse(Response $response, string $deviceId): void diff --git a/tests/Util/HttpUtilTest.php b/tests/Util/HttpUtilTest.php new file mode 100644 index 0000000..d4d026c --- /dev/null +++ b/tests/Util/HttpUtilTest.php @@ -0,0 +1,85 @@ +jwtConfiguration = new JwtConfiguration( + audience: 'anz', + algorithm: 'ES256', + publicCert: base64_decode('LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFT0hIQzMvVDZ3cnVNTk40OTBqVE1maXNFa1BoTQp5eFNiQm1DK0hSYWF2Z1dLM25aNG1HNFlmVDRxMmF1L3V4TktBTjJvODJOdW84VTQ0ZXZkcExkQUhBPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==', true), + privateCert: base64_decode('LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU9OdDBIdEdzUGdRRytKY2VGUk5GdlRZMVVVeDVITTdqQzNVS1ZHRHBlS0tvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFT0hIQzMvVDZ3cnVNTk40OTBqVE1maXNFa1BoTXl4U2JCbUMrSFJhYXZnV0szblo0bUc0WQpmVDRxMmF1L3V4TktBTjJvODJOdW84VTQ0ZXZkcExkQUhBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=', true), + lifetime: 3_600 + ); + $this->jwtUtil = new JwtUtil($this->jwtConfiguration); + + $cookieConfiguration = new CookieConfiguration( + domain: '.example.com', + secure: true, + jwtPayloadCookieName: 'qux', + jwtSignatureCookieName: 'quux', + deviceIdCookieName: 'corge', + refreshTokenCookieName: 'garply', + refreshTokenExistenceCookieName: 'grault', + refreshTokenLifetime: 3600, + ); + + $this->httpUtil = new HttpUtil( + cookieConfiguration: $cookieConfiguration, + jwtConfiguration: $this->jwtConfiguration, + authRedirectDefaultUrl: 'https://example.com', + authRedirectQueryUrlAllowedPattern: '^https?://(.*)\.example\.com$' + ); + } + + public function testStoreJwtOnResponse(): void + { + $response = new Response(); + $token = $this->jwtUtil->create('123'); + $expireAt = new DateTimeImmutable(sprintf('+%d seconds', $this->jwtConfiguration->getLifetime())); + $this->httpUtil->storeJwtOnResponse($response, $token, $expireAt); + + $cookies = $response->headers->getCookies(); + $this->assertCount(2, $cookies); + + /** @var Cookie $payloadCookie */ + $payloadCookie = current( + array_filter($cookies, static function (Cookie $cookie) { + return $cookie->getName() === 'qux'; + }) + ); + + /** @var Cookie $signCookie */ + $signCookie = current( + array_filter($cookies, static function (Cookie $cookie) { + return $cookie->getName() === 'quux'; + }) + ); + + $this->assertSame($token->toString(), $payloadCookie->getValue() . '.' . $signCookie->getValue()); + $this->assertTrue($payloadCookie->isSecure()); + $this->assertFalse($payloadCookie->isHttpOnly()); + $this->assertSame('.example.com', $payloadCookie->getDomain()); + + $this->assertTrue($signCookie->isSecure()); + $this->assertTrue($signCookie->isHttpOnly()); + $this->assertSame('.example.com', $signCookie->getDomain()); + } +} diff --git a/tests/Util/JwtUtilTest.php b/tests/Util/JwtUtilTest.php index cd56f3f..cad0bd5 100644 --- a/tests/Util/JwtUtilTest.php +++ b/tests/Util/JwtUtilTest.php @@ -22,8 +22,8 @@ protected function setUp(): void $this->jwtConfiguration = new JwtConfiguration( audience: 'anz', algorithm: 'ES256', - publicCert: base64_decode('LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFT0hIQzMvVDZ3cnVNTk40OTBqVE1maXNFa1BoTQp5eFNiQm1DK0hSYWF2Z1dLM25aNG1HNFlmVDRxMmF1L3V4TktBTjJvODJOdW84VTQ0ZXZkcExkQUhBPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=='), - privateCert: base64_decode('LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU9OdDBIdEdzUGdRRytKY2VGUk5GdlRZMVVVeDVITTdqQzNVS1ZHRHBlS0tvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFT0hIQzMvVDZ3cnVNTk40OTBqVE1maXNFa1BoTXl4U2JCbUMrSFJhYXZnV0szblo0bUc0WQpmVDRxMmF1L3V4TktBTjJvODJOdW84VTQ0ZXZkcExkQUhBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo='), + publicCert: base64_decode('LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFT0hIQzMvVDZ3cnVNTk40OTBqVE1maXNFa1BoTQp5eFNiQm1DK0hSYWF2Z1dLM25aNG1HNFlmVDRxMmF1L3V4TktBTjJvODJOdW84VTQ0ZXZkcExkQUhBPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==', true), + privateCert: base64_decode('LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU9OdDBIdEdzUGdRRytKY2VGUk5GdlRZMVVVeDVITTdqQzNVS1ZHRHBlS0tvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFT0hIQzMvVDZ3cnVNTk40OTBqVE1maXNFa1BoTXl4U2JCbUMrSFJhYXZnV0szblo0bUc0WQpmVDRxMmF1L3V4TktBTjJvODJOdW84VTQ0ZXZkcExkQUhBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=', true), lifetime: 3_600 ); $this->jwtUtil = new JwtUtil($this->jwtConfiguration); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 9b0a80c..53ab368 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,5 +2,4 @@ declare(strict_types=1); -require dirname(__DIR__).'/vendor/autoload.php'; - +require dirname(__DIR__) . '/vendor/autoload.php';