diff --git a/serverless.yml b/serverless.yml index 1730b0a..ef0cdbe 100644 --- a/serverless.yml +++ b/serverless.yml @@ -6,6 +6,7 @@ params: cache_ttl: 31536000 avif_enabled: 'true' webp_enabled: 'true' + cors_allow_origin: '*' prod: app_debug: 0 @@ -89,6 +90,7 @@ functions: S3_SECRET_KEY: ${param:s3_secret_key} LOG_STREAM: php://stderr LOG_LEVEL: ${param:log_level} + CORS_ALLOW_ORIGIN: ${param:cors_allow_origin} AVIF_COMPRESSION: ${param:avif_compression} AVIF_ENABLED: ${param:avif_enabled} WEBP_ENABLED: ${param:webp_enabled} diff --git a/src/Cache/Cache.php b/src/Cache/Cache.php index a952bbf..7ef9789 100644 --- a/src/Cache/Cache.php +++ b/src/Cache/Cache.php @@ -23,6 +23,7 @@ final class Cache public function __construct( private readonly Storage $storage, private readonly int $ttl, + private readonly ?string $corsAllowOrigin = '*', ) { } @@ -48,6 +49,10 @@ public function createResponse( $response->headers->set('X-Content-Type-Options', 'nosniff'); $response->setPublic(); + if (true === \is_string($this->corsAllowOrigin)) { + $response->headers->set('Access-Control-Allow-Origin', $this->corsAllowOrigin); + } + if (true === $varyAccept) { $response->headers->set('Vary', 'Accept'); try { diff --git a/src/Container.php b/src/Container.php index 5ff09c6..e064e8d 100644 --- a/src/Container.php +++ b/src/Container.php @@ -47,6 +47,7 @@ final class Container private const string KEY_FETCH_MAX_SIZE = 'fetch_max_size'; private const string KEY_FETCH_ALLOW_REDIRECTS = 'fetch_allow_redirects'; private const string KEY_FORCE_TOKEN = 'force_token'; + private const string KEY_CORS_ALLOW_ORIGIN = 'cors_allow_origin'; /** @var array */ private array $container = []; @@ -229,11 +230,13 @@ private function bootStorage(): void private function bootCache(): void { $this->add(self::KEY_CACHE_TTL, (int) $this->getEnv('CACHE_TTL')); + $this->add(self::KEY_CORS_ALLOW_ORIGIN, $this->getEnv('CORS_ALLOW_ORIGIN') ?? '*'); $this->add( Cache::class, new Cache( $this->get(Storage::class), $this->get(self::KEY_CACHE_TTL), + $this->get(self::KEY_CORS_ALLOW_ORIGIN), ), ); } diff --git a/tests/Cache/CacheTest.php b/tests/Cache/CacheTest.php index 124bd23..e438855 100644 --- a/tests/Cache/CacheTest.php +++ b/tests/Cache/CacheTest.php @@ -14,6 +14,7 @@ namespace BaBeuloula\CdnPhp\Tests\Cache; use BaBeuloula\CdnPhp\Cache\Cache; +use BaBeuloula\CdnPhp\Storage\Storage; use BaBeuloula\CdnPhp\Tests\TestCase; use League\Flysystem\Config; use League\Flysystem\FilesystemAdapter; @@ -55,6 +56,31 @@ public function canCreateAResponseWithoutWebpSupport(): void static::assertNotNull($response->headers->get('Last-Modified')); static::assertSame('Accept', $response->headers->get('Vary')); static::assertSame('nosniff', $response->headers->get('X-Content-Type-Options')); + static::assertSame('*', $response->headers->get('Access-Control-Allow-Origin')); + } + + #[Test] + public function corsHeaderAbsentWhenCorsAllowOriginIsNull(): void + { + /** @var Storage $storage */ + $storage = $this->getContainer(Storage::class); + $cache = new Cache($storage, 3600, null); + + $response = $cache->createResponse(static::TEST_FILENAME, false, false, new Request()); + + static::assertNull($response->headers->get('Access-Control-Allow-Origin')); + } + + #[Test] + public function corsHeaderSetToCustomOrigin(): void + { + /** @var Storage $storage */ + $storage = $this->getContainer(Storage::class); + $cache = new Cache($storage, 3600, 'https://example.com'); + + $response = $cache->createResponse(static::TEST_FILENAME, false, false, new Request()); + + static::assertSame('https://example.com', $response->headers->get('Access-Control-Allow-Origin')); } #[Test]