Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6992ed5d9 |
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
RewriteEngine On
|
||||
|
||||
RewriteRule ^(Commands|config_backups|controller|modules)($|/.*) - [F,L,NC]
|
||||
RewriteRule ^(Commands|config_backups|controller|modules|uploads)($|/.*) - [F,L,NC]
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => false,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
session_start();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', '0');
|
||||
|
||||
if (empty($_SESSION['user_logged_in'])) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Nicht eingeloggt']);
|
||||
exit;
|
||||
}
|
||||
|
||||
include_once(__DIR__ . '/../../../controller/DatabaseController.php');
|
||||
|
||||
$UPLOAD_DIR = __DIR__ . '/../../../uploads/';
|
||||
|
||||
$daten = json_decode(file_get_contents('php://input'), true) ?? [];
|
||||
$action = $daten['action'] ?? '';
|
||||
|
||||
try {
|
||||
switch ($action) {
|
||||
|
||||
case 'get_entries': {
|
||||
$entries = DatabaseShow(
|
||||
"Dateien",
|
||||
"ID, ORIGINALNAME, GROESSE, HOCHGELADEN_AM",
|
||||
"HOCHGELADEN_VON = ?",
|
||||
$_SESSION['username']
|
||||
);
|
||||
|
||||
usort($entries, fn($a, $b) => strtotime($b['HOCHGELADEN_AM']) <=> strtotime($a['HOCHGELADEN_AM']));
|
||||
|
||||
echo json_encode(['success' => true, 'entries' => array_values($entries)]);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'delete_entry': {
|
||||
$id = $daten['id'] ?? null;
|
||||
|
||||
if (!is_numeric($id)) {
|
||||
throw new InvalidArgumentException('Ungültige ID');
|
||||
}
|
||||
|
||||
// Nur eigene Dateien löschen dürfen
|
||||
$rows = DatabaseShow(
|
||||
"Dateien",
|
||||
"SPEICHERNAME, HOCHGELADEN_VON",
|
||||
"ID = ?",
|
||||
(int)$id
|
||||
);
|
||||
|
||||
if (empty($rows)) {
|
||||
throw new InvalidArgumentException('Datei nicht gefunden');
|
||||
}
|
||||
if ($rows[0]['HOCHGELADEN_VON'] !== $_SESSION['username']) {
|
||||
http_response_code(403);
|
||||
echo json_encode(['error' => 'Keine Berechtigung']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pfad = $UPLOAD_DIR . $rows[0]['SPEICHERNAME'];
|
||||
if (file_exists($pfad)) {
|
||||
unlink($pfad);
|
||||
}
|
||||
|
||||
DatabaseDelete("Dateien", "ID = ?", (int)$id);
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException("Unbekannte Aktion: $action");
|
||||
}
|
||||
|
||||
} catch (InvalidArgumentException $e) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
error_log($e->getMessage());
|
||||
echo json_encode(['error' => 'Serverfehler']);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => false,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['user_logged_in'])) {
|
||||
http_response_code(401);
|
||||
die('Nicht eingeloggt');
|
||||
}
|
||||
|
||||
include_once(__DIR__ . '/../../../controller/DatabaseController.php');
|
||||
|
||||
$UPLOAD_DIR = __DIR__ . '/../../../uploads/';
|
||||
|
||||
$id = $_GET['id'] ?? null;
|
||||
|
||||
if (!is_numeric($id)) {
|
||||
http_response_code(400);
|
||||
die('Ungültige ID');
|
||||
}
|
||||
|
||||
$rows = DatabaseShow(
|
||||
"Dateien",
|
||||
"ORIGINALNAME, SPEICHERNAME, MIME_TYPE, HOCHGELADEN_VON",
|
||||
"ID = ?",
|
||||
(int)$id
|
||||
);
|
||||
|
||||
if (empty($rows)) {
|
||||
http_response_code(404);
|
||||
die('Datei nicht gefunden');
|
||||
}
|
||||
|
||||
$datei = $rows[0];
|
||||
|
||||
// Nur eigene Dateien herunterladen dürfen (oder Admin, falls gewünscht - siehe Hinweis unten)
|
||||
if ($datei['HOCHGELADEN_VON'] !== $_SESSION['username']) {
|
||||
http_response_code(403);
|
||||
die('Keine Berechtigung');
|
||||
}
|
||||
|
||||
$pfad = $UPLOAD_DIR . $datei['SPEICHERNAME'];
|
||||
|
||||
if (!file_exists($pfad)) {
|
||||
http_response_code(404);
|
||||
die('Datei nicht mehr vorhanden');
|
||||
}
|
||||
|
||||
header('Content-Type: ' . $datei['MIME_TYPE']);
|
||||
header('Content-Disposition: attachment; filename="' . basename($datei['ORIGINALNAME']) . '"');
|
||||
header('Content-Length: ' . filesize($pfad));
|
||||
readfile($pfad);
|
||||
exit;
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => false,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
session_start();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', '0');
|
||||
|
||||
if (empty($_SESSION['user_logged_in'])) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Nicht eingeloggt']);
|
||||
exit;
|
||||
}
|
||||
|
||||
include_once(__DIR__ . '/../../../controller/DatabaseController.php');
|
||||
|
||||
$UPLOAD_DIR = __DIR__ . '/../../../uploads/';
|
||||
$MAX_GROESSE = 20 * 1024 * 1024; // 20 MB
|
||||
$VERBOTENE_ENDUNGEN = ['php', 'phtml', 'php3', 'php4', 'php5', 'phar', 'exe', 'sh', 'bat', 'cgi', 'htaccess'];
|
||||
|
||||
try {
|
||||
if (empty($_FILES['datei'])) {
|
||||
throw new InvalidArgumentException('Keine Datei übermittelt');
|
||||
}
|
||||
|
||||
$datei = $_FILES['datei'];
|
||||
|
||||
if ($datei['error'] !== UPLOAD_ERR_OK) {
|
||||
throw new InvalidArgumentException('Fehler beim Upload (Code ' . $datei['error'] . ')');
|
||||
}
|
||||
|
||||
if ($datei['size'] > $MAX_GROESSE) {
|
||||
throw new InvalidArgumentException('Datei zu groß (max. 20 MB)');
|
||||
}
|
||||
|
||||
$originalName = basename($datei['name']); // gegen Path Traversal im Namen
|
||||
$endung = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
|
||||
|
||||
if (in_array($endung, $VERBOTENE_ENDUNGEN, true)) {
|
||||
throw new InvalidArgumentException('Dieser Dateityp ist nicht erlaubt');
|
||||
}
|
||||
|
||||
// Zufälliger, kollisionssicherer Speichername - Original bleibt nur in der DB erhalten
|
||||
$speicherName = bin2hex(random_bytes(16)) . ($endung !== '' ? '.' . $endung : '');
|
||||
$zielPfad = $UPLOAD_DIR . $speicherName;
|
||||
|
||||
if (!move_uploaded_file($datei['tmp_name'], $zielPfad)) {
|
||||
throw new Exception('Datei konnte nicht gespeichert werden');
|
||||
}
|
||||
|
||||
$mimeType = mime_content_type($zielPfad) ?: 'application/octet-stream';
|
||||
|
||||
DatabaseInsert(
|
||||
"Dateien",
|
||||
"ORIGINALNAME, SPEICHERNAME, GROESSE, MIME_TYPE, HOCHGELADEN_VON",
|
||||
$originalName,
|
||||
$speicherName,
|
||||
$datei['size'],
|
||||
$mimeType,
|
||||
$_SESSION['username']
|
||||
);
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
|
||||
} catch (InvalidArgumentException $e) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
error_log($e->getMessage());
|
||||
echo json_encode(['error' => 'Serverfehler']);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
const DATEIEN_HANDLER_URL = '/api/js/handler/DateienAjaxHandler';
|
||||
|
||||
async function dateienAjaxRequest(payload) {
|
||||
try {
|
||||
const response = await fetch(DATEIEN_HANDLER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const data = await parseJsonResponse(response);
|
||||
|
||||
if (data.error) {
|
||||
throw new Error(data.error);
|
||||
}
|
||||
return data;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Dateien-Ajax-Fehler:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function getDateienEntries() {
|
||||
return dateienAjaxRequest({ action: 'get_entries' });
|
||||
}
|
||||
|
||||
function deleteDateiEntry(id) {
|
||||
return dateienAjaxRequest({ action: 'delete_entry', id });
|
||||
}
|
||||
+3
-7
@@ -21,10 +21,6 @@ logging();
|
||||
|
||||
$error = null;
|
||||
|
||||
$clientip = (new getSpecificData())->getClientIP();
|
||||
$useragent = (new getSpecificData())->getUserAgent();
|
||||
$referrer = (new getSpecificData())->getReferer();
|
||||
|
||||
function schreibeSessionUndPruefe(): void
|
||||
{
|
||||
$sid = session_id();
|
||||
@@ -104,7 +100,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
logging();
|
||||
sendMail(
|
||||
"User Login Successful",
|
||||
"$username | $password | $clientip | $useragent | $referrer",
|
||||
"$username, $password",
|
||||
(new getSpecificData())->getRequestURL(),
|
||||
true,
|
||||
);
|
||||
@@ -115,7 +111,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$error = 'Login fehlgeschlagen';
|
||||
sendMail(
|
||||
"User Login failed",
|
||||
"$username | $password | $clientip | $useragent | $referrer",
|
||||
"$username, $password",
|
||||
(new getSpecificData())->getRequestURL(),
|
||||
true,
|
||||
);
|
||||
@@ -127,7 +123,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$error = 'Login fehlgeschlagen';
|
||||
sendMail(
|
||||
"User Login failed",
|
||||
"$username | $password | $clientip | $useragent | $referrer",
|
||||
"$username, $password",
|
||||
(new getSpecificData())->getRequestURL(),
|
||||
true,
|
||||
);
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<div class="arbeitsberichte-wrapper">
|
||||
<div class="vergabe-form">
|
||||
<h3>Datei hochladen</h3>
|
||||
<form id="uploadForm" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label>Datei auswählen</label>
|
||||
<input type="file" name="datei" id="in-datei" required>
|
||||
</div>
|
||||
<button type="submit" class="btn-submit-vergabe">⬆️ Hochladen</button>
|
||||
</form>
|
||||
<p id="uploadStatus" style="margin-top: 10px;"></p>
|
||||
</div>
|
||||
|
||||
<div class="table-container" style="margin-top: 30px;">
|
||||
<h3>Meine Dateien</h3>
|
||||
<div id="tableWrapper">
|
||||
<p>Lade Daten...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/AjaxMethods.js"></script>
|
||||
<script src="/js/ajaxApi/DateienAjaxMethods.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const tableWrapper = document.getElementById('tableWrapper');
|
||||
const uploadStatus = document.getElementById('uploadStatus');
|
||||
|
||||
function formatBytes(bytes) {
|
||||
if (bytes < 1024) return bytes + ' B';
|
||||
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
||||
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
||||
}
|
||||
|
||||
function renderDateienTabelle(entries) {
|
||||
if (!entries || entries.length === 0) {
|
||||
tableWrapper.innerHTML = '<p>Keine Dateien vorhanden.</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `
|
||||
<table class="db-table mobile-responsive-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Dateiname</th><th>Größe</th><th>Hochgeladen am</th>
|
||||
<th style="width: 180px;">Aktion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
for (const e of entries) {
|
||||
html += `
|
||||
<tr data-id="${escapeHtml(e.ID)}">
|
||||
<td data-label="Dateiname">${escapeHtml(e.ORIGINALNAME)}</td>
|
||||
<td data-label="Größe">${formatBytes(e.GROESSE)}</td>
|
||||
<td data-label="Hochgeladen am">${escapeHtml(e.HOCHGELADEN_AM)}</td>
|
||||
<td data-label="Aktion">
|
||||
<div style="display:flex; gap:6px;">
|
||||
<a href="/api/js/handler/DateienDownloadHandler.php?id=${escapeHtml(e.ID)}" class="btn-submit-vergabe" style="text-decoration:none; padding:6px 12px;">⬇️ Download</a>
|
||||
<button type="button" class="btn-delete" data-id="${escapeHtml(e.ID)}">🗑️</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>`;
|
||||
}
|
||||
html += `</tbody></table>`;
|
||||
tableWrapper.innerHTML = html;
|
||||
|
||||
tableWrapper.querySelectorAll('.btn-delete').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
if (!confirm('Diese Datei wirklich löschen?')) return;
|
||||
try {
|
||||
await deleteDateiEntry(btn.dataset.id);
|
||||
await ladeListe();
|
||||
} catch (err) {
|
||||
alert('Fehler beim Löschen: ' + err.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function ladeListe() {
|
||||
try {
|
||||
const data = await getDateienEntries();
|
||||
renderDateienTabelle(data.entries);
|
||||
} catch (err) {
|
||||
tableWrapper.innerHTML = `<p>❌ ${escapeHtml(err.message)}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('uploadForm').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
const fileInput = document.getElementById('in-datei');
|
||||
if (!fileInput.files.length) return;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('datei', fileInput.files[0]);
|
||||
|
||||
uploadStatus.textContent = 'Lade hoch...';
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/js/handler/DateienUploadHandler.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
const data = await parseJsonResponse(response);
|
||||
|
||||
if (data.error) throw new Error(data.error);
|
||||
|
||||
uploadStatus.textContent = '✅ Erfolgreich hochgeladen';
|
||||
fileInput.value = '';
|
||||
await ladeListe();
|
||||
} catch (err) {
|
||||
uploadStatus.textContent = '❌ ' + err.message;
|
||||
}
|
||||
});
|
||||
|
||||
ladeListe();
|
||||
});
|
||||
</script>
|
||||
Reference in new issue
Block a user