From 8a494d59a5769d9e27408c965aa2f04b5543256d Mon Sep 17 00:00:00 2001 From: andre Date: Wed, 23 Sep 2026 16:07:01 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20o=20login=20reporta=20falhas=20=C3=A0?= =?UTF-8?q?=20frota=20(activo=20no=20pr=C3=B3ximo=20refresh=20do=20platfor?= =?UTF-8?q?m-tools)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O login desta plataforma é próprio, por isso é daqui que o hub fica a saber dos logins falhados e dos bloqueios do throttle. A cópia vendorizada do platform-tools (ea3616a, ver VENDORED.md) ainda não traz functions_security_events.php, e até lá isto não faz nada. Co-Authored-By: Claude Opus 5.5 --- views/auth/login.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/views/auth/login.php b/views/auth/login.php index 3011c3a..a9685f3 100644 --- a/views/auth/login.php +++ b/views/auth/login.php @@ -19,6 +19,18 @@ if (!empty($_SESSION['user_id'])) { exit; } +// O login é deste site, não o partilhado, por isso é daqui que a frota fica a +// saber das falhas (platform-tools/functions_security_events.php). A cópia +// vendorizada ainda não traz esse ficheiro (ver VENDORED.md); até ao próximo +// refresh isto não faz nada. +$report_login = function (string $kind) use ($pdo): void { + $f = dirname(__DIR__, 2) . '/shared/platform-tools/functions_security_events.php'; + if (!is_file($f)) return; + require_once $f; + platform_security_event($pdo, $kind, hub_security_mask_identifier((string) ($_POST['email'] ?? ''))); + hub_security_maybe_sync($pdo); +}; + $error = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { csrf_check(); @@ -26,6 +38,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Counts successes too, so a guessed password can't be parlayed into // stuffing the rest of the user list from the same IP. if (!throttle_check($pdo, 'login')) { + $report_login('login_throttled'); throttle_block('login form'); } throttle_record($pdo, 'login'); @@ -36,6 +49,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { header('Location: ' . base_url($destination($user['role']))); exit; } + $report_login('login_failed'); // Deliberately vague — doesn't reveal whether the address exists. $error = 'Email ou palavra-passe incorretos.'; }