apiRoutesContainingAny([ 'users', 'students', 'parents', 'teacher', 'attendance', 'finance', 'inventory', 'messages', 'dashboard', 'reports', ]), 0, 100); foreach ($privateRoutes as $route) { $method = $this->primaryMethod($route); if ($method !== 'GET') { continue; } $uri = $route->uri(); $response = $this->requestAs($this->actorFor($uri), $method, $uri); $cacheControl = strtolower((string) $response->headers->get('Cache-Control')); $this->assertControlled($response, $method, $uri); $this->assertFalse(str_contains($cacheControl, 'public') && str_contains($cacheControl, 'max-age'), "$method $uri should not mark private API data as publicly cacheable."); } } /** @test */ public function conditional_cache_headers_do_not_bypass_authorization(): void { $routes = array_slice($this->apiRoutesContainingAny(['users', 'students', 'finance', 'attendance', 'dashboard', 'reports']), 0, 70); foreach ($routes as $route) { $method = $this->primaryMethod($route); if ($method !== 'GET') { continue; } $uri = $route->uri(); $response = $this->withHeaders([ 'If-None-Match' => '"attacker-cache-tag"', 'If-Modified-Since' => 'Wed, 21 Oct 2099 07:28:00 GMT', ])->json('GET', $this->materializePath($uri)); $this->assertStatusIn($response, [200, 204, 302, 304, 401, 403, 404, 405, 409, 419, 422], "conditional unauthenticated GET $uri"); $this->assertNotSame(500, $response->getStatusCode(), "conditional unauthenticated GET $uri should not crash."); } } }