diff --git a/assets/modules/analytics.js b/assets/modules/analytics.js index 68e888b..2868ca9 100644 --- a/assets/modules/analytics.js +++ b/assets/modules/analytics.js @@ -1,4 +1,4 @@ -const ENDPOINT = '/t' +let ENDPOINT = '/t' const SK_UID = '_u' const SK_HASH = '_h' @@ -86,7 +86,9 @@ async function trackPageView(visitor) { export async function initAnalytics() { const keyB64 = document.body.dataset.k - if (!keyB64) return + const ep = document.body.dataset.e + if (!keyB64 || !ep) return + ENDPOINT = ep try { encKey = await importKey(keyB64) diff --git a/src/Controller/AnalyticsController.php b/src/Controller/AnalyticsController.php index 3395e62..0253292 100644 --- a/src/Controller/AnalyticsController.php +++ b/src/Controller/AnalyticsController.php @@ -11,17 +11,25 @@ use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Routing\Attribute\Route; class AnalyticsController extends AbstractController { - #[Route('/t', name: 'app_analytics_track', methods: ['POST'])] + #[Route('/t/{token}', name: 'app_analytics_track', methods: ['POST'])] public function track( + string $token, + #[Autowire('%kernel.secret%')] string $appSecret, Request $request, AnalyticsCryptoService $crypto, EntityManagerInterface $em, MessageBusInterface $bus, ): Response { + $expectedToken = substr(hash('sha256', $appSecret.'_endpoint'), 0, 8); + if (!hash_equals($expectedToken, $token)) { + return new Response('', 404); + } + $body = $request->getContent(); $envelope = json_decode($body, true); diff --git a/src/Twig/AnalyticsExtension.php b/src/Twig/AnalyticsExtension.php index 45f9317..b7e8a82 100644 --- a/src/Twig/AnalyticsExtension.php +++ b/src/Twig/AnalyticsExtension.php @@ -3,20 +3,26 @@ namespace App\Twig; use App\Service\AnalyticsCryptoService; +use Symfony\Component\DependencyInjection\Attribute\Autowire; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class AnalyticsExtension extends AbstractExtension implements GlobalsInterface { + private string $endpointToken; + public function __construct( private AnalyticsCryptoService $crypto, + #[Autowire('%kernel.secret%')] string $appSecret, ) { + $this->endpointToken = substr(hash('sha256', $appSecret.'_endpoint'), 0, 8); } public function getGlobals(): array { return [ 'analytics_key' => $this->crypto->getKeyForJs(), + 'analytics_endpoint' => '/t/'.$this->endpointToken, ]; } } diff --git a/templates/base.html.twig b/templates/base.html.twig index 573d55a..53da635 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -84,7 +84,7 @@ {% endblock %} {% block head %}{% endblock %} - +