Added template layer below the master template in preparation for other things.

This commit is contained in:
flash 2025-01-30 12:07:59 +00:00
parent 720d36dd23
commit a09bdb5fc3
5 changed files with 62 additions and 44 deletions

View file

@ -4,9 +4,13 @@ namespace Misuzu;
use Index\CsrfToken;
final class CSRF {
private static CsrfToken $instance;
private static ?CsrfToken $instance = null;
private static string $secretKey = '';
public static function available(): bool {
return self::$instance !== null;
}
public static function create(string $identity, ?string $secretKey = null): CsrfToken {
if($secretKey === null)
$secretKey = self::$secretKey;
@ -21,14 +25,17 @@ final class CSRF {
}
public static function validate(string $token, int $tolerance = -1): bool {
return self::$instance->verifyToken($token, $tolerance);
return self::$instance?->verifyToken($token, $tolerance) ?? false;
}
public static function token(): string {
return self::$instance->createToken();
return self::$instance?->createToken() ?? '';
}
public static function validateRequest(int $tolerance = -1): bool {
if(self::$instance === null)
return false;
$token = (string)filter_input(INPUT_POST, '_csrf');
if(empty($token))
$token = (string)filter_input(INPUT_GET, 'csrf');

View file

@ -31,6 +31,7 @@ final class TemplatingExtension extends AbstractExtension {
return [
new TwigFunction('asset', $this->getAssetPath(...)),
new TwigFunction('url', $this->ctx->urls->format(...)),
new TwigFunction('csrf_available', CSRF::available(...)),
new TwigFunction('csrf_token', CSRF::token(...)),
new TwigFunction('git_commit_hash', GitInfo::hash(...)),
new TwigFunction('git_tag', GitInfo::tag(...)),

13
templates/html.twig Normal file
View file

@ -0,0 +1,13 @@
<!doctype html>
<html>
<head>
<meta charset="{{ html_charset|default('utf-8') }}">
{% if html_title is defined and html_title is not empty %}<title>{{ html_title }}</title>{% endif %}
{% if html_viewport is not defined or html_viewport is not empty %}<meta name="viewport" content="{{ html_viewport|default('width=device-width, initial-scale=1') }}">{% endif %}
{% block html_head %}{% endblock %}
{% if csrf_available() %}<meta name="csrf-token" content="{{ csrf_token() }}">{% endif %}
</head>
<body{% if html_body_attrs is defined and html_body_attrs is iterable %}{% for name, value in html_body_attrs %}{% if value is not empty %} {{ name }}="{{ value }}"{% endif %}{% endfor %}{% endif %}>
{% block html_body %}{% endblock %}
</body>
</html>

View file

@ -1,13 +1,10 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% include '_layout/meta.twig' %}
<meta name="csrf-token" content="{{ csrf_token() }}">
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet">
<link href="{{ asset('misuzu.css') }}" type="text/css" rel="stylesheet">
{% if site_background is defined %}
{% extends 'html.twig' %}
{% block html_head %}
{% include '_layout/meta.twig' %}
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet">
<link href="{{ asset('misuzu.css') }}" type="text/css" rel="stylesheet">
{% if site_background is defined %}
<style>
:root {
--background-width: {{ site_background.width }}px;
@ -15,30 +12,34 @@
--background-image: url('{{ site_background_url|raw }}');
}
</style>
{% endif %}
{% if site_logo is defined %}
{% endif %}
{% if site_logo is defined %}
<style>
:root {
--site-logo: url('{{ site_logo }}');
}
</style>
{% endif %}
</head>
<body class="main{% if site_background is defined %} {{ site_background.classNames('main--bg-%s')|join(' ') }}{% endif %}"
style="{% if global_accent_colour is defined %}--accent-colour: {{ global_accent_colour }}{% endif %}" id="container">
{% block main_header %}
{% include '_layout/header.twig' %}
{% endif %}
{% endblock %}
<div class="main__wrapper">
<noscript>
<div class="warning">
<div class="warning__content"><strong>Significant parts of the site require JavaScript.</strong> If you have it turned off and something doesn't work, that's probably why!</div>
</div>
</noscript>
{% set html_body_attrs = {
'class': 'main' ~ (site_background is defined ? (' ' ~ site_background.classNames('main--bg-%s')|join(' ')) : ''),
'style': global_accent_colour is defined ? ('--accent-colour: ' ~ global_accent_colour) : '',
} %}
{% if globals.active_ban_info is not null %}
{% block html_body %}
{% block main_header %}
{% include '_layout/header.twig' %}
{% endblock %}
<div class="main__wrapper">
<noscript>
<div class="warning">
<div class="warning__content"><strong>Significant parts of the site require JavaScript.</strong> If you have it turned off and something doesn't work, that's probably why!</div>
</div>
</noscript>
{% if globals.active_ban_info is not null %}
<div class="warning warning--red">
<div class="warning__content">
<p>You have been banned {% if globals.active_ban_info.permanent %}<strong>permanently</strong>{% else %}for <strong title="{{ globals.active_ban_info.expiresTime|date('r') }}">{{ globals.active_ban_info.remainingString }}</strong>{% endif %} since <strong><time datetime="{{ globals.active_ban_info.createdTime|date('c') }}" title="{{ globals.active_ban_info.createdTime|date('r') }}">{{ globals.active_ban_info.createdTime|time_format }}</time></strong>.</p>
@ -47,20 +48,19 @@
{% endif %}
</div>
</div>
{% endif %}
{% endif %}
{% block content %}
{% block content %}
<div class="container">
This page is empty, populate it.
</div>
{% endblock %}
</div>
{% endblock %}
</div>
{% block main_footer %}
{% include '_layout/footer.twig' %}
{% endblock %}
{% block main_footer %}
{% include '_layout/footer.twig' %}
{% endblock %}
<script src="/vendor/highlightjs/highlight.min.js" type="text/javascript"></script>
<script src="{{ asset('misuzu.js') }}" type="text/javascript"></script>
</body>
</html>
<script src="/vendor/highlightjs/highlight.min.js" type="text/javascript"></script>
<script src="{{ asset('misuzu.js') }}" type="text/javascript"></script>
{% endblock %}

View file

@ -75,10 +75,7 @@ handleValue:
$hostName ??= 'localhost';
// this should really not be necessary
CSRF::init($msz->config->getString('csrf.secret', 'soup'), '::1');
// neither should this i think, mostly done to make sure the url handler thing is available
// this should really not be necessary, mostly done to make sure the url registry is available
$msz->createRouting(new HttpRequest('::1', true, 'XX', '1.1', 'GET', '/', [], [], new HttpHeaders([
new HttpHeader('Host', $hostName),
]), null));