From b422b6ded608807c7d3bb8b965b3797ca513610b Mon Sep 17 00:00:00 2001 From: winter Sparkles Date: Sat, 8 Aug 2026 23:01:51 +0100 Subject: implement a large chunk of the auth system itself :D --- webroot/index.php | 63 ++++++++++++++++++++++++ webroot/static/style.css | 122 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 webroot/index.php create mode 100644 webroot/static/style.css (limited to 'webroot') diff --git a/webroot/index.php b/webroot/index.php new file mode 100644 index 0000000..729cdf2 --- /dev/null +++ b/webroot/index.php @@ -0,0 +1,63 @@ +Server misconfiguration! couldn't figure out the request path

"; + exit; +} + +$path = explode('?', $path, 2)[0]; + +$config = parse_ini_file(__DIR__ . '/../config.ini', true, INI_SCANNER_TYPED); + +require_once __DIR__ . '/../localisation.php'; + +Psso\XMLResponse::addStylesheet('../templates/index.xsl'); +Psso\XMLResponse::addPreamble(function ($doc) use ($config) { + $doc->addAttribute('site-name', $config['site']['name']); + $doc->addAttribute('source', $config['site']['source-location']); +}); + +$router = new Psso\Router('../routes', $config); + +$router->registerStatusHandler(404, function ($path) { + $resp = new Psso\XMLResponse; + $resp->doc->addAttribute('title', 'Not found'); + $resp->doc->addChild( + 'error', + "The requested page ($path) does not exist." + ); + $resp->send(); +}); + +$router->registerStatusHandler(405, function ($path) { + $method = $_SERVER['REQUEST_METHOD']; + $resp = new Psso\XMLResponse; + $resp->doc->addAttribute('title', 'Wrong method'); + $resp->doc->addChild( + 'error', + "Your request method ($method) is not valid for this path." + ); + $resp->send(); +}); + +$router->setExceptionHandler(function (Throwable $e) { + $resp = new Psso\XMLResponse; + $resp->doc->addAttribute('title', 'Uncaught exception'); + $resp->doc->addChild( + 'error', + $e::class . ': ' . $e->getMessage() + ); + $resp->send(); + error_log($e); +}); + +$router->dispatch($path); diff --git a/webroot/static/style.css b/webroot/static/style.css new file mode 100644 index 0000000..b12e886 --- /dev/null +++ b/webroot/static/style.css @@ -0,0 +1,122 @@ +:root { + font-family: sans-serif; + color-scheme: light dark; + + /* theme colours */ + --primary: #055; + --secondary: #dee; + --negative: #a01; + --background: #eff; + --foreground: #022; + --behind: #dee; + --header-bg: var(--primary); + + @media (prefers-color-scheme: dark) { + --primary: #8cc; + --secondary: #122; + --negative: #e78; + --background: #233; + --foreground: #eff; + --behind: #011; + --header-bg: var(--secondary); + } + + /* dimensions */ + --page-width: 800px; + --is-wide: 1; + @media (width < 800px) { + --is-wide: 0; + } +} + +body { + margin: 0; + padding: 0; + + background-color: var(--behind); +} + +header { + background: linear-gradient( + to bottom, + color-mix(in oklab, var(--header-bg), var(--behind)), + var(--header-bg) + ); + color: contrast-color(var(--header-bg)); + + padding: 1em; + max-width: var(--page-width); + margin: calc(var(--is-wide) * 1em) auto; + height: 100px; + display: flex; + align-items: end; + + site-name { + font-weight: bold; + font-size: xx-large; + } +} + +footer { + font-size: small; + text-align: center; + margin: 1lh; + color: color-mix(in oklab, var(--foreground), var(--behind)); + + a { + color: inherit; + text-decoration-style: dotted; + } +} + +main { + padding: 1em; + max-width: var(--page-width); + margin: auto; + background-color: var(--background); + color: var(--foreground); +} + +error-message { + background-color: var(--negative); + color: contrast-color(var(--negative)); + margin: 1em 0; + padding: 1em; + border-radius: 4px; + display: flex; + flex-direction: column; + gap: 0.5lh; + width: max-content; + max-width: 100%; + box-sizing: border-box; + + box-label { + font-weight: bold; + } +} + +.challenge-message { + border: 1px solid var(--negative); + padding: 1em; + width: max-content; + max-width: 100%; + box-sizing: border-box; +} + +form { + display: grid; + grid-template-columns: max-content max-content; + gap: 1em; + background-color: var(--behind); + margin: 1em 0; + padding: 1em; + width: max-content; + max-width: 100%; + box-sizing: border-box; + + button { + grid-column: 1 / 3; + width: max-content; + justify-self: center; + } +} -- cgit v1.3