feat: api/photo.php — Foto-Auslieferung mit JWT-Auth für PWA
All checks were successful
Deploy bericht / deploy (push) Successful in 1s
All checks were successful
Deploy bericht / deploy (push) Successful in 1s
Neuer Endpoint liefert Dateien aus DOL_DATA_ROOT aus, geschützt per JWT statt Dolibarr-Session. Whitelist auf facture/commande/propal/ bericht. Optional size=small/mini für Thumbs (Dolibarr _small Variante). CORS-Header damit PWA direkt zugreifen kann. Die PWA kann damit Anhang-Bilder in der Auftrags-Detail-Ansicht rendern — vorher nutzte sie document.php was nur mit Session ging und deshalb im Standalone-Mode leer blieb. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> [deploy]
This commit is contained in:
parent
3069453823
commit
95701ed2d6
1 changed files with 52 additions and 0 deletions
52
api/photo.php
Normal file
52
api/photo.php
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
/* GET /api/photo.php?relpath=<path>
|
||||||
|
* Liefert eine Datei aus DOL_DATA_ROOT aus, authentifiziert per JWT.
|
||||||
|
* Whitelist: nur facture/, commande/, propal/, bericht/
|
||||||
|
*
|
||||||
|
* Für den Thumb-Request der PWA werden auch Thumbnails ausgeliefert
|
||||||
|
* (Dolibarr legt <name>_small.png unter thumbs/ ab).
|
||||||
|
*
|
||||||
|
* Query:
|
||||||
|
* relpath — relativer Pfad unter DOL_DATA_ROOT
|
||||||
|
* size=small|mini (optional, nutzt automatisch das Thumb)
|
||||||
|
*/
|
||||||
|
require_once __DIR__.'/_inc.php';
|
||||||
|
|
||||||
|
api_authenticate();
|
||||||
|
global $db, $user;
|
||||||
|
|
||||||
|
$relpath = (string) ($_GET['relpath'] ?? '');
|
||||||
|
$size = (string) ($_GET['size'] ?? '');
|
||||||
|
|
||||||
|
if (empty($relpath)) api_fail('relpath fehlt');
|
||||||
|
|
||||||
|
// Whitelist
|
||||||
|
if (!preg_match('#^(facture|commande|propal|bericht)/#', $relpath)) {
|
||||||
|
api_fail('Pfad nicht erlaubt', 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
$full = bericht_resolve_data_path($relpath);
|
||||||
|
if (!$full || !file_exists($full)) api_fail('Datei nicht gefunden', 404);
|
||||||
|
|
||||||
|
// Thumb-Variante (kleiner, schneller)
|
||||||
|
if ($size === 'small' || $size === 'mini') {
|
||||||
|
$dir = dirname($full);
|
||||||
|
$base = pathinfo($full, PATHINFO_FILENAME);
|
||||||
|
$ext = pathinfo($full, PATHINFO_EXTENSION);
|
||||||
|
$thumb = $dir.'/thumbs/'.$base.'_'.$size.'.'.$ext;
|
||||||
|
if (file_exists($thumb)) {
|
||||||
|
$full = $thumb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content-Type aus mimetype
|
||||||
|
$mime = function_exists('dol_mimetype') ? dol_mimetype($full) : 'application/octet-stream';
|
||||||
|
|
||||||
|
// Binary ausliefern — header() ersetzt vorherigen JSON Content-Type
|
||||||
|
header_remove('Content-Type');
|
||||||
|
header('Content-Type: '.$mime);
|
||||||
|
header('Content-Length: '.filesize($full));
|
||||||
|
header('Cache-Control: private, max-age=3600');
|
||||||
|
header('Access-Control-Allow-Origin: *');
|
||||||
|
readfile($full);
|
||||||
|
exit;
|
||||||
Loading…
Reference in a new issue