feat: implement global autoresponder plugin

This commit is contained in:
Marek Miklewicz
2026-06-02 19:19:00 +02:00
commit 6f989af278
62 changed files with 2018 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
final class CsrfGuard
{
public function __construct(private string $secret, private string $username, private string $sessionId)
{
$this->sessionId = $this->sessionId !== '' ? $this->sessionId : 'no_session';
}
/**
* @return array{ts:int,sid:string,token:string}
*/
public function issue(string $intent): array
{
$ts = time();
return ['ts' => $ts, 'sid' => $this->sessionId, 'token' => $this->buildToken($intent, $ts, $this->sessionId)];
}
public function validate(string $intent, string $timestamp, string $token, int $ttl = 3600, string $sessionHint = ''): bool
{
if (!preg_match('/^[0-9]{1,20}$/', $timestamp)) {
return false;
}
$ts = (int)$timestamp;
$now = time();
if ($ts <= 0 || $ts > $now + 30 || $now - $ts > $ttl) {
return false;
}
$sids = array_values(array_unique(array_filter([$sessionHint, $this->sessionId, 'no_session'], static fn ($v): bool => $v !== '')));
foreach ($sids as $sid) {
if (hash_equals($this->buildToken($intent, $ts, $sid), trim($token))) {
return true;
}
}
return false;
}
private function buildToken(string $intent, int $timestamp, string $sid): string
{
return hash_hmac('sha256', implode('|', [$this->username, $sid, $intent, (string)$timestamp]), $this->secret);
}
}