feat(php): update live

backup
flop 3 weeks ago
parent 3e34bd8404
commit 7d7ebf88c6
  1. 105
      ts/live.php

@ -5,25 +5,23 @@ define('PASSWORD', 'cttue_avj2305_44');
define('FILES_DIR', __DIR__ . '/avj2305');
define('ACTIVE_FILE', __DIR__ . '/active.txt');
// -- helpers ------------------------------------------------------------------
// =============================================================================
// HELPERS
// =============================================================================
function is_authed(): bool {
return !empty($_SESSION['auth']);
function redirect(string $url): never {
header('Location: ' . $url);
exit;
}
function require_auth(): void {
if (!is_authed()) {
header('Location: ?login');
exit;
}
if (empty($_SESSION['auth'])) redirect('?login');
}
function get_active(): string {
if (file_exists(ACTIVE_FILE)) {
if (!file_exists(ACTIVE_FILE)) return '';
$v = trim(file_get_contents(ACTIVE_FILE));
if ($v !== '') return $v;
}
return '';
return $v !== '' ? $v : '';
}
function set_active(string $filename): void {
@ -32,45 +30,42 @@ function set_active(string $filename): void {
function get_bin_files(): array {
$files = glob(FILES_DIR . '/*.bin');
if (!$files) return [];
return array_map('basename', $files);
return $files ? array_map('basename', $files) : [];
}
function safe_filename(string $name): bool {
// basename only, no path traversal, must end in .bin
return $name === basename($name)
&& str_ends_with($name, '.bin')
&& !str_contains($name, "\0");
}
// -- routing ------------------------------------------------------------------
// =============================================================================
// ACTIONS (POST handlers - redirect, never render)
// =============================================================================
$q = array_key_first($_GET) ?? ''; // first query param key
// POST: login
if ($q === 'login' && $_SERVER['REQUEST_METHOD'] === 'POST') {
function action_login(): never {
if (hash_equals(PASSWORD, $_POST['password'] ?? '')) {
$_SESSION['auth'] = true;
header('Location: ?edit');
} else {
header('Location: ?login&err=1');
redirect('?edit');
}
exit;
redirect('?login&err=1');
}
// POST: set active file
if ($q === 'edit' && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['file'])) {
function action_set_file(): never {
require_auth();
$f = $_POST['file'];
$f = $_POST['file'] ?? '';
if (safe_filename($f) && file_exists(FILES_DIR . '/' . $f)) {
set_active($f);
}
header('Location: ?edit');
exit;
redirect('?edit');
}
// GET: login page
if ($q === 'login') { ?>
// =============================================================================
// RENDERERS (GET handlers - output HTML, never redirect)
// =============================================================================
function render_login(): never {
$err = !empty($_GET['err']); ?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Login</title>
@ -88,17 +83,15 @@ if ($q === 'login') { ?>
<label>Password</label>
<input type="password" name="password" autofocus>
<button type="submit">Login</button>
<?php if (!empty($_GET['err'])): ?><span class="err">Wrong password.</span><?php endif; ?>
<?php if ($err): ?><span class="err">Wrong password.</span><?php endif; ?>
</form>
</body></html>
<?php exit; }
// GET: edit page
if ($q === 'edit') {
function render_edit(): never {
require_auth();
$files = get_bin_files();
$active = get_active();
?>
$active = get_active(); ?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Select File</title>
@ -133,27 +126,53 @@ if ($q === 'edit') {
</body></html>
<?php exit; }
// DEFAULT: serve active .bin file
// =============================================================================
// FILE SERVER (default route)
// =============================================================================
function serve_active_file(): never {
$active = get_active();
if ($active === '') {
http_response_code(404);
exit('No active file set.');
http_response_code(404); exit('No active file set.');
}
if (!safe_filename($active)) {
http_response_code(500);
exit('Invalid filename.');
http_response_code(500); exit('Invalid filename.');
}
$path = FILES_DIR . '/' . $active;
if (!file_exists($path)) {
http_response_code(404);
exit('File not found.');
http_response_code(404); exit('File not found.');
}
header('Content-Type: application/octet-stream');
header('Content-Disposition: inline; filename="' . addslashes($active) . '"');
header('Content-Length: ' . filesize($path));
readfile($path);
exit;
}
// =============================================================================
// ROUTES
// =============================================================================
//
// GET /live.php -> serve active .bin file
// GET /live.php?login -> login page
// POST /live.php?login -> process login
// GET /live.php?edit -> file picker [auth required]
// POST /live.php?edit -> set active file [auth required]
//
// =============================================================================
$method = $_SERVER['REQUEST_METHOD'];
$route = array_key_first($_GET) ?? '';
match (true) {
$method === 'POST' && $route === 'login' => action_login(),
$method === 'POST' && $route === 'edit' => action_set_file(),
$method === 'GET' && $route === 'login' => render_login(),
$method === 'GET' && $route === 'edit' => render_edit(),
default => serve_active_file(),
};

Loading…
Cancel
Save