<?php
// JWT auth with secret "secret" (top-100 brute list) AND alg:none accepted.
header("Content-Type: application/json");

// CORS wide open
if (!empty($_SERVER['HTTP_ORIGIN'])) {
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
    header("Access-Control-Allow-Credentials: true");
}

$SECRET = getenv('JWT_SECRET') ?: 'secret';

function b64url_encode($s) { return rtrim(strtr(base64_encode($s), '+/', '-_'), '='); }
function b64url_decode($s) { return base64_decode(strtr($s, '-_', '+/')); }

function sign($header_json, $payload_json, $secret) {
    $h = b64url_encode($header_json);
    $p = b64url_encode($payload_json);
    $sig = hash_hmac('sha256', "$h.$p", $secret, true);
    return "$h.$p." . b64url_encode($sig);
}

function verify($jwt, $secret) {
    $parts = explode('.', $jwt);
    if (count($parts) < 2) return null;
    [$h, $p] = $parts;
    $header = json_decode(b64url_decode($h), true);
    $payload = json_decode(b64url_decode($p), true);
    if (!$header || !$payload) return null;

    $alg = strtolower($header['alg'] ?? '');

    // VULN 1 — accept alg:none
    if ($alg === 'none' || $alg === '') return $payload;

    // VULN 2 — weak HS256 secret
    if ($alg === 'hs256') {
        if (count($parts) !== 3) return null;
        $sig  = b64url_decode($parts[2]);
        $want = hash_hmac('sha256', "$h.$p", $secret, true);
        if (hash_equals($want, $sig)) return $payload;
    }
    return null;
}

// POST creds -> issue token
$method = $_SERVER['REQUEST_METHOD'];
$body = json_decode(file_get_contents('php://input'), true) ?: [];

if ($method === 'POST' && isset($body['action']) && $body['action'] === 'login') {
    $u = $body['username'] ?? '';
    $p = $body['password'] ?? '';
    // plaintext check — admin / admin123
    if ($u === 'admin' && $p === 'admin123') {
        $jwt = sign(
            json_encode(['alg' => 'HS256', 'typ' => 'JWT']),
            json_encode(['sub' => 'admin', 'role' => 'admin', 'iat' => time(), 'exp' => time() + 3600]),
            $SECRET
        );
        echo json_encode(['token' => $jwt, 'expires_in' => 3600]);
        exit;
    }
    http_response_code(401);
    echo json_encode(['error' => 'bad credentials']);
    exit;
}

// GET — show current session from Authorization: Bearer ...
$hdr = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (preg_match('/Bearer\s+(\S+)/i', $hdr, $m)) {
    $claims = verify($m[1], $SECRET);
    if ($claims) {
        echo json_encode(['authenticated' => true, 'claims' => $claims]);
        exit;
    }
    http_response_code(401);
    echo json_encode(['error' => 'invalid token']);
    exit;
}

echo json_encode([
    'message' => 'POST {action:"login",username,password} to obtain token',
    'example' => ['username' => 'admin', 'password' => 'admin123'],
]);
