Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
TwigCspExtension
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
4 / 4
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFunctions
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getNonce
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 renderNonceAttr
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Security\Csp;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use Twig\Extension\AbstractExtension;
12use Twig\TwigFunction;
13
14/**
15 * Twig Extension for Content Security Policy (CSP) Level 3 Helpers.
16 *
17 * Exposes dynamic `csp_nonce()` function to Twig templates.
18 *
19 * @package App\Core\Security\Csp
20 */
21final class TwigCspExtension extends AbstractExtension
22{
23    /**
24     * TwigCspExtension constructor.
25     *
26     * @param CspNonceManagerInterface $nonceManager Nonce manager instance.
27     */
28    public function __construct(
29        private readonly CspNonceManagerInterface $nonceManager
30    ) {
31    }
32
33    /**
34     * {@inheritdoc}
35     */
36    public function getFunctions(): array
37    {
38        return [
39            new TwigFunction('csp_nonce', [$this, 'getNonce']),
40            new TwigFunction('csp_script_attr', [$this, 'renderNonceAttr'], ['is_safe' => ['html']]),
41        ];
42    }
43
44    /**
45     * Returns current request CSP nonce string.
46     *
47     * @return string Active nonce.
48     */
49    public function getNonce(): string
50    {
51        return $this->nonceManager->getNonce();
52    }
53
54    /**
55     * Renders safe nonce attribute string for inline script tags: `nonce="..."`.
56     *
57     * @return string Safe HTML attribute.
58     */
59    public function renderNonceAttr(): string
60    {
61        $nonce = htmlspecialchars($this->getNonce(), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
62        return sprintf('nonce="%s"', $nonce);
63    }
64}