diff --git a/src/Auth/Protect/Protection.php b/src/Auth/Protect/Protection.php index ba56c52714..75031ca3a7 100644 --- a/src/Auth/Protect/Protection.php +++ b/src/Auth/Protect/Protection.php @@ -69,6 +69,12 @@ public function protect() ->protect(); } + public function cacheable() + { + return $this->driver() + ->cacheable(); + } + protected function url() { return URL::tidy(request()->fullUrl()); diff --git a/src/Auth/Protect/Protectors/Protector.php b/src/Auth/Protect/Protectors/Protector.php index cd06d2c6e3..96cd573228 100644 --- a/src/Auth/Protect/Protectors/Protector.php +++ b/src/Auth/Protect/Protectors/Protector.php @@ -36,4 +36,9 @@ public function setConfig($config) return $this; } + + public function cacheable() + { + return false; + } } diff --git a/src/Http/Responses/DataResponse.php b/src/Http/Responses/DataResponse.php index baca6e7896..847023d681 100644 --- a/src/Http/Responses/DataResponse.php +++ b/src/Http/Responses/DataResponse.php @@ -95,7 +95,7 @@ protected function protect() $protection->protect(); - if ($protection->scheme()) { + if ($protection->scheme() && ! $protection->cacheable()) { $this->headers['X-Statamic-Protected'] = true; } diff --git a/tests/Auth/Protect/ProtectionTest.php b/tests/Auth/Protect/ProtectionTest.php index 38005fa7c3..febdfa3eb4 100644 --- a/tests/Auth/Protect/ProtectionTest.php +++ b/tests/Auth/Protect/ProtectionTest.php @@ -147,6 +147,46 @@ public function protect() $this->assertTrue($state->protected); } + #[Test] + public function protector_driver_allows_static_caching() + { + config(['statamic.protect.default' => 'test']); + config(['statamic.protect.schemes.test' => [ + 'driver' => 'test', + ]]); + + app(ProtectorManager::class)->extend('test', function ($app) { + return new class() extends Protector + { + public function protect() + { + // + } + + public function cacheable() + { + return true; + } + }; + }); + + $this->assertTrue($this->protection->cacheable()); + $this->assertTrue($this->protection->driver()->cacheable()); + } + + #[Test] + public function protector_driver_disallows_static_caching() + { + config(['statamic.protect.default' => 'logged_in']); + config(['statamic.protect.schemes.logged_in' => [ + 'driver' => 'auth', + 'form_url' => '/login', + ]]); + + $this->assertFalse($this->protection->cacheable()); + $this->assertFalse($this->protection->driver()->cacheable()); + } + private function createEntryWithScheme($scheme) { return EntryFactory::id('test') diff --git a/tests/FrontendTest.php b/tests/FrontendTest.php index 418fa02a94..634797cc09 100644 --- a/tests/FrontendTest.php +++ b/tests/FrontendTest.php @@ -11,6 +11,8 @@ use Illuminate\Support\Facades\Event; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; +use Statamic\Auth\Protect\ProtectorManager; +use Statamic\Auth\Protect\Protectors\Protector; use Statamic\Events\ResponseCreated; use Statamic\Facades\Blueprint; use Statamic\Facades\Cascade; @@ -373,6 +375,45 @@ public function header_is_added_to_protected_responses() ->assertHeader('X-Statamic-Protected', true); } + #[Test] + public function header_is_not_added_to_cacheable_protected_responses() + { + // config(['statamic.protect.default' => 'test']); + config(['statamic.protect.schemes.test' => [ + 'driver' => 'test', + ]]); + + app(ProtectorManager::class)->extend('test', function ($app) { + return new class() extends Protector + { + public function protect() + { + // + } + + public function cacheable() + { + return true; + } + }; + }); + + $page = $this->createPage('about'); + + $this + ->get('/about') + ->assertOk() + ->assertHeaderMissing('X-Statamic-Protected'); + + $page->set('protect', 'test')->save(); + + $this + ->actingAs(User::make()) + ->get('/about') + ->assertOk() + ->assertHeaderMissing('X-Statamic-Protected'); + } + #[Test] public function key_variables_key_added() {