116 lines
3.5 KiB
PHP
116 lines
3.5 KiB
PHP
<?php
|
|
/**
|
|
* SPA Backup API - Speichert SPA-Backups in Nextcloud
|
|
* URL: https://docs.artetui.de/api/backup.php
|
|
*/
|
|
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: https://docs.artetui.de');
|
|
header('Access-Control-Allow-Methods: POST, OPTIONS');
|
|
header('Access-Control-Allow-Headers: Content-Type');
|
|
|
|
// Preflight für CORS
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
|
http_response_code(200);
|
|
exit;
|
|
}
|
|
|
|
// Nur POST erlauben
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['error' => 'Method not allowed']);
|
|
exit;
|
|
}
|
|
|
|
// Konfiguration aus .env laden
|
|
$envFile = __DIR__ . '/spa-backup-api.env';
|
|
if (file_exists($envFile)) {
|
|
$lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
foreach ($lines as $line) {
|
|
if (strpos(trim($line), '#') === 0) continue;
|
|
list($key, $value) = explode('=', $line, 2);
|
|
putenv(trim($key) . '=' . trim($value));
|
|
}
|
|
}
|
|
|
|
$NEXTCLOUD_URL = 'https://cloud.artetui.de';
|
|
$NEXTCLOUD_USER = getenv('NEXTCLOUD_USER') ?: 'lars.munkes';
|
|
$NEXTCLOUD_PASS = getenv('NEXTCLOUD_PASS');
|
|
|
|
// Prüfen ob Credentials konfiguriert sind
|
|
if (!$NEXTCLOUD_PASS) {
|
|
http_response_code(500);
|
|
echo json_encode(['error' => 'Nextcloud credentials not configured. Create spa-backup-api.env file.']);
|
|
exit;
|
|
}
|
|
|
|
// Request-Daten lesen
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|
|
|
if (!$input || !isset($input['app']) || !isset($input['data'])) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Missing app or data parameter']);
|
|
exit;
|
|
}
|
|
|
|
$app = $input['app'];
|
|
$backupData = $input['data'];
|
|
|
|
// Validierung: Nur erlaubte Apps
|
|
$allowedApps = ['schadenprofi', 'angebotsdatenbank', 'kostenschaetzung', 'zeitwert'];
|
|
if (!in_array($app, $allowedApps)) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Invalid app name']);
|
|
exit;
|
|
}
|
|
|
|
// Backup-Dateiname mit Timestamp
|
|
$timestamp = date('Y-m-d_H-i-s');
|
|
$filename = "{$app}-backup-{$timestamp}.json";
|
|
|
|
// Nextcloud WebDAV Upload
|
|
$webdavUrl = "{$NEXTCLOUD_URL}/remote.php/dav/files/{$NEXTCLOUD_USER}/Backups/{$app}/{$filename}";
|
|
|
|
// Verzeichnis erstellen falls nicht existiert
|
|
$dirUrl = "{$NEXTCLOUD_URL}/remote.php/dav/files/{$NEXTCLOUD_USER}/Backups/{$app}";
|
|
$ch = curl_init($dirUrl);
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'MKCOL');
|
|
curl_setopt($ch, CURLOPT_USERPWD, "{$NEXTCLOUD_USER}:{$NEXTCLOUD_PASS}");
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_exec($ch);
|
|
curl_close($ch);
|
|
|
|
// Backup hochladen
|
|
$ch = curl_init($webdavUrl);
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
|
|
curl_setopt($ch, CURLOPT_USERPWD, "{$NEXTCLOUD_USER}:{$NEXTCLOUD_PASS}");
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($backupData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
'Content-Type: application/json',
|
|
]);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_HEADER, true);
|
|
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
// Erfolg prüfen
|
|
if ($httpCode >= 200 && $httpCode < 300) {
|
|
echo json_encode([
|
|
'success' => true,
|
|
'message' => 'Backup erfolgreich gespeichert',
|
|
'filename' => $filename,
|
|
'path' => "/Backups/{$app}/{$filename}",
|
|
'timestamp' => $timestamp,
|
|
'url' => "{$NEXTCLOUD_URL}/f/" // Nextcloud sharing link base
|
|
]);
|
|
} else {
|
|
http_response_code(500);
|
|
echo json_encode([
|
|
'error' => 'Nextcloud upload failed',
|
|
'http_code' => $httpCode
|
|
]);
|
|
}
|
|
?>
|