feat(audit): platform-tools atualizado (12f26fd) e registo de auditoria ligado

- shared/platform-tools: ea3616a → 12f26fd (27 commits). Traz o módulo de
  audit (f761d99, o pin da frota), «manter sessão iniciada», o registo de
  segurança da frota (o gancho que o login já tinha passa a funcionar) e a
  correção do IP do cliente encontrada nesta auditoria (último X-Forwarded-For
  / X-Real-IP), promovida ao partilhado. client_ip() da app delega nele.
- config/functions_audit.php: audit() sobre platform_audit(); tabela
  audit_log criada no primeiro uso, segredos ocultados, nunca parte a ação.
- Registado: login, falha de login, bloqueio por excesso de tentativas,
  logout, pedidos de recuperação, mudança/definição de palavra-passe,
  registo e criação de utilizadores, convites, perfil (antes/depois), todas
  as definições (db_update_setting, com valor anterior), cada passo da
  lixeira (apagar, restaurar, eliminar de vez) e ações nas mensagens.
- Sistema → Auditoria (views/sysadmin/audit.php), só sysadmin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
andreandClaude Opus 5.5 committed 2026-09-25 07:28:13 +01:00
1 parent 5e300fc341
commit 0e8b53f620
65 files changed
+5852 -455

No files matched your search

+9
View File
@@ -41,11 +41,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email_opt = isset($_POST['email_opt_out']) ? 1 : 0;
$sms_opt = isset($_POST['sms_opt_out']) ? 1 : 0;
$marketing = isset($_POST['marketing_consent']) ? 1 : 0;
$before = db_get_user($pdo, (int) $user['id']) ?? [];
$pdo->prepare(
"UPDATE users SET phone=?, address=?, city=?, postal_code=?,
email_opt_out=?, sms_opt_out=?, marketing_consent=?
WHERE id=?"
)->execute([$phone, $address, $city, $postal_code, $email_opt, $sms_opt, $marketing, $user['id']]);
audit('user.profile_update', [
'target_type' => 'user', 'target_id' => (int) $user['id'], 'target_label' => (string) $user['name'],
'changes' => platform_audit_diff(
array_intersect_key($before, array_flip(['phone', 'address', 'city', 'postal_code', 'email_opt_out', 'sms_opt_out', 'marketing_consent'])),
['phone' => $phone, 'address' => $address, 'city' => $city, 'postal_code' => $postal_code,
'email_opt_out' => (string) $email_opt, 'sms_opt_out' => (string) $sms_opt, 'marketing_consent' => (string) $marketing]
),
]);
$saved = true;
}
}