bericht/ajax/get_photo.php
Eduard Wisch a31e063e7a
All checks were successful
Deploy bericht / deploy (push) Successful in 1s
PWA: Foto-Galerie mit Zoom und Swipe [deploy]
- Neue API: list_photos.php listet vorhandene Bilder
- Neue API: get_photo.php liefert Bilder per Token aus
- PWA zeigt Galerie mit allen vorhandenen Fotos
- Tippen auf Thumbnail öffnet Vollbild-Viewer
- Pinch-to-Zoom, Doppeltap, Swipe-Navigation
- Galerie aktualisiert sich nach Upload automatisch

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-13 13:09:30 +02:00

72 lines
2.6 KiB
PHP

<?php
/* Liefert ein Foto aus dem Upload-Ordner aus.
* Authentifizierung über Token in der URL.
*
* GET: token, file (Dateiname)
*/
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__.'/../class/upload_token.class.php';
// Token validieren
$token = (string) ($_REQUEST['token'] ?? '');
$tok = BerichtUploadToken::fetchValid($db, $token);
if (!$tok) {
http_response_code(403);
die('Token ungültig');
}
// Dateiname validieren (keine Pfad-Traversal erlauben)
$filename = basename((string) ($_REQUEST['file'] ?? ''));
if (empty($filename)) {
http_response_code(400);
die('Dateiname fehlt');
}
// Upload-Ordner ermitteln
$upload_dir = $tok->getUploadDir();
if (!$upload_dir) {
http_response_code(404);
die('Ordner nicht gefunden');
}
$filepath = $upload_dir . '/' . $filename;
// Prüfen ob Datei existiert und im erlaubten Ordner liegt
$realpath = realpath($filepath);
$realdir = realpath($upload_dir);
if (!$realpath || !$realdir || strpos($realpath, $realdir) !== 0) {
http_response_code(404);
die('Datei nicht gefunden');
}
// Datei ausliefern
$mime = mime_content_type($realpath);
if (!$mime || strpos($mime, 'image') !== 0) {
$mime = 'application/octet-stream';
}
header('Content-Type: ' . $mime);
header('Content-Length: ' . filesize($realpath));
header('Cache-Control: private, max-age=3600');
readfile($realpath);
exit;