[orbis] Weekly backup 2026-07-07 — 318 files changed, 48597 insertions(+), 7 deletions(-)

This commit is contained in:
DO Server Backup
2026-07-07 15:58:55 +00:00
parent 5fda5a1536
commit fe18800d18
318 changed files with 48597 additions and 7 deletions
@@ -0,0 +1,62 @@
<?php
require_once __DIR__ . '/functions.php';
class AdminAuth {
private const MAX_ATTEMPTS = 5;
private const LOCKOUT_MINUTES = 15;
public static function attempt(string $password): bool {
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
if (self::isLockedOut($ip)) {
return false;
}
if (password_verify($password, ADMIN_PASSWORD_HASH)) {
db()->query("DELETE FROM login_attempts WHERE ip_address = :ip", ['ip' => $ip]);
$_SESSION['wt_admin'] = true;
session_regenerate_id(true);
return true;
}
self::recordFailure($ip);
return false;
}
public static function isLockedOut(string $ip): bool {
$row = db()->fetch("SELECT * FROM login_attempts WHERE ip_address = :ip", ['ip' => $ip]);
if (!$row || (int) $row['attempts'] < self::MAX_ATTEMPTS) {
return false;
}
$lockoutUntil = strtotime($row['last_attempt']) + self::LOCKOUT_MINUTES * 60;
return time() < $lockoutUntil;
}
private static function recordFailure(string $ip): void {
$row = db()->fetch("SELECT * FROM login_attempts WHERE ip_address = :ip", ['ip' => $ip]);
if ($row) {
$lockoutUntil = strtotime($row['last_attempt']) + self::LOCKOUT_MINUTES * 60;
// Reset the counter once the previous lockout window has fully expired.
$attempts = (time() < $lockoutUntil) ? (int) $row['attempts'] + 1 : 1;
db()->update('login_attempts', ['attempts' => $attempts, 'last_attempt' => date('Y-m-d H:i:s')], 'ip_address = :ip', ['ip' => $ip]);
} else {
db()->insert('login_attempts', ['ip_address' => $ip, 'attempts' => 1, 'last_attempt' => date('Y-m-d H:i:s')]);
}
}
public static function isLoggedIn(): bool {
return !empty($_SESSION['wt_admin']);
}
public static function require(): void {
if (!self::isLoggedIn()) {
header('Location: /admin/login.php');
exit;
}
}
public static function logout(): void {
unset($_SESSION['wt_admin']);
session_regenerate_id(true);
}
}