HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/hi.naniguide.com/app/Http/Middleware/VerifyWordPressSignature.php
<?php

namespace App\Http\Middleware;

use App\Models\WordPressIntegration;
use App\Services\WordPressPluginBrandingService;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class VerifyWordPressSignature
{
    public function __construct(
        private readonly WordPressPluginBrandingService $wordpressPluginBrandingService
    ) {
    }

    public function handle(Request $request, Closure $next)
    {
        $customer = $request->user('sanctum');
        if (!$customer) {
            abort(401);
        }

        $integration = WordPressIntegration::query()->firstOrCreate(
            ['customer_id' => $customer->id],
            [
                'signing_secret' => Str::random(64),
                'last_rotated_at' => now(),
            ]
        );

        $acceptedHeaders = $this->wordpressPluginBrandingService->acceptedHeaderNames();
        $timestamp = '';
        foreach (($acceptedHeaders['timestamp'] ?? []) as $headerName) {
            $timestamp = (string) $request->header($headerName, '');
            if ($timestamp !== '') {
                break;
            }
        }

        $signature = '';
        foreach (($acceptedHeaders['signature'] ?? []) as $headerName) {
            $signature = (string) $request->header($headerName, '');
            if ($signature !== '') {
                break;
            }
        }

        if ($timestamp === '' || $signature === '') {
            return response()->json(['message' => 'Missing signature'], 401);
        }

        if (!ctype_digit($timestamp)) {
            return response()->json(['message' => 'Invalid timestamp'], 401);
        }

        $ts = (int) $timestamp;
        $now = time();
        $skew = abs($now - $ts);

        if ($skew > 300) {
            return response()->json(['message' => 'Signature expired'], 401);
        }

        $externalId = trim((string) $request->input('external_id', ''));
        if ($externalId === '') {
            return response()->json(['message' => 'external_id is required'], 422);
        }

        $cacheKey = 'wp_event:' . $customer->id . ':' . hash('sha256', $externalId);
        if (!Cache::add($cacheKey, 1, now()->addDay())) {
            return response()->json(['message' => 'Duplicate event'], 409);
        }

        $body = (string) $request->getContent();
        $bodyHash = hash('sha256', $body);

        $method = strtoupper($request->getMethod());
        $path = '/' . ltrim($request->path(), '/');

        $signed = $ts . "\n" . $method . "\n" . $path . "\n" . $bodyHash;
        $expected = hash_hmac('sha256', $signed, (string) $integration->signing_secret);

        if (!hash_equals($expected, $signature)) {
            Cache::forget($cacheKey);
            return response()->json(['message' => 'Invalid signature'], 401);
        }

        $request->attributes->set('wp_integration_id', $integration->id);

        return $next($request);
    }
}