'Method not allowed']); exit; } // Read JSON body $raw = file_get_contents('php://input'); $data = json_decode($raw ?: '', true); $username = is_array($data) ? (string)($data['username'] ?? '') : ''; $password = is_array($data) ? (string)($data['password'] ?? '') : ''; if ($username === '' || $password === '') { http_response_code(400); echo json_encode(['error' => 'Missing username or password']); exit; } // === Simple credential check === // Recommended: set these via environment variables $expectedUser = getenv('MEDIA_USER') ?: 'admin'; // Store bcrypt hash in env: MEDIA_PASS_HASH="$2y$10$..." $expectedHash = getenv('MEDIA_PASS_HASH'); // If no hash provided, fall back to a plain password for quick LAN-only testing. // Strongly recommend switching to MEDIA_PASS_HASH once you verify flow works. $plainFallbackPass = getenv('MEDIA_PASS_PLAIN') ?: 'changeme'; $ok = false; if ($expectedHash) { $ok = hash_equals($expectedUser, $username) && password_verify($password, $expectedHash); } else { $ok = hash_equals($expectedUser, $username) && hash_equals($plainFallbackPass, $password); } if (!$ok) { // Slight delay makes brute forcing annoying usleep(250000); http_response_code(401); echo json_encode(['error' => 'Invalid credentials']); exit; } // Success: mark session authed, rotate session id session_regenerate_id(true); $_SESSION['authed'] = true; $_SESSION['user'] = $username; echo json_encode(['ok' => true, 'user' => $username]);