initial commit
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
ini_set('session.cookie_httponly', '1');
|
||||
ini_set('session.use_strict_mode', '1');
|
||||
|
||||
session_start();
|
||||
|
||||
$config = require '/var/www/TRAILER_TREKKER/private/config.php';
|
||||
|
||||
function json_response($data, int $code = 200): never {
|
||||
http_response_code($code);
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Cache-Control: no-store');
|
||||
echo json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
function require_login(): void {
|
||||
if (empty($_SESSION['tt_logged_in'])) {
|
||||
json_response(['ok' => false, 'error' => 'not_authenticated'], 401);
|
||||
}
|
||||
}
|
||||
|
||||
function read_json_file(string $path): array {
|
||||
if (!file_exists($path)) return [];
|
||||
$raw = file_get_contents($path);
|
||||
if ($raw === false || trim($raw) === '') return [];
|
||||
$data = json_decode($raw, true);
|
||||
return is_array($data) ? $data : [];
|
||||
}
|
||||
|
||||
function write_json_file_atomic(string $path, string $json): bool {
|
||||
// Ensure directory exists
|
||||
$dir = dirname($path);
|
||||
if (!is_dir($dir)) {
|
||||
if (!mkdir($dir, 0750, true)) return false;
|
||||
}
|
||||
|
||||
$fp = fopen($path, 'c+');
|
||||
if ($fp === false) return false;
|
||||
|
||||
$ok = false;
|
||||
if (flock($fp, LOCK_EX)) {
|
||||
ftruncate($fp, 0);
|
||||
rewind($fp);
|
||||
$bytes = fwrite($fp, $json);
|
||||
fflush($fp);
|
||||
flock($fp, LOCK_UN);
|
||||
$ok = ($bytes !== false);
|
||||
}
|
||||
fclose($fp);
|
||||
return $ok;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/_bootstrap.php';
|
||||
require_login();
|
||||
|
||||
$dataFile = $config['DATA_FILE'];
|
||||
|
||||
$data = read_json_file($dataFile);
|
||||
|
||||
// If file is empty/uninitialized, return defaults
|
||||
if (empty($data)) {
|
||||
$data = [
|
||||
'meta' => ['schema' => 1, 'updatedAt' => gmdate('c')],
|
||||
'trips' => [],
|
||||
'shopping' => [],
|
||||
'preTripTodos' => [],
|
||||
'preTripChecklist' => [],
|
||||
'upgrades' => [],
|
||||
'fixes' => [],
|
||||
];
|
||||
}
|
||||
|
||||
json_response(['ok' => true, 'data' => $data]);
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/_bootstrap.php';
|
||||
require_login();
|
||||
|
||||
$max = (int)$config['MAX_JSON_BYTES'];
|
||||
$raw = file_get_contents('php://input');
|
||||
|
||||
if ($raw === false) {
|
||||
json_response(['ok' => false, 'error' => 'no_body'], 400);
|
||||
}
|
||||
|
||||
if (strlen($raw) > $max) {
|
||||
json_response(['ok' => false, 'error' => 'payload_too_large'], 413);
|
||||
}
|
||||
|
||||
$data = json_decode($raw, true);
|
||||
if (!is_array($data)) {
|
||||
json_response(['ok' => false, 'error' => 'invalid_json'], 400);
|
||||
}
|
||||
|
||||
// Minimal sanity enforcement
|
||||
$data['meta'] = $data['meta'] ?? [];
|
||||
$data['meta']['schema'] = 1;
|
||||
$data['meta']['updatedAt'] = gmdate('c');
|
||||
|
||||
// Only allow the keys we expect (keeps junk out)
|
||||
$allowed = ['meta','trips','shopping','preTripTodos','preTripChecklist','upgrades','fixes'];
|
||||
$clean = [];
|
||||
foreach ($allowed as $k) {
|
||||
$clean[$k] = $data[$k] ?? ($k === 'meta' ? $data['meta'] : []);
|
||||
}
|
||||
|
||||
$json = json_encode($clean, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
if ($json === false) {
|
||||
json_response(['ok' => false, 'error' => 'encode_failed'], 500);
|
||||
}
|
||||
|
||||
$ok = write_json_file_atomic($config['DATA_FILE'], $json . "\n");
|
||||
if (!$ok) {
|
||||
json_response(['ok' => false, 'error' => 'write_failed'], 500);
|
||||
}
|
||||
|
||||
json_response(['ok' => true]);
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/_bootstrap.php';
|
||||
|
||||
$username = $_POST['username'] ?? '';
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
$expectedUser = $config['USERNAME'];
|
||||
$expectedHash = $config['PASSWORD_HASH'];
|
||||
|
||||
if ($username === $expectedUser && password_verify($password, $expectedHash)) {
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['tt_logged_in'] = true;
|
||||
header('Location: /');
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Location: /?err=1');
|
||||
exit;
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/_bootstrap.php';
|
||||
|
||||
$_SESSION = [];
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params["path"], $params["domain"],
|
||||
(bool)$params["secure"], (bool)$params["httponly"]
|
||||
);
|
||||
}
|
||||
session_destroy();
|
||||
|
||||
header('Location: /');
|
||||
exit;
|
||||
Reference in New Issue
Block a user