security: clean repository without media files and sensitive data

- Removed area/ directory with 816MB of media files
- Removed sensitive FTP credentials from Git history
- Implemented .env.upload system for secure deployments
- Added comprehensive .gitignore for future protection

This commit represents a clean slate with all sensitive data removed.
This commit is contained in:
Johannes
2025-09-07 11:05:29 +02:00
commit b4758b4f26
61 changed files with 23829 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
<?php
class AuthService {
private static function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
public static function verifyJWT($jwt) {
if (!$jwt) return null;
$parts = explode('.', $jwt);
if (count($parts) !== 3) return null;
list($header, $payload, $signature) = $parts;
$valid = self::base64url_encode(hash_hmac('sha256', "$header.$payload", self::$jwtSecret, true));
if (!hash_equals($valid, $signature)) return null;
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (!$data || ($data['exp'] ?? 0) < time()) return null;
// User-Infos je nach Rolle ergänzen
if ($data['role'] === 'admin') {
return [
'username' => $data['id'],
'role' => 'admin'
];
} elseif ($data['role'] === 'client') {
return [
'client' => $data['dir'],
'role' => 'client',
'dir' => $data['dir']
];
}
return null;
}
private static $adminFile = __DIR__ . '/../../storage/data/admins.json';
private static $clientFile = __DIR__ . '/../../storage/data/clients.json';
private static $jwtSecret = 'adspreview_secret_2025';
public static function authenticate($username, $password) {
if ($username) {
// Admin-Login
$admins = json_decode(file_get_contents(self::$adminFile), true);
foreach ($admins as $admin) {
if ($admin['username'] === $username && password_verify($password, $admin['password'])) {
$token = self::generateJWT($admin['username'], '', 'admin');
return ['success' => true, 'token' => $token, 'role' => 'admin'];
}
}
return ['success' => false, 'message' => 'Falscher Benutzername oder Passwort.'];
} else {
// Client-Login (nur Passwort)
$clients = json_decode(file_get_contents(self::$clientFile), true);
foreach ($clients as $key => $client) {
if ($client['pass'] === md5($password)) {
$token = self::generateJWT($key, $client['dir'], 'client');
return ['success' => true, 'token' => $token, 'role' => 'client'];
}
}
return ['success' => false, 'message' => 'Falsches Passwort.'];
}
}
private static function generateJWT($id, $dir, $role) {
$header = self::base64url_encode(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));
$payload = self::base64url_encode(json_encode([
'id' => $id,
'dir' => $dir,
'role' => $role,
'exp' => time() + 60 * 60 * 12 // 12 Stunden
]));
$signature = hash_hmac('sha256', "$header.$payload", self::$jwtSecret, true);
$signature = self::base64url_encode($signature);
return "$header.$payload.$signature";
}
}

View File

@@ -0,0 +1,23 @@
<?php
class JsonStorageService {
private static function getFilePath(string $type): string {
return __DIR__ . '/../../storage/data/' . $type . '.json';
}
public static function read(string $type): array {
$file = self::getFilePath($type);
if (!file_exists($file)) {
return [];
}
$json = file_get_contents($file);
$data = json_decode($json, true);
return is_array($data) ? $data : [];
}
public static function write(string $type, array $data): bool {
$file = self::getFilePath($type);
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
return file_put_contents($file, $json) !== false;
}
}