add user confirmation

This commit is contained in:
Francesco Picone
2025-12-09 17:50:01 +01:00
parent 10f709a970
commit 402826b7ef
10 changed files with 611 additions and 61 deletions

1
.gitignore vendored
View File

@@ -19,6 +19,7 @@ test_email.php
# Log
*.log
logs/
# OS
.DS_Store

View File

@@ -29,6 +29,45 @@ if (isset($_GET['toggle_active']) && is_numeric($_GET['toggle_active'])) {
exit;
}
// Gestione re-invio email verifica
if (isset($_GET['resend_verification']) && is_numeric($_GET['resend_verification'])) {
$user_id = (int)$_GET['resend_verification'];
try {
$pdo = get_db_connection();
$stmt = $pdo->prepare("SELECT id, email, first_name, email_verified FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
if ($user && !$user['email_verified']) {
// Genera nuovo token
$email_token = bin2hex(random_bytes(32));
$token_expires = date('Y-m-d H:i:s', strtotime('+24 hours'));
$stmt = $pdo->prepare("UPDATE users SET email_token = ?, email_token_expires = ? WHERE id = ?");
$stmt->execute([$email_token, $token_expires, $user_id]);
// Invia email
$verify_url = SITE_URL . "/verify_email.php?token=" . $email_token;
$subject = "Conferma il tuo account su " . SITE_NAME;
$body = "<p>Ciao <strong>" . htmlspecialchars($user['first_name']) . "</strong>,</p>
<p>Un amministratore ha inviato nuovamente il link di verifica per il tuo account.</p>
<p><a href='" . $verify_url . "' style='display: inline-block; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 5px;'>Conferma Email</a></p>
<p>Questo link è valido per 24 ore.</p>";
send_email($user['email'], $subject, $body);
set_flash_message('success', 'Email di verifica inviata a ' . htmlspecialchars($user['email']));
} else {
set_flash_message('error', 'Utente già verificato o non trovato');
}
} catch (Exception $e) {
set_flash_message('error', 'Errore durante l\'invio dell\'email');
}
header('Location: users.php');
exit;
}
// Ottieni tutti gli utenti non admin
$pdo = get_db_connection();
$stmt = $pdo->query("
@@ -102,6 +141,7 @@ $users = $stmt->fetchAll();
<tr>
<th>Nome</th>
<th>Email</th>
<th>Stato Email</th>
<th>Registrato il</th>
<th>Ultimo Accesso</th>
<th>Acquisti</th>
@@ -116,7 +156,16 @@ $users = $stmt->fetchAll();
<td>
<strong><?php echo htmlspecialchars($user['first_name'] . ' ' . $user['last_name']); ?></strong>
</td>
<td><?php echo htmlspecialchars($user['email']); ?></td>
<td>
<?php echo htmlspecialchars($user['email']); ?>
</td>
<td>
<?php if ($user['email_verified']): ?>
<span class="text-success">✓ Verificata</span>
<?php else: ?>
<span class="text-warning">⚠️ Non verificata</span>
<?php endif; ?>
</td>
<td><?php echo format_date($user['created_at']); ?></td>
<td>
<?php
@@ -137,6 +186,14 @@ $users = $stmt->fetchAll();
class="btn btn-small <?php echo $user['is_active'] ? 'btn-danger' : 'btn-success'; ?>">
<?php echo $user['is_active'] ? 'Blocca' : 'Sblocca'; ?>
</a>
<?php if (!$user['email_verified']): ?>
<a href="users.php?resend_verification=<?php echo $user['id']; ?>"
class="btn btn-small btn-secondary"
style="margin-left: 5px;"
onclick="return confirm('Inviare nuovamente l\'email di verifica?');">
📧 Re-Invia
</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>

View File

@@ -0,0 +1,23 @@
-- Aggiunge campi per verifica email agli utenti esistenti
-- Esegui questo script per aggiornare il database senza perdere dati
USE pilatesplatform;
-- Aggiungi campi per verifica email
ALTER TABLE users
ADD COLUMN email_verified BOOLEAN DEFAULT FALSE COMMENT 'True se email verificata' AFTER is_active,
ADD COLUMN email_token VARCHAR(64) DEFAULT NULL COMMENT 'Token per verifica email' AFTER email_verified,
ADD COLUMN email_token_expires DATETIME DEFAULT NULL COMMENT 'Scadenza token verifica email' AFTER email_token;
-- Aggiungi indici per performance
ALTER TABLE users
ADD INDEX idx_email_verified (email_verified),
ADD INDEX idx_email_token (email_token);
-- Imposta tutti gli utenti esistenti come verificati (per retrocompatibilità)
UPDATE users SET email_verified = TRUE WHERE email_verified = FALSE;
-- Imposta admin come verificato
UPDATE users SET email_verified = TRUE WHERE is_admin = TRUE;
SELECT 'Migrazione completata! Campi email_verified, email_token, email_token_expires aggiunti.' AS status;

View File

@@ -22,6 +22,9 @@ CREATE TABLE IF NOT EXISTS users (
last_name VARCHAR(100) NOT NULL COMMENT 'Cognome',
is_admin BOOLEAN DEFAULT FALSE COMMENT 'True se amministratore',
is_active BOOLEAN DEFAULT TRUE COMMENT 'Permette di disabilitare account',
email_verified BOOLEAN DEFAULT FALSE COMMENT 'True se email verificata',
email_token VARCHAR(64) DEFAULT NULL COMMENT 'Token per verifica email',
email_token_expires DATETIME DEFAULT NULL COMMENT 'Scadenza token verifica email',
profile_image VARCHAR(255) DEFAULT NULL COMMENT 'URL immagine profilo',
phone VARCHAR(20) DEFAULT NULL COMMENT 'Numero telefono opzionale',
created_at DATETIME NOT NULL COMMENT 'Data registrazione',
@@ -31,6 +34,8 @@ CREATE TABLE IF NOT EXISTS users (
INDEX idx_email (email),
INDEX idx_is_admin (is_admin),
INDEX idx_email_verified (email_verified),
INDEX idx_email_token (email_token),
INDEX idx_deleted_at (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Utenti della piattaforma';

View File

@@ -208,17 +208,22 @@ function get_user_by_id($user_id) {
* @param string $first_name Nome
* @param string $last_name Cognome
* @param bool $is_admin Se è amministratore
* @param string|null $email_token Token verifica email
* @param string|null $token_expires Scadenza token
* @return int|false ID del nuovo utente o false in caso di errore
*/
function create_user($email, $password, $first_name, $last_name, $is_admin = false) {
function create_user($email, $password, $first_name, $last_name, $is_admin = false, $email_token = null, $token_expires = null) {
$pdo = get_db_connection();
$hashed_password = hash_password($password);
try {
$stmt = $pdo->prepare("
INSERT INTO users (email, password, first_name, last_name, is_admin, created_at)
VALUES (?, ?, ?, ?, ?, NOW())
INSERT INTO users (
email, password, first_name, last_name, is_admin,
email_verified, email_token, email_token_expires, created_at
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())
");
$stmt->execute([
@@ -226,12 +231,16 @@ function create_user($email, $password, $first_name, $last_name, $is_admin = fal
$hashed_password,
$first_name,
$last_name,
$is_admin ? 1 : 0
$is_admin ? 1 : 0,
$is_admin ? 1 : 0, // Admin sempre verificati
$email_token,
$token_expires
]);
return $pdo->lastInsertId();
} catch (PDOException $e) {
error_log("Create user error: " . $e->getMessage());
return false;
}
}

View File

@@ -39,8 +39,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$user = get_user_by_email($email);
if ($user && verify_password($password, $user['password'])) {
// Password corretta - effettua il login
// Password corretta - verifica se email è confermata
// Admin possono sempre accedere
if (!$user['is_admin'] && !$user['email_verified']) {
$error = 'Devi verificare la tua email prima di accedere. <a href="resend_verification.php?email=' . urlencode($email) . '" style="color: #667eea; font-weight: bold;">Invia nuovo link</a>';
} elseif (!$user['is_active']) {
$error = 'Il tuo account è stato disattivato. Contatta l\'amministratore.';
} else {
// Aggiorna data ultimo accesso
$pdo = get_db_connection();
$stmt = $pdo->prepare("UPDATE users SET last_login = NOW() WHERE id = ?");
@@ -71,7 +77,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Location: user/dashboard.php');
}
exit;
}
} else {
$error = 'Email o password non corretti';
}
@@ -103,7 +109,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
<?php if ($error): ?>
<div class="alert alert-error">
<?php echo htmlspecialchars($error); ?>
<?php echo $error; // Contiene HTML sicuro per link ?>
</div>
<?php endif; ?>

View File

@@ -45,14 +45,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (get_user_by_email($email)) {
$error = 'Questa email è già registrata';
} else {
// Crea il nuovo utente
$user_id = create_user($email, $password, $first_name, $last_name);
// Genera token di verifica email
$email_token = bin2hex(random_bytes(32));
$token_expires = date('Y-m-d H:i:s', strtotime('+24 hours'));
// Crea il nuovo utente (non verificato)
$user_id = create_user($email, $password, $first_name, $last_name, false, $email_token, $token_expires);
if ($user_id) {
$success = true;
// Invia email di benvenuto
$subject = "Benvenuto su " . SITE_NAME . "!";
// Invia email di verifica
$verify_url = SITE_URL . "/verify_email.php?token=" . $email_token;
$subject = "Conferma il tuo account su " . SITE_NAME;
$body = "
<html>
<head>
@@ -63,27 +68,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }
.button { display: inline-block; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 5px; margin: 20px 0; }
.footer { text-align: center; color: #999; font-size: 12px; margin-top: 20px; }
.warning { background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0; }
</style>
</head>
<body>
<div class='container'>
<div class='header'>
<h1>Benvenuto su " . SITE_NAME . "!</h1>
<h1>Conferma il tuo account</h1>
</div>
<div class='content'>
<p>Ciao <strong>" . htmlspecialchars($first_name) . "</strong>,</p>
<p>Grazie per esserti registrato sulla nostra piattaforma! Il tuo account è stato creato con successo.</p>
<p>Grazie per esserti registrato su " . SITE_NAME . "!</p>
<p>Per completare la registrazione e attivare il tuo account, devi confermare il tuo indirizzo email cliccando sul pulsante qui sotto:</p>
<div style='text-align: center;'>
<a href='" . $verify_url . "' class='button'>✅ Conferma Email</a>
</div>
<p style='font-size: 14px; color: #666;'>Oppure copia e incolla questo link nel tuo browser:<br>
<a href='" . $verify_url . "'>" . $verify_url . "</a></p>
<div class='warning'>
<strong>⏰ Importante:</strong> Questo link è valido per 24 ore. Dopo questo periodo dovrai richiedere un nuovo link di verifica.
</div>
<p><strong>I tuoi dati di accesso:</strong></p>
<ul>
<li>Email: " . htmlspecialchars($email) . "</li>
<li>Password: quella che hai scelto durante la registrazione</li>
</ul>
<p>Ora puoi accedere al catalogo delle nostre lezioni e iniziare il tuo percorso di Pilates!</p>
<div style='text-align: center;'>
<a href='" . SITE_URL . "/user/dashboard.php' class='button'>Vai alla Dashboard</a>
</div>
<p>Se hai domande o hai bisogno di assistenza, non esitare a contattarci.</p>
<p>Buon allenamento!<br>Il team di " . SITE_NAME . "</p>
<p>Una volta verificata la tua email, potrai accedere al catalogo delle nostre lezioni e iniziare il tuo percorso di Pilates!</p>
<p>Se non hai richiesto questa registrazione, ignora questa email.</p>
<p>A presto!<br>Il team di " . SITE_NAME . "</p>
</div>
<div class='footer'>
<p>Questa è una email automatica, per favore non rispondere a questo messaggio.</p>
@@ -99,7 +111,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pdo = get_db_connection();
$stmt = $pdo->prepare("
INSERT INTO activity_log (user_id, action, description, ip_address, user_agent, created_at)
VALUES (?, 'register', 'Nuovo utente registrato', ?, ?, NOW())
VALUES (?, 'register', 'Nuovo utente registrato - in attesa verifica email', ?, ?, NOW())
");
$stmt->execute([
$user_id,
@@ -107,11 +119,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_SERVER['HTTP_USER_AGENT'] ?? null
]);
// Login automatico dopo registrazione
login_user($user_id, false);
// Reindirizza dopo 2 secondi
header("refresh:2;url=user/dashboard.php");
// NON fare login automatico - utente deve verificare email prima
// Reindirizza a pagina di conferma
header("refresh:3;url=login.php");
} else {
$error = 'Errore durante la registrazione. Riprova più tardi.';
}
@@ -154,7 +164,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
</div>
<?php endif; ?>
<?php if (!$success): ?>
<?php if ($success): ?>
<div class="alert alert-success">
<h3 style="margin-top: 0;">✅ Registrazione completata!</h3>
<p>Ti abbiamo inviato un'email di verifica a <strong><?php echo htmlspecialchars($email); ?></strong></p>
<p>Per attivare il tuo account, clicca sul link che troverai nell'email.</p>
<p class="text-muted" style="font-size: 14px; margin-top: 15px;">
⚠️ Il link è valido per 24 ore. Se non lo trovi, controlla la cartella spam.
</p>
<p style="margin-top: 20px;">Sarai reindirizzato alla pagina di login tra pochi secondi...</p>
</div>
<?php elseif (!$success): ?>
<form method="POST" action="">
<div class="form-group">
<label for="first_name" class="form-label">Nome</label>

207
resend_verification.php Normal file
View File

@@ -0,0 +1,207 @@
<?php
/**
* Re-Invio Email di Verifica
*
* Permette agli utenti di richiedere un nuovo link di verifica email
*/
require_once 'includes/config.php';
require_once 'includes/functions.php';
session_start();
$success = false;
$error = '';
$email = sanitize_input($_GET['email'] ?? '');
// Processa il form
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = sanitize_input($_POST['email'] ?? '');
if (empty($email)) {
$error = 'Inserisci la tua email';
} elseif (!validate_email($email)) {
$error = 'Email non valida';
} else {
try {
$pdo = get_db_connection();
// Trova utente
$stmt = $pdo->prepare("
SELECT id, first_name, email_verified
FROM users
WHERE email = ?
AND deleted_at IS NULL
");
$stmt->execute([$email]);
$user = $stmt->fetch();
if (!$user) {
// Per sicurezza, non rivelare se l'email esiste
$success = true;
} elseif ($user['email_verified']) {
$error = 'Questo account è già stato verificato. Puoi effettuare il login.';
} else {
// Genera nuovo token
$email_token = bin2hex(random_bytes(32));
$token_expires = date('Y-m-d H:i:s', strtotime('+24 hours'));
// Aggiorna token
$stmt = $pdo->prepare("
UPDATE users
SET email_token = ?,
email_token_expires = ?,
updated_at = NOW()
WHERE id = ?
");
$stmt->execute([$email_token, $token_expires, $user['id']]);
// Log attività
$stmt = $pdo->prepare("
INSERT INTO activity_log (user_id, action, description, ip_address, user_agent, created_at)
VALUES (?, 'resend_verification', 'Richiesto nuovo link verifica email', ?, ?, NOW())
");
$stmt->execute([
$user['id'],
$_SERVER['REMOTE_ADDR'] ?? null,
$_SERVER['HTTP_USER_AGENT'] ?? null
]);
// Invia email
$verify_url = SITE_URL . "/verify_email.php?token=" . $email_token;
$subject = "Conferma il tuo account su " . SITE_NAME;
$body = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; border-radius: 8px 8px 0 0; }
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }
.button { display: inline-block; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 5px; margin: 20px 0; }
.footer { text-align: center; color: #999; font-size: 12px; margin-top: 20px; }
.warning { background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0; }
</style>
</head>
<body>
<div class='container'>
<div class='header'>
<h1>Nuovo Link di Verifica</h1>
</div>
<div class='content'>
<p>Ciao <strong>" . htmlspecialchars($user['first_name']) . "</strong>,</p>
<p>Hai richiesto un nuovo link per verificare il tuo account su " . SITE_NAME . ".</p>
<p>Per completare la registrazione e attivare il tuo account, clicca sul pulsante qui sotto:</p>
<div style='text-align: center;'>
<a href='" . $verify_url . "' class='button'>✅ Conferma Email</a>
</div>
<p style='font-size: 14px; color: #666;'>Oppure copia e incolla questo link nel tuo browser:<br>
<a href='" . $verify_url . "'>" . $verify_url . "</a></p>
<div class='warning'>
<strong>⏰ Importante:</strong> Questo link è valido per 24 ore. Questo nuovo link sostituisce quello precedente.
</div>
<p>Se non hai richiesto questo link, ignora questa email e il tuo account rimarrà non verificato.</p>
<p>A presto!<br>Il team di " . SITE_NAME . "</p>
</div>
<div class='footer'>
<p>Questa è una email automatica, per favore non rispondere a questo messaggio.</p>
</div>
</div>
</body>
</html>
";
send_email($email, $subject, $body);
$success = true;
}
} catch (PDOException $e) {
$error = 'Errore durante l\'invio. Riprova più tardi.';
error_log("Resend verification error: " . $e->getMessage());
}
}
}
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Re-Invio Verifica Email - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<header class="header">
<div class="container">
<div class="header-content">
<h1 class="logo">
<a href="index.php" style="color: inherit; text-decoration: none;"><?php echo SITE_NAME; ?></a>
</h1>
</div>
</div>
</header>
<main class="container" style="max-width: 500px; margin: 50px auto;">
<div class="card">
<h2 class="section-title" style="text-align: center;">📧 Re-Invio Email di Verifica</h2>
<?php if ($error): ?>
<div class="alert alert-error">
<?php echo htmlspecialchars($error); ?>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success">
<h3 style="margin-top: 0;">✅ Email Inviata!</h3>
<p>Se l'email è registrata nel nostro sistema, riceverai un nuovo link di verifica.</p>
<p class="text-muted" style="font-size: 14px; margin-top: 15px;">
Controlla la tua casella email (e la cartella spam). Il link è valido per 24 ore.
</p>
<div style="text-align: center; margin-top: 25px;">
<a href="login.php" class="btn btn-primary">
← Torna al Login
</a>
</div>
</div>
<?php else: ?>
<p class="text-center text-muted" style="margin-bottom: 20px;">
Inserisci la tua email per ricevere un nuovo link di verifica
</p>
<form method="POST" action="">
<div class="form-group">
<label for="email" class="form-label">Email</label>
<input
type="email"
id="email"
name="email"
class="form-control"
value="<?php echo htmlspecialchars($email); ?>"
required
autofocus
placeholder="tua-email@esempio.com"
>
</div>
<button type="submit" class="btn btn-primary btn-large" style="width: 100%;">
📧 Invia Nuovo Link
</button>
</form>
<div class="text-center mt-2">
<p class="text-muted">
<a href="login.php">← Torna al Login</a>
</p>
</div>
<?php endif; ?>
</div>
</main>
<footer class="footer">
<div class="container">
<p>&copy; <?php echo date('Y'); ?> <?php echo SITE_NAME; ?>. Tutti i diritti riservati.</p>
</div>
</footer>
</body>
</html>

View File

@@ -2,15 +2,29 @@
"""
Script Python per invio email SMTP
Legge le credenziali da config.php e invia email tramite Gmail
Log solo in caso di errore
"""
import sys
import json
import re
import smtplib
import logging
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from pathlib import Path
from datetime import datetime
# Configura logging solo per errori
log_file = Path(__file__).parent / 'logs' / 'email_errors.log'
log_file.parent.mkdir(exist_ok=True)
logging.basicConfig(
filename=str(log_file),
level=logging.ERROR,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
def parse_php_config(config_path):
"""Estrae le configurazioni SMTP dal file config.php"""
@@ -86,19 +100,25 @@ def send_email(to_email, subject, html_body, config):
}
except smtplib.SMTPAuthenticationError as e:
error_msg = f'Autenticazione SMTP fallita per {to_email}: {str(e)}'
logging.error(error_msg)
return {
'success': False,
'error': f'Autenticazione SMTP fallita: {str(e)}'
'error': error_msg
}
except smtplib.SMTPException as e:
error_msg = f'Errore SMTP invio a {to_email}: {str(e)}'
logging.error(error_msg)
return {
'success': False,
'error': f'Errore SMTP: {str(e)}'
'error': error_msg
}
except Exception as e:
error_msg = f'Errore generico invio a {to_email}: {str(e)}'
logging.error(error_msg)
return {
'success': False,
'error': f'Errore generico: {str(e)}'
'error': error_msg
}
def main():
@@ -115,9 +135,11 @@ def main():
data = json.loads(sys.argv[1])
if 'to' not in data or 'subject' not in data or 'html' not in data:
error = 'Parametri mancanti: to, subject, html sono obbligatori'
logging.error(error)
print(json.dumps({
'success': False,
'error': 'Parametri mancanti: to, subject, html sono obbligatori'
'error': error
}))
sys.exit(1)
@@ -133,15 +155,19 @@ def main():
sys.exit(0 if result['success'] else 1)
except json.JSONDecodeError as e:
error = f'JSON non valido: {str(e)}'
logging.error(error)
print(json.dumps({
'success': False,
'error': f'JSON non valido: {str(e)}'
'error': error
}))
sys.exit(1)
except Exception as e:
error = f'Errore: {str(e)}'
logging.error(error)
print(json.dumps({
'success': False,
'error': f'Errore: {str(e)}'
'error': error
}))
sys.exit(1)

196
verify_email.php Normal file
View File

@@ -0,0 +1,196 @@
<?php
/**
* Verifica Email
*
* Conferma l'indirizzo email dell'utente tramite token
*/
require_once 'includes/config.php';
require_once 'includes/functions.php';
session_start();
$success = false;
$error = '';
$email = '';
// Verifica token
if (isset($_GET['token']) && !empty($_GET['token'])) {
$token = sanitize_input($_GET['token']);
try {
$pdo = get_db_connection();
// Trova utente con questo token
$stmt = $pdo->prepare("
SELECT id, email, first_name, email_token_expires, email_verified
FROM users
WHERE email_token = ?
AND deleted_at IS NULL
");
$stmt->execute([$token]);
$user = $stmt->fetch();
if (!$user) {
$error = 'Token non valido o già utilizzato.';
} elseif ($user['email_verified']) {
$error = 'Questo account è già stato verificato. Puoi effettuare il login.';
$email = $user['email'];
} elseif (strtotime($user['email_token_expires']) < time()) {
$error = 'Il token è scaduto. Richiedi un nuovo link di verifica dalla pagina di login.';
$email = $user['email'];
} else {
// Token valido - verifica email
$stmt = $pdo->prepare("
UPDATE users
SET email_verified = TRUE,
email_token = NULL,
email_token_expires = NULL,
updated_at = NOW()
WHERE id = ?
");
$stmt->execute([$user['id']]);
// Log attività
$stmt = $pdo->prepare("
INSERT INTO activity_log (user_id, action, description, ip_address, user_agent, created_at)
VALUES (?, 'email_verified', 'Email verificata con successo', ?, ?, NOW())
");
$stmt->execute([
$user['id'],
$_SERVER['REMOTE_ADDR'] ?? null,
$_SERVER['HTTP_USER_AGENT'] ?? null
]);
// Invia email di benvenuto
$subject = "Benvenuto su " . SITE_NAME . "!";
$body = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; border-radius: 8px 8px 0 0; }
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }
.button { display: inline-block; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 5px; margin: 20px 0; }
.footer { text-align: center; color: #999; font-size: 12px; margin-top: 20px; }
</style>
</head>
<body>
<div class='container'>
<div class='header'>
<h1>✅ Account Attivato!</h1>
</div>
<div class='content'>
<p>Ciao <strong>" . htmlspecialchars($user['first_name']) . "</strong>,</p>
<p>🎉 Il tuo account è stato verificato con successo!</p>
<p>Ora puoi accedere alla piattaforma e iniziare a esplorare il nostro catalogo di lezioni di Pilates.</p>
<div style='text-align: center;'>
<a href='" . SITE_URL . "/login.php' class='button'>Accedi Ora</a>
</div>
<p><strong>Cosa puoi fare ora:</strong></p>
<ul>
<li>🎥 Guarda le lezioni demo gratuite</li>
<li>📚 Esplora il catalogo completo</li>
<li>🛒 Acquista le lezioni che ti interessano</li>
<li>👤 Personalizza il tuo profilo</li>
</ul>
<p>Se hai domande o hai bisogno di assistenza, non esitare a contattarci.</p>
<p>Buon allenamento!<br>Il team di " . SITE_NAME . "</p>
</div>
<div class='footer'>
<p>Questa è una email automatica, per favore non rispondere a questo messaggio.</p>
</div>
</div>
</body>
</html>
";
send_email($user['email'], $subject, $body);
$success = true;
$email = $user['email'];
}
} catch (PDOException $e) {
$error = 'Errore durante la verifica. Riprova più tardi.';
error_log("Email verification error: " . $e->getMessage());
}
} else {
$error = 'Token mancante. Controlla il link nell\'email di verifica.';
}
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Verifica Email - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<header class="header">
<div class="container">
<div class="header-content">
<h1 class="logo">
<a href="index.php" style="color: inherit; text-decoration: none;"><?php echo SITE_NAME; ?></a>
</h1>
</div>
</div>
</header>
<main class="container" style="max-width: 600px; margin: 50px auto;">
<div class="card">
<h2 class="section-title" style="text-align: center;">
<?php echo $success ? '✅ Email Verificata!' : '❌ Verifica Fallita'; ?>
</h2>
<?php if ($success): ?>
<div class="alert alert-success">
<p style="font-size: 16px; margin-bottom: 15px;">
Il tuo account è stato attivato con successo!
</p>
<p>
Email verificata: <strong><?php echo htmlspecialchars($email); ?></strong>
</p>
<p style="margin-top: 20px;">
Ora puoi accedere alla piattaforma e iniziare il tuo percorso di Pilates!
</p>
<div style="text-align: center; margin-top: 30px;">
<a href="login.php" class="btn btn-primary btn-large">
🔐 Vai al Login
</a>
</div>
</div>
<?php else: ?>
<div class="alert alert-error">
<p style="font-size: 16px; margin-bottom: 15px;">
<?php echo htmlspecialchars($error); ?>
</p>
<?php if ($email): ?>
<p style="margin-top: 20px;">
Puoi richiedere un nuovo link di verifica dalla pagina di login.
</p>
<?php endif; ?>
<div style="text-align: center; margin-top: 30px;">
<a href="login.php" class="btn btn-primary">
← Torna al Login
</a>
<?php if ($email): ?>
<a href="resend_verification.php?email=<?php echo urlencode($email); ?>" class="btn btn-secondary" style="margin-left: 10px;">
📧 Invia Nuovo Link
</a>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</div>
</main>
<footer class="footer">
<div class="container">
<p>&copy; <?php echo date('Y'); ?> <?php echo SITE_NAME; ?>. Tutti i diritti riservati.</p>
</div>
</footer>
</body>
</html>