2b9a673912
PHP registration page for AzerothCore with SRP6 salt/verifier generation, Cloudflare Turnstile + honeypot + rate limiting anti-spam, and a WoW-themed landing page with client setup instructions.
88 lines
2.4 KiB
PHP
88 lines
2.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
function client_ip(): string
|
|
{
|
|
// Uprav podle své infrastruktury: pokud web běží za reverzní proxy
|
|
// (nginx proxy_pass, Cloudflare, ...), musíš X-Forwarded-For nastavit
|
|
// a validovat důvěryhodně na úrovni proxy, jinak si ji klient může
|
|
// vymyslet sám. Bez proxy je REMOTE_ADDR spolehlivý zdroj.
|
|
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
|
|
return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : '0.0.0.0';
|
|
}
|
|
|
|
function csrf_token(): string
|
|
{
|
|
if (empty($_SESSION['csrf_token'])) {
|
|
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
|
}
|
|
return $_SESSION['csrf_token'];
|
|
}
|
|
|
|
function csrf_verify(?string $token): bool
|
|
{
|
|
return is_string($token)
|
|
&& !empty($_SESSION['csrf_token'])
|
|
&& hash_equals($_SESSION['csrf_token'], $token);
|
|
}
|
|
|
|
/**
|
|
* Honeypot: skryté pole, které lidský uživatel nikdy nevyplní, ale
|
|
* jednoduší boti ano.
|
|
*/
|
|
function honeypot_triggered(): bool
|
|
{
|
|
return !empty($_POST['website']);
|
|
}
|
|
|
|
/**
|
|
* @return string[] seznam chyb (prázdné pole = validní)
|
|
*/
|
|
function validate_username(string $username, array $rules): array
|
|
{
|
|
$errors = [];
|
|
$len = mb_strlen($username);
|
|
|
|
if ($len < $rules['username_min'] || $len > $rules['username_max']) {
|
|
$errors[] = sprintf(
|
|
'Uživatelské jméno musí mít %d až %d znaků.',
|
|
$rules['username_min'],
|
|
$rules['username_max']
|
|
);
|
|
}
|
|
|
|
if (!preg_match('/^[A-Za-z0-9]+$/', $username)) {
|
|
$errors[] = 'Uživatelské jméno smí obsahovat pouze písmena A-Z a číslice (bez diakritiky a speciálních znaků).';
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
function validate_password(string $password, array $rules): array
|
|
{
|
|
$errors = [];
|
|
$len = strlen($password);
|
|
|
|
if ($len < $rules['password_min'] || $len > $rules['password_max']) {
|
|
$errors[] = sprintf(
|
|
'Heslo musí mít %d až %d znaků.',
|
|
$rules['password_min'],
|
|
$rules['password_max']
|
|
);
|
|
}
|
|
|
|
if (!preg_match('/^[\x21-\x7E]+$/', $password)) {
|
|
$errors[] = 'Heslo smí obsahovat pouze běžné znaky ASCII (bez mezer a diakritiky) — herní klient WoW jiné znaky nepodporuje.';
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
|
|
function validate_email(string $email): array
|
|
{
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
return ['Zadej platnou e-mailovou adresu.'];
|
|
}
|
|
return [];
|
|
}
|