<?php
declare(strict_types=1);
namespace App\Framework\Security\ContentSecurityPolicy\Computer;
use App\Repository\GoogleTagManagerRepository;
class PageScriptCSPComputer
{
public function __construct(
private readonly GoogleTagManagerRepository $tagManagerRepository,
) {
}
public function computeShaSet(): array
{
$hashAlgos = ['sha256', 'sha384', 'sha512'];
$supportedAlgos = array_filter($hashAlgos, fn (string $algo) => \in_array($algo, hash_algos(), true));
$usedAlgo = reset($supportedAlgos);
if (false === $usedAlgo) {
return [];
}
$shaSet = [];
$scripts = $this->tagManagerRepository->getAllScripts();
foreach ($scripts as $script) {
$htmlScript = (string) $script->getScript();
if (1 !== preg_match_all('/<script[^>]*+>/i', $htmlScript)) {
continue;
}
preg_match('/^\s*+<script[^>]*+>(?<script>((?s).*))<\/script>\s*+$/i', $htmlScript, $matches);
if (
!\array_key_exists('script', $matches)
|| !\is_string($matches['script'])
|| '' === $matches['script']) {
continue;
}
$hash = hash($usedAlgo, $matches[1], true);
$shaSet[] = sprintf('%s-%s', $usedAlgo, base64_encode($hash));
}
return $shaSet;
}
}