diff --git a/api/.env b/api/.env
index 9e7c528..4a7e56e 100644
--- a/api/.env
+++ b/api/.env
@@ -6,4 +6,4 @@ LXD_CLIENT_CERT=/etc/ssl/lxdapp/client.crt
LXD_CLIENT_KEY=/etc/ssl/lxdapp/client.key
LXD_IMAGE_FINGERPRINT=2edfd84b1396
AUTH_KEY=R9kX2HFA7ZjLdVYm8TsQWpCeNuB1v0GrS6MI4axf
-
+STATEDIR=/var/www/html/lxd-app/api/public/last-access-logs
\ No newline at end of file
diff --git a/api/public/index.php b/api/public/index.php
index 9fef4d0..9a1ee57 100644
--- a/api/public/index.php
+++ b/api/public/index.php
@@ -14,6 +14,7 @@ use App\Controllers\HandoffController;
use App\Services\LxdService;
use Zounar\PHPProxy\Proxy;
use App\Utils\LogWriterHelper;
+use App\Utils\ContainerHelper;
require __DIR__ . '/../vendor/autoload.php';
diff --git a/api/src/Controllers/HandoffController.php b/api/src/Controllers/HandoffController.php
index 744f69a..e45b8e3 100644
--- a/api/src/Controllers/HandoffController.php
+++ b/api/src/Controllers/HandoffController.php
@@ -5,6 +5,7 @@ namespace App\Controllers;
use App\Services\LxdService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
+use App\Utils\ContainerHelper;
class HandoffController
{
@@ -13,9 +14,9 @@ class HandoffController
// if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
$q = $req->getQueryParams();
- $name = (string)($q['name'] ?? '');
+ $name = ContainerHelper::getName($req);
$id = (string)($q['handoff'] ?? '');
- $path = (string)($q['path'] ?? '/login');
+ $path = (string)($q['path'] ?? '/');
if (!$name || !$id) {
return $this->html($res, 400, '
Bad request
');
diff --git a/api/src/Controllers/LoginController.php b/api/src/Controllers/LoginController.php
index 075b82c..49406ac 100644
--- a/api/src/Controllers/LoginController.php
+++ b/api/src/Controllers/LoginController.php
@@ -7,6 +7,7 @@ use App\Services\LxdService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use App\Utils\LogWriterHelper;
+use App\Utils\ContainerHelper;
class LoginController
{
@@ -16,12 +17,7 @@ class LoginController
public function index(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
try {
- $origin = $request->getHeaderLine('Origin');
- $domain = !empty($origin) ? parse_url($origin, PHP_URL_HOST) : $request->getHeaderLine('Host');
-
- $configPath = __DIR__ . '/../../config.json';
- $config = file_exists($configPath) ? json_decode(file_get_contents($configPath), true) : [];
- $name = $config[$domain] ?? null;
+ $name = ContainerHelper::getName($request);
$params = (array)$request->getParsedBody();
@@ -42,10 +38,8 @@ class LoginController
if ($status !== 'Running') {
$lxd->startContainer($name);
}
-
- // Log path only (avoid leaking query in logs)
- $uri = $request->getUri();
- LogWriterHelper::write($name, $uri->getPath());
+
+ LogWriterHelper::write($name);
// ---- NEW: create one-time handoff and store creds server-side ----
$handoffId = bin2hex(random_bytes(16));
@@ -56,12 +50,11 @@ class LoginController
];
// sanitize the container path (not a full URL!)
- $path = $this->sanitizeRedirectPath($params['redirect'] ?? '/login');
+ // $path = $this->sanitizeRedirectPath($params['redirect'] ?? '/login');
// Client goes to waiting page; when ready it will be sent to the bridge
- $redirect = '/waiting?name=' . rawurlencode($name)
- . '&handoff=' . rawurlencode($handoffId)
- . '&path=' . rawurlencode($path);
+ $redirect = '/waiting?handoff=' . rawurlencode($handoffId);
+ //. '&path=' . rawurlencode($path);
return $this->json($response, [
'status' => 'success',
@@ -78,8 +71,7 @@ class LoginController
public function status(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
- $queryParams = $request->getQueryParams();
- $name = $queryParams['name'] ?? '';
+ $name = ContainerHelper::getName($request);
if (empty($name)) {
return $this->json($response, [
@@ -115,6 +107,7 @@ class LoginController
return $this->json($response, [
'status' => 'ready',
'ip' => $ip,
+ 'name' => $name,
'message' => 'Container is ready',
]);
}
@@ -167,4 +160,5 @@ class LoginController
return in_array($path, $allow, true) ? $path : '/login';
}
}
+
\ No newline at end of file
diff --git a/api/src/Scripts/auto-stop-containers.php b/api/src/Scripts/auto-stop-containers.php
index 6294602..5d3d893 100755
--- a/api/src/Scripts/auto-stop-containers.php
+++ b/api/src/Scripts/auto-stop-containers.php
@@ -8,7 +8,7 @@ use App\Services\LxdService;
$lxdService = new LxdService();
// Define the directory containing access logs
-$logDir = realpath(__DIR__ . '/../../public/last-access-logs'); // Adjust if you're in /app/src/Cron or similar
+$logDir = $_ENV['STATEDIR'] ?? "/var/www/html/lxd-app/api/public/last-access-logs";
// Define the idle threshold in minutes
$thresholdMinutes = 30;
@@ -18,23 +18,15 @@ foreach (glob($logDir . '/*.txt') as $filePath) {
// Extract the container name from the file name
$containerName = basename($filePath, '.txt');
- // Get the last line from the log file
- $lastLine = getLastLine($filePath);
- if (!$lastLine) {
- echo "No access logs found for $containerName.\n";
+ // Get the last modified time of the file
+ $lastModified = filemtime($filePath);
+ if (!$lastModified) {
+ echo "Failed to get modification time for $containerName.\n";
continue;
}
- // Parse the timestamp from the last log entry
- $parts = explode(' : ', $lastLine);
- if (!isset($parts[0])) continue;
-
- $lastAccess = DateTime::createFromFormat('Y-m-d H:i:s', trim($parts[0]));
- if (!$lastAccess) continue;
-
- // Calculate the idle time in seconds
- $now = new DateTime();
- $interval = $now->getTimestamp() - $lastAccess->getTimestamp();
+ $now = time();
+ $interval = $now - $lastModified;
// Check if the container has been idle for longer than the threshold
if ($interval > $thresholdMinutes * 60) {
@@ -49,20 +41,7 @@ foreach (glob($logDir . '/*.txt') as $filePath) {
echo "Container $containerName does not exist.\n";
}
} catch (Throwable $e) {
- // Handle any errors that occur while stopping the container
echo "Error stopping $containerName: " . $e->getMessage() . "\n";
}
}
}
-
-/**
- * Get the last non-empty line from a file.
- *
- * @param string $filePath Path to the file.
- * @return string|null The last line, or null if the file is empty.
- */
-function getLastLine(string $filePath): ?string
-{
- $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
- return $lines ? end($lines) : null;
-}
diff --git a/api/src/Utils/ContainerHelper.php b/api/src/Utils/ContainerHelper.php
new file mode 100644
index 0000000..ceca7ed
--- /dev/null
+++ b/api/src/Utils/ContainerHelper.php
@@ -0,0 +1,33 @@
+getHeaderLine('Origin');
+ $domain = !empty($origin) ? parse_url($origin, PHP_URL_HOST) : $request->getHeaderLine('Host');
+
+ // Load config.json once
+ $config = self::getConfig();
+ return $config[$domain] ?? null;
+ }
+
+ protected static function getConfig(): array
+ {
+ static $config = null;
+
+ if ($config !== null) {
+ return $config;
+ }
+
+ $configPath = __DIR__ . '/../../config.json';
+
+ return file_exists($configPath) ? json_decode(file_get_contents($configPath), true) : [];
+ }
+}
diff --git a/api/src/Utils/LogWriterHelper.php b/api/src/Utils/LogWriterHelper.php
index 74d461f..4c897ff 100644
--- a/api/src/Utils/LogWriterHelper.php
+++ b/api/src/Utils/LogWriterHelper.php
@@ -3,19 +3,7 @@
namespace App\Utils;
class LogWriterHelper {
- public static function write(string $name, string $uri): void {
- // Dynamically resolve the log directory relative to the current file
- $logDir = realpath(__DIR__ . '/../../public/last-access-logs');
-
- // If the resolved path doesn't exist (e.g., public dir was missing), create it
- if (!$logDir) {
- $logDir = __DIR__ . '/../../public/last-access-logs';
- if (!file_exists($logDir)) {
- mkdir($logDir, 0777, true);
- }
- }
-
- $logLine = date("Y-m-d H:i:s") . " : " . $uri . "\n";
- file_put_contents($logDir . '/' . $name . '.txt', $logLine, FILE_APPEND);
+ public static function write(string $name): void {
+ touch($_ENV['STATEDIR']."/".$name);
}
}
\ No newline at end of file
diff --git a/index.php b/index.php
index 47733c3..15fed4c 100644
--- a/index.php
+++ b/index.php
@@ -27,7 +27,7 @@ $container = $config[$host] ?? null;
$lxd = new LxdService();
// === Helper URLs ===
-$redirectBase = parseUrl("$host/app?auth=ok&redirect=" . urlencode(getFullUrl()));
+$redirectBase = parseUrl("$host/app");
$waitingPage = parseUrl("$host/app/waiting?name=$container&redirect=" . urlencode(getFullUrl()));
// === If container is missing or invalid ===
if (!$container || !$lxd->containerExists($container)) {
@@ -71,7 +71,8 @@ function proxy(string $name, string $targetUrl): void {
$_SERVER['HTTP_PROXY_TARGET_URL'] = $targetUrl;
$responseCode = Proxy::run();
- writeLog($name, $targetUrl);
+ touch($_ENV['STATEDIR']."/".$name);
+
}
function getFullUrl(): string {