init
This commit is contained in:
55
auth/rate_limit.php
Normal file
55
auth/rate_limit.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
function auth_check_rate_limit(string $key): array
|
||||
{
|
||||
$config = require __DIR__ . "/config.php";
|
||||
$window = (int) $config["rate_limit"]["window_seconds"];
|
||||
$max = (int) $config["rate_limit"]["max_attempts"];
|
||||
$dir = __DIR__ . "/ratelimit";
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
@mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
$safeKey = hash("sha256", $key);
|
||||
$file = $dir . "/" . $safeKey . ".json";
|
||||
$now = time();
|
||||
|
||||
$data = [
|
||||
"count" => 1,
|
||||
"reset_at" => $now + $window,
|
||||
];
|
||||
|
||||
if (is_file($file)) {
|
||||
$raw = @file_get_contents($file);
|
||||
$decoded = $raw ? json_decode($raw, true) : null;
|
||||
if (is_array($decoded) && isset($decoded["count"], $decoded["reset_at"])) {
|
||||
if ($now <= (int) $decoded["reset_at"]) {
|
||||
$decoded["count"] = (int) $decoded["count"] + 1;
|
||||
$data = $decoded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$limited = $data["count"] > $max;
|
||||
$retryAfter = max(0, $data["reset_at"] - $now);
|
||||
|
||||
$payload = json_encode($data);
|
||||
if ($payload !== false) {
|
||||
$fh = @fopen($file, "cb+");
|
||||
if ($fh !== false) {
|
||||
if (flock($fh, LOCK_EX)) {
|
||||
ftruncate($fh, 0);
|
||||
fwrite($fh, $payload);
|
||||
fflush($fh);
|
||||
flock($fh, LOCK_UN);
|
||||
}
|
||||
fclose($fh);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
"limited" => $limited,
|
||||
"retry_after" => $retryAfter,
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user