All checks were successful
Deploy bericht / deploy (push) Successful in 1s
- api/_jwt.php: HS256 JWT encode/decode/from_request, Secret aus
dolibarr_main_instance_unique_id, 7 Tage TTL
- api/_inc.php: gemeinsamer API-Init mit CORS, JSON-Helpers,
api_authenticate() lädt User aus JWT und prüft bericht/read
- api/auth.php: POST { login, password } → JWT mit user + perms
- api/orders.php:
- GET /api/orders.php — Liste der Aufträge des Users (Multi-User
Filter über fk_user_*, Admin sieht alle)
- GET /api/orders.php?id=X — Auftrags-Detail mit Kunde + Berichten
- GET /api/orders.php?id=X&action=photos — Anhänge
- POST /api/orders.php?id=X&action=upload_photo — Foto hochladen,
Bericht wird automatisch angelegt falls nicht vorhanden
- api/reports.php:
- GET /api/reports.php?id=X — Bericht-Detail + Seiten
- POST /api/reports.php?id=X&action=finalize — Status auf final
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
[deploy]
102 lines
3.6 KiB
PHP
102 lines
3.6 KiB
PHP
<?php
|
|
/* Gemeinsamer API-Init für alle Bericht-API-Endpoints.
|
|
*
|
|
* - Lädt Dolibarr ohne Login (NOLOGIN), wir machen User-Auth selbst per JWT
|
|
* - CORS für die PWA
|
|
* - JSON Request/Response Helpers
|
|
* - Authentifiziert per JWT (außer auth.php)
|
|
*/
|
|
|
|
if (!defined('NOLOGIN')) define('NOLOGIN', '1');
|
|
if (!defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1');
|
|
if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1');
|
|
if (!defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1');
|
|
if (!defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1');
|
|
if (!defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1');
|
|
|
|
$res = 0;
|
|
if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
|
|
$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
|
|
while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; }
|
|
if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
|
|
if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
|
|
if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php";
|
|
if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php";
|
|
if (!$res) die("Include of main fails");
|
|
|
|
require_once __DIR__.'/_jwt.php';
|
|
require_once __DIR__.'/../class/bericht.class.php';
|
|
require_once __DIR__.'/../lib/bericht.lib.php';
|
|
|
|
// CORS — die PWA läuft auf der gleichen Domain (subpfad), aber wir sind defensiv
|
|
$allowed_origin = '*'; // bei Bedarf in Konstante BERICHT_API_CORS_ORIGIN packen
|
|
if (getDolGlobalString('BERICHT_API_CORS_ORIGIN')) {
|
|
$allowed_origin = getDolGlobalString('BERICHT_API_CORS_ORIGIN');
|
|
}
|
|
header('Access-Control-Allow-Origin: '.$allowed_origin);
|
|
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
|
|
header('Access-Control-Allow-Headers: Content-Type, Authorization');
|
|
header('Access-Control-Max-Age: 86400');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
|
http_response_code(204);
|
|
exit;
|
|
}
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
function api_send($data, $code = 200)
|
|
{
|
|
http_response_code($code);
|
|
echo json_encode($data, JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
function api_fail($msg, $code = 400)
|
|
{
|
|
api_send(array('error' => $msg), $code);
|
|
}
|
|
|
|
function api_ok($data = array())
|
|
{
|
|
api_send(array_merge(array('ok' => true), $data));
|
|
}
|
|
|
|
function api_input()
|
|
{
|
|
$body = file_get_contents('php://input');
|
|
if (!$body) return $_POST;
|
|
$json = json_decode($body, true);
|
|
return is_array($json) ? $json : $_POST;
|
|
}
|
|
|
|
/**
|
|
* Lädt den User aus dem JWT und liefert das User-Objekt zurück.
|
|
* Beendet bei ungültigem/fehlendem Token.
|
|
*/
|
|
function api_authenticate($db_param = null)
|
|
{
|
|
global $db, $user, $conf;
|
|
if ($db_param) $db = $db_param;
|
|
|
|
$payload = bericht_jwt_from_request();
|
|
if (!$payload || empty($payload['sub'])) {
|
|
api_fail('Token ungültig oder fehlt', 401);
|
|
}
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
|
|
$u = new User($db);
|
|
if ($u->fetch((int) $payload['sub']) <= 0) {
|
|
api_fail('User nicht gefunden', 401);
|
|
}
|
|
if (empty($u->statut)) {
|
|
api_fail('User deaktiviert', 401);
|
|
}
|
|
$u->loadRights();
|
|
$user = $u;
|
|
|
|
if (!$user->hasRight('bericht', 'read')) {
|
|
api_fail('Keine Bericht-Rechte', 403);
|
|
}
|
|
return $user;
|
|
}
|