feat(rgpd): pedido de acesso/apagamento de dados + processo escrito (item 9.5)
- migration_20260925_rgpd_requests.sql: tabela rgpd_requests (email, tipo, estado, consentimento). - config/functions_rgpd.php: rgpd_find() (acesso, art.º 15) e rgpd_erase() (apagamento por anonimização, art.º 17) sobre membership_leads/trial_leads/ event_leads, + CRUD dos pedidos. - Política de Privacidade: formulário público (POST + CSRF + anti-spam) para pedir acesso ou apagamento, e o processo escrito (resposta em 30 dias). - Backoffice: página "Pedidos RGPD" (nav + index) para exportar os dados de um email (CSV, audit) ou anonimizá-los (POST + CSRF, audit). O email está desligado, por isso os pedidos ficam guardados (como as leads), não dependem de SMTP. Texto legal com placeholders — rever com jurista antes do go-live (como já constava na Política). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
116817e2de
commit
3f2c505c17
6 files changed
+248
-1
No files matched your search
+62
-1
@@ -11,6 +11,36 @@ require __DIR__ . '/_open.php';
|
||||
$pp_name = htmlspecialchars($info['name'] ?? 'FitMe 3070');
|
||||
$pp_email = htmlspecialchars($info['email'] ?? '');
|
||||
$pp_addr = htmlspecialchars($info['adress'] ?? '');
|
||||
|
||||
// Pedido RGPD (acesso/apagamento). POST + CSRF + anti-spam; fica guardado
|
||||
// (o email está desligado, não pode depender de SMTP) e é processado no
|
||||
// backoffice (Sistema → Pedidos RGPD).
|
||||
$rgpd_status = '';
|
||||
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
|
||||
csrf_check();
|
||||
$rgpd_email = trim((string) ($_POST['rgpd_email'] ?? ''));
|
||||
$rgpd_type = (string) ($_POST['rgpd_type'] ?? '') === 'apagamento' ? 'apagamento' : 'acesso';
|
||||
$rgpd_msg = trim((string) ($_POST['rgpd_message'] ?? ''));
|
||||
$rgpd_consent = !empty($_POST['rgpd_consent']);
|
||||
if (!filter_var($rgpd_email, FILTER_VALIDATE_EMAIL) || !$rgpd_consent) {
|
||||
$rgpd_status = 'erro';
|
||||
} elseif (public_form_screen($pdo, 'rgpd', 'rgpd_requests', $rgpd_email, $rgpd_msg) !== null) {
|
||||
$rgpd_status = 'ok'; // anti-spam: mesma resposta de sucesso
|
||||
} else {
|
||||
try {
|
||||
db_rgpd_request_create($pdo, [
|
||||
'gym_id' => (int) $gym['id'],
|
||||
'email' => $rgpd_email,
|
||||
'request_type' => $rgpd_type,
|
||||
'message' => $rgpd_msg,
|
||||
'consent' => 1,
|
||||
]);
|
||||
$rgpd_status = 'ok';
|
||||
} catch (Throwable $e) {
|
||||
$rgpd_status = 'erro';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<section class="privacy-section" style="padding: 140px 0 60px;">
|
||||
<div class="container">
|
||||
@@ -59,10 +89,41 @@ $pp_addr = htmlspecialchars($info['adress'] ?? '');
|
||||
<p>O mapa da secção de contactos é do <b>Google Maps</b> e só é carregado se carregares em «Mostrar mapa»; nesse momento a Google recebe o teu endereço IP e pode guardar cookies, segundo a <a href="https://policies.google.com/privacy" target="_blank" rel="noopener">política da Google</a>. As avaliações apresentadas vêm do perfil público do ginásio no Google; as fotos dos autores são guardadas neste site para o teu navegador não ter de as pedir à Google.</p>
|
||||
|
||||
<h2 class="h4 mt-4">5. Os teus direitos</h2>
|
||||
<p>Tens direito de acesso, retificação, apagamento, limitação, portabilidade e oposição, e de retirar o consentimento a qualquer momento (sem afetar o tratamento feito até aí). Basta escreveres para <a href="mailto:<?= $pp_email ?>"><?= $pp_email !== '' ? $pp_email : '[EMAIL]' ?></a>; respondemos no prazo de um mês.
|
||||
<p>Tens direito de acesso, retificação, apagamento, limitação, portabilidade e oposição, e de retirar o consentimento a qualquer momento (sem afetar o tratamento feito até aí). Podes pedir a exportação dos teus dados ou o seu apagamento com o formulário abaixo; respondemos no prazo de um mês.
|
||||
Se tiveres conta na área de cliente, podes corrigir os teus dados e preferências no teu perfil.
|
||||
Tens ainda o direito de apresentar reclamação à Comissão Nacional de Proteção de Dados (<a href="https://www.cnpd.pt" target="_blank" rel="noopener">www.cnpd.pt</a>).</p>
|
||||
|
||||
<h3 class="h6 mt-4 mb-2">Pedir acesso ou apagamento</h3>
|
||||
<?php if ($rgpd_status === 'ok'): ?>
|
||||
<div class="alert alert-success py-2">Pedido recebido. Vamos responder no prazo de um mês.</div>
|
||||
<?php elseif ($rgpd_status === 'erro'): ?>
|
||||
<div class="alert alert-danger py-2">Não foi possível enviar o pedido. Confirma o e-mail e tenta de novo.</div>
|
||||
<?php endif; ?>
|
||||
<form method="POST" action="" class="mt-2 mb-3" style="max-width:520px;">
|
||||
<?= public_form_trap('rgpd') /* honeypot + carimbo + prova de JS */ ?>
|
||||
<?= csrf_field() ?>
|
||||
<div class="mb-2">
|
||||
<label class="form-label" for="rgpd_email">O teu e-mail</label>
|
||||
<input type="email" class="form-control" id="rgpd_email" name="rgpd_email" required>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label" for="rgpd_type">O que pretendes?</label>
|
||||
<select class="form-select" id="rgpd_type" name="rgpd_type">
|
||||
<option value="acesso">Aceder aos meus dados (exportação)</option>
|
||||
<option value="apagamento">Apagar os meus dados</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label" for="rgpd_message">Mensagem (opcional)</label>
|
||||
<textarea class="form-control" id="rgpd_message" name="rgpd_message" rows="2"></textarea>
|
||||
</div>
|
||||
<div class="form-check mb-3">
|
||||
<input class="form-check-input" type="checkbox" id="rgpd_consent" name="rgpd_consent" value="1" required>
|
||||
<label class="form-check-label" for="rgpd_consent">Consinto no tratamento dos meus dados para responder a este pedido.</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Enviar pedido</button>
|
||||
</form>
|
||||
|
||||
<h2 class="h4 mt-4">6. Cookies</h2>
|
||||
<p>Este site usa apenas um cookie técnico de sessão (<code>FIT_SESS</code>), necessário para os formulários e para a área reservada, que expira ao fechar o navegador. Não usamos cookies de publicidade nem de estatística. O Google Maps só coloca cookies se escolheres ver o mapa.</p>
|
||||
|
||||
|
||||
Reference in new issue
Block a user