121 lines
4.1 KiB
PHP
121 lines
4.1 KiB
PHP
<?php
|
|
/**
|
|
* Gemeinsame Hilfsfunktionen: Einstellungen lesen, Besucher erkennen, Signaturen für Formularangaben.
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/** Standardwerte aller Einstellungen. */
|
|
function deskhub_tickets_defaults(): array
|
|
{
|
|
return [
|
|
'server_url' => '',
|
|
'api_key' => '',
|
|
'department_id' => 0,
|
|
'topic_id' => 0,
|
|
'priority_id' => 0,
|
|
'consent_text' => '',
|
|
'accent_color' => '',
|
|
'attachments' => 1,
|
|
'success_text' => '',
|
|
'status_page_url' => '',
|
|
'min_seconds' => 3,
|
|
'rate_limit_per_hour' => 5,
|
|
'turnstile_site' => '',
|
|
'turnstile_secret' => '',
|
|
];
|
|
}
|
|
|
|
/** Alle Einstellungen (mit Standardwerten). Server-Adresse und Schlüssel lassen sich zusätzlich in der wp-config.php festlegen. */
|
|
function deskhub_tickets_options(): array
|
|
{
|
|
$saved = get_option('deskhub_tickets_options', []);
|
|
$opts = array_merge(deskhub_tickets_defaults(), is_array($saved) ? $saved : []);
|
|
if (defined('DESKHUB_TICKETS_SERVER') && DESKHUB_TICKETS_SERVER !== '') {
|
|
$opts['server_url'] = (string) DESKHUB_TICKETS_SERVER;
|
|
}
|
|
if (defined('DESKHUB_TICKETS_API_KEY') && DESKHUB_TICKETS_API_KEY !== '') {
|
|
$opts['api_key'] = (string) DESKHUB_TICKETS_API_KEY;
|
|
}
|
|
return $opts;
|
|
}
|
|
|
|
function deskhub_tickets_option(string $key)
|
|
{
|
|
$opts = deskhub_tickets_options();
|
|
return $opts[$key] ?? null;
|
|
}
|
|
|
|
/** Wird der API-Schlüssel aus der wp-config.php genommen (dann ist das Feld in den Einstellungen gesperrt)? */
|
|
function deskhub_tickets_key_from_config(): bool
|
|
{
|
|
return defined('DESKHUB_TICKETS_API_KEY') && DESKHUB_TICKETS_API_KEY !== '';
|
|
}
|
|
|
|
/**
|
|
* Erkennt den Besucher für die Mengenbegrenzung. Es zählt nur REMOTE_ADDR: Header wie X-Forwarded-For kann jeder selbst setzen.
|
|
* Steht die Seite hinter einem Proxy, liefert der Filter "deskhub_tickets_client_ip" die richtige Adresse.
|
|
*/
|
|
function deskhub_tickets_client_ip(): string
|
|
{
|
|
$ip = isset($_SERVER['REMOTE_ADDR']) ? (string) $_SERVER['REMOTE_ADDR'] : '';
|
|
$ip = apply_filters('deskhub_tickets_client_ip', $ip);
|
|
return filter_var($ip, FILTER_VALIDATE_IP) ? (string) $ip : 'unknown';
|
|
}
|
|
|
|
/** Kurzer Schlüssel für einen Besucher (nicht umkehrbar, damit keine IP-Adressen in der Datenbank stehen). */
|
|
function deskhub_tickets_visitor_key(string $scope): string
|
|
{
|
|
return 'dht_' . substr(hash_hmac('sha256', $scope . '|' . deskhub_tickets_client_ip(), wp_salt('auth')), 0, 32);
|
|
}
|
|
|
|
/**
|
|
* Zählt einen Vorgang für den Besucher und sagt, ob er noch erlaubt ist.
|
|
* $max Vorgänge je $window Sekunden; false = Grenze erreicht (der Vorgang wird dann nicht mehr gezählt).
|
|
*/
|
|
function deskhub_tickets_rate_allow(string $scope, int $max, int $window): bool
|
|
{
|
|
if ($max <= 0) {
|
|
return true;
|
|
}
|
|
$key = deskhub_tickets_visitor_key($scope);
|
|
$count = (int) get_transient($key);
|
|
if ($count >= $max) {
|
|
return false;
|
|
}
|
|
set_transient($key, $count + 1, $window);
|
|
return true;
|
|
}
|
|
|
|
/** Unterschreibt Angaben, die durchs Formular laufen (Abteilung, Thema, Priorität), damit Besucher sie nicht ändern können. */
|
|
function deskhub_tickets_sign(string $payload): string
|
|
{
|
|
return hash_hmac('sha256', $payload, wp_salt('auth'));
|
|
}
|
|
|
|
function deskhub_tickets_verify_signature(string $payload, string $signature): bool
|
|
{
|
|
return $signature !== '' && hash_equals(deskhub_tickets_sign($payload), $signature);
|
|
}
|
|
|
|
/** Zeitstempel mit Unterschrift: beweist, wann das Formular angezeigt wurde (Schutz vor Robotern, die sofort absenden). */
|
|
function deskhub_tickets_timestamp_token(): string
|
|
{
|
|
$t = (string) time();
|
|
return $t . '.' . deskhub_tickets_sign('ts|' . $t);
|
|
}
|
|
|
|
/** Alter des Formulars in Sekunden; null, wenn der Wert fehlt oder gefälscht ist. */
|
|
function deskhub_tickets_timestamp_age(string $token): ?int
|
|
{
|
|
if (!preg_match('/^(\d{9,11})\.([a-f0-9]{64})$/', $token, $m)) {
|
|
return null;
|
|
}
|
|
if (!deskhub_tickets_verify_signature('ts|' . $m[1], $m[2])) {
|
|
return null;
|
|
}
|
|
return time() - (int) $m[1];
|
|
}
|