bericht/api/_jwt.php
Eduard Wisch 641e16a2bc
All checks were successful
Deploy bericht / deploy (push) Successful in 5s
[deploy] API: Schnell-Auftrag-Anlage + Kunden-Defaults + JWT 30 Tage
- POST /api/orders.php?action=create: legt Draft-Auftrag an, übernimmt
  Kunden-Defaults (Zahlungsbedingung, Zahlart, Bankkonto, Incoterms,
  Lieferadresse) und setzt Hauptansprechpartner als externen Kontakt.
  Titel wird in Extrafield options_auftragsbeschreibung abgelegt.
- /api/customers.php: liefert cond_reglement_label + mode_reglement_label
  damit die PWA die übernommenen Defaults anzeigen kann.
- JWT-TTL von 7 auf 30 Tage hochgesetzt — deckt Urlaubszeiten ab und
  verhindert häufiges Neu-Anmelden.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 17:42:39 +02:00

66 lines
2.1 KiB
PHP

<?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);
}