Release v1.5.1

This commit is contained in:
AudioCore Bot
2026-04-01 14:12:17 +00:00
parent dc53051358
commit 9deabe1ec9
50 changed files with 10775 additions and 5637 deletions

View File

@@ -7,6 +7,7 @@ use Core\Http\Response;
use Core\Services\Auth;
use Core\Services\Database;
use Core\Services\Mailer;
use Core\Services\RateLimiter;
use Core\Services\Settings;
use Core\Views\View;
use PDO;
@@ -28,6 +29,13 @@ class NewsletterController
if ($email === '') {
return new Response('Missing email', 400);
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return new Response('Invalid email', 400);
}
$limitKey = sha1(strtolower($email) . '|' . $this->clientIp());
if (RateLimiter::tooMany('newsletter_subscribe', $limitKey, 8, 600)) {
return new Response('Too many requests. Please wait 10 minutes and try again.', 429);
}
$db = Database::get();
if ($db instanceof PDO) {
@@ -61,6 +69,16 @@ class NewsletterController
{
$email = trim((string)($_POST['email'] ?? ''));
$status = 'Email is required.';
if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$limitKey = sha1(strtolower($email) . '|' . $this->clientIp());
if (RateLimiter::tooMany('newsletter_unsubscribe', $limitKey, 8, 600)) {
return new Response($this->view->render('site/unsubscribe.php', [
'title' => 'Unsubscribe',
'email' => $email,
'status' => 'Too many unsubscribe attempts. Please wait 10 minutes.',
]), 429);
}
}
$db = Database::get();
if ($db instanceof PDO && $email !== '') {
@@ -76,6 +94,24 @@ class NewsletterController
]));
}
private function clientIp(): string
{
foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'] as $key) {
$value = trim((string)($_SERVER[$key] ?? ''));
if ($value === '') {
continue;
}
if ($key === 'HTTP_X_FORWARDED_FOR') {
$parts = array_map('trim', explode(',', $value));
$value = (string)($parts[0] ?? '');
}
if ($value !== '') {
return substr($value, 0, 64);
}
}
return '0.0.0.0';
}
public function adminIndex(): Response
{
if ($guard = $this->guard(['admin', 'manager'])) {