<?php
/* Mini JWT Helper für die Bericht-API.
 * HS256 only — kein externes Lib nötig.
 *
 * Secret kommt aus $dolibarr_main_instance_unique_id (siehe conf.php),
 * salt'ed mit "bericht-api-v1".
 */

if (!defined('BERICHT_JWT_TTL')) define('BERICHT_JWT_TTL', 30 * 86400); // 30 Tage

function bericht_jwt_secret()
{
    global $dolibarr_main_instance_unique_id;
    $base = $dolibarr_main_instance_unique_id ?? 'fallback-secret-do-not-use';
    return hash('sha256', $base.'|bericht-api-v1');
}

function bericht_b64url_encode($data)
{
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function bericht_b64url_decode($data)
{
    return base64_decode(strtr($data, '-_', '+/').str_repeat('=', (4 - strlen($data) % 4) % 4));
}

function bericht_jwt_encode(array $payload)
{
    $header = array('alg' => 'HS256', 'typ' => 'JWT');
    $h = bericht_b64url_encode(json_encode($header));
    $p = bericht_b64url_encode(json_encode($payload));
    $sig = hash_hmac('sha256', $h.'.'.$p, bericht_jwt_secret(), true);
    return $h.'.'.$p.'.'.bericht_b64url_encode($sig);
}

function bericht_jwt_decode($token)
{
    $parts = explode('.', $token);
    if (count($parts) !== 3) return null;
    list($h, $p, $s) = $parts;
    $expected = bericht_b64url_encode(hash_hmac('sha256', $h.'.'.$p, bericht_jwt_secret(), true));
    if (!hash_equals($expected, $s)) return null;
    $payload = json_decode(bericht_b64url_decode($p), true);
    if (!is_array($payload)) return null;
    if (isset($payload['exp']) && $payload['exp'] < time()) return null;
    return $payload;
}

/**
 * Liest und validiert das Authorization: Bearer <jwt> Header.
 * @return array|null  decoded payload
 */
function bericht_jwt_from_request()
{
    $hdr = '';
    if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
        $hdr = $_SERVER['HTTP_AUTHORIZATION'];
    } elseif (function_exists('apache_request_headers')) {
        $h = apache_request_headers();
        if (isset($h['Authorization'])) $hdr = $h['Authorization'];
    }
    if (!$hdr || stripos($hdr, 'bearer ') !== 0) return null;
    $token = trim(substr($hdr, 7));
    return bericht_jwt_decode($token);
}
