Compare commits
10 Commits
91e4559bd2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95a7faf5eb | ||
|
|
402826b7ef | ||
|
|
10f709a970 | ||
|
|
568a02251c | ||
|
|
b79b31df69 | ||
|
|
b612146dfe | ||
|
|
80e733adfb | ||
|
|
77377cbaf1 | ||
|
|
1ea20d24a0 | ||
|
|
33b24d8395 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,6 +19,7 @@ test_email.php
|
|||||||
|
|
||||||
# Log
|
# Log
|
||||||
*.log
|
*.log
|
||||||
|
logs/
|
||||||
|
|
||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
66
README.md
66
README.md
@@ -49,13 +49,10 @@ Piattaforma completa per vendere videolezioni e lezioni live di Pilates. Svilupp
|
|||||||
### Requisiti
|
### Requisiti
|
||||||
- **PHP** 7.4 o superiore (8.0+ raccomandato)
|
- **PHP** 7.4 o superiore (8.0+ raccomandato)
|
||||||
- **MySQL** 5.7 o superiore (o MariaDB 10.3+)
|
- **MySQL** 5.7 o superiore (o MariaDB 10.3+)
|
||||||
|
- **Python** 3.6 o superiore (per invio email SMTP)
|
||||||
- **Web Server** (Apache, Nginx, o PHP built-in server per sviluppo)
|
- **Web Server** (Apache, Nginx, o PHP built-in server per sviluppo)
|
||||||
- **Account PayPal** Sandbox (per test) o Business (per produzione)
|
- **Account PayPal** Sandbox (per test) o Business (per produzione)
|
||||||
- **FFmpeg** (opzionale, per conversione automatica video in MP4)
|
- **FFmpeg** (opzionale, per conversione automatica video in MP4)
|
||||||
- **PHP** 7.4 o superiore
|
|
||||||
- **MySQL** 5.7 o superiore (o MariaDB 10.3+)
|
|
||||||
- **Web Server** (Apache, Nginx, o PHP built-in server per sviluppo)
|
|
||||||
- **Account PayPal** Sandbox (per test) o Business (per produzione)
|
|
||||||
|
|
||||||
### Passo 1: Copia i File
|
### Passo 1: Copia i File
|
||||||
```bash
|
```bash
|
||||||
@@ -115,7 +112,7 @@ define('SECRET_KEY', 'CAMBIA-QUESTA-CHIAVE-CON-STRINGA-CASUALE-LUNGA-E-SICURA');
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Email SMTP con Gmail ⭐ **IMPORTANTE**
|
#### Email SMTP con Gmail ⭐ **IMPORTANTE**
|
||||||
Per inviare email (recupero password), configura Gmail SMTP:
|
Per inviare email (recupero password, registrazione), configura Gmail SMTP:
|
||||||
|
|
||||||
1. **Abilita verifica 2 fattori** sul tuo account Gmail
|
1. **Abilita verifica 2 fattori** sul tuo account Gmail
|
||||||
2. Vai su [Password per le app](https://myaccount.google.com/apppasswords)
|
2. Vai su [Password per le app](https://myaccount.google.com/apppasswords)
|
||||||
@@ -127,14 +124,30 @@ In `includes/config.php`:
|
|||||||
```php
|
```php
|
||||||
define('USE_SMTP', true); // Attiva SMTP
|
define('USE_SMTP', true); // Attiva SMTP
|
||||||
define('SMTP_HOST', 'smtp.gmail.com');
|
define('SMTP_HOST', 'smtp.gmail.com');
|
||||||
define('SMTP_PORT', 587);
|
define('SMTP_PORT', 587); // 587 per TLS, 465 per SSL
|
||||||
define('SMTP_USERNAME', 'tua-email@gmail.com'); // La tua Gmail
|
define('SMTP_USERNAME', 'tua-email@gmail.com'); // La tua Gmail
|
||||||
define('SMTP_PASSWORD', 'abcd efgh ijkl mnop'); // Password app (16 caratteri)
|
define('SMTP_PASSWORD', 'abcd efgh ijkl mnop'); // Password app (16 caratteri)
|
||||||
define('SMTP_ENCRYPTION', 'tls');
|
define('SMTP_ENCRYPTION', 'tls'); // tls (porta 587) o ssl (porta 465)
|
||||||
```
|
```
|
||||||
|
|
||||||
⚠️ **Non usare la password normale di Gmail**, usa solo la password applicazione!
|
⚠️ **Non usare la password normale di Gmail**, usa solo la password applicazione!
|
||||||
|
|
||||||
|
**Sistema di invio email:**
|
||||||
|
- Le email vengono inviate tramite script Python (`send_email.py`)
|
||||||
|
- Python 3.6+ deve essere installato sul server
|
||||||
|
- Lo script legge automaticamente le credenziali da `config.php`
|
||||||
|
- Più affidabile e stabile rispetto a SMTP nativo PHP
|
||||||
|
|
||||||
|
Verifica installazione Python:
|
||||||
|
```bash
|
||||||
|
python3 --version
|
||||||
|
```
|
||||||
|
|
||||||
|
Se Python non è installato:
|
||||||
|
- **Ubuntu/Debian**: `sudo apt install python3`
|
||||||
|
- **CentOS/RHEL**: `sudo yum install python3`
|
||||||
|
- **Windows**: Scarica da [python.org](https://www.python.org/downloads/)
|
||||||
|
|
||||||
#### PayPal Sandbox (per Test)
|
#### PayPal Sandbox (per Test)
|
||||||
1. Vai su [PayPal Developer](https://developer.paypal.com/)
|
1. Vai su [PayPal Developer](https://developer.paypal.com/)
|
||||||
2. Accedi con il tuo account PayPal
|
2. Accedi con il tuo account PayPal
|
||||||
@@ -520,11 +533,39 @@ Crea `.htaccess` nella cartella `includes/`:
|
|||||||
- La piattaforma è già aggiornata per gestire valori null
|
- La piattaforma è già aggiornata per gestire valori null
|
||||||
- Se vedi ancora warning, verifica che tutti i file siano aggiornati
|
- Se vedi ancora warning, verifica che tutti i file siano aggiornati
|
||||||
|
|
||||||
### Reset Password non funziona
|
### Reset Password / Email non funzionano
|
||||||
- Verifica che le email vengano inviate correttamente
|
- Verifica che Python 3 sia installato: `python3 --version`
|
||||||
- Configura SMTP in `config.php` se `mail()` non funziona
|
- Controlla credenziali SMTP in `config.php`
|
||||||
- Il token scade dopo 1 ora per sicurezza
|
- Verifica che `send_email.py` abbia permessi esecuzione
|
||||||
- Controlla che la tabella `users` abbia i campi `reset_token` e `reset_expires`
|
- Testa invio dal profilo admin: pulsante "🧪 Testa Invio Email"
|
||||||
|
- Il token reset scade dopo 1 ora per sicurezza
|
||||||
|
- Controlla log errori PHP per dettagli (`error_log()`)
|
||||||
|
|
||||||
|
**Test manuale script Python:**
|
||||||
|
```bash
|
||||||
|
cd /path/to/pilates-platform
|
||||||
|
python3 send_email.py '{"to":"test@esempio.com","subject":"Test","html":"<p>Test email</p>"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Errori comuni:**
|
||||||
|
- `python3: command not found` → Installa Python 3
|
||||||
|
- `Authentication failed` → Verifica password applicazione Gmail
|
||||||
|
- `Connection refused` → Controlla porta (587 per TLS, 465 per SSL)
|
||||||
|
- `Script not found` → Verifica che `send_email.py` esista nella root del progetto
|
||||||
|
- `Permission denied` → Su Linux: `chmod +x send_email.py`
|
||||||
|
- Il token reset scade dopo 1 ora per sicurezza
|
||||||
|
- Controlla log errori PHP per dettagli
|
||||||
|
|
||||||
|
**Test manuale script Python:**
|
||||||
|
```bash
|
||||||
|
cd /path/to/pilates-platform
|
||||||
|
python3 send_email.py '{"to":"test@esempio.com","subject":"Test","html":"<p>Test email</p>"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Errori comuni:**
|
||||||
|
- `python3: command not found` → Installa Python 3
|
||||||
|
- `Authentication failed` → Verifica password applicazione Gmail
|
||||||
|
- `Connection refused` → Controlla porta (587 per TLS, 465 per SSL)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -550,6 +591,7 @@ pilates-platform/
|
|||||||
├── process_payment.php # Elabora pagamento PayPal
|
├── process_payment.php # Elabora pagamento PayPal
|
||||||
├── stream_video.php # Streaming protetto video (verifica permessi)
|
├── stream_video.php # Streaming protetto video (verifica permessi)
|
||||||
├── convert_videos.php # Conversione batch video in MP4 H.264
|
├── convert_videos.php # Conversione batch video in MP4 H.264
|
||||||
|
├── send_email.py # Script Python per invio email SMTP
|
||||||
├── test_password.php # Utility test hash password (debug)
|
├── test_password.php # Utility test hash password (debug)
|
||||||
├── test_email.php # Utility test invio email SMTP (debug)
|
├── test_email.php # Utility test invio email SMTP (debug)
|
||||||
└── README.md # Questo file
|
└── README.md # Questo file
|
||||||
|
|||||||
@@ -29,6 +29,45 @@ if (isset($_GET['toggle_active']) && is_numeric($_GET['toggle_active'])) {
|
|||||||
exit;
|
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
|
// Ottieni tutti gli utenti non admin
|
||||||
$pdo = get_db_connection();
|
$pdo = get_db_connection();
|
||||||
$stmt = $pdo->query("
|
$stmt = $pdo->query("
|
||||||
@@ -102,6 +141,7 @@ $users = $stmt->fetchAll();
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Nome</th>
|
<th>Nome</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
|
<th>Stato Email</th>
|
||||||
<th>Registrato il</th>
|
<th>Registrato il</th>
|
||||||
<th>Ultimo Accesso</th>
|
<th>Ultimo Accesso</th>
|
||||||
<th>Acquisti</th>
|
<th>Acquisti</th>
|
||||||
@@ -116,7 +156,16 @@ $users = $stmt->fetchAll();
|
|||||||
<td>
|
<td>
|
||||||
<strong><?php echo htmlspecialchars($user['first_name'] . ' ' . $user['last_name']); ?></strong>
|
<strong><?php echo htmlspecialchars($user['first_name'] . ' ' . $user['last_name']); ?></strong>
|
||||||
</td>
|
</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 echo format_date($user['created_at']); ?></td>
|
||||||
<td>
|
<td>
|
||||||
<?php
|
<?php
|
||||||
@@ -137,6 +186,14 @@ $users = $stmt->fetchAll();
|
|||||||
class="btn btn-small <?php echo $user['is_active'] ? 'btn-danger' : 'btn-success'; ?>">
|
class="btn btn-small <?php echo $user['is_active'] ? 'btn-danger' : 'btn-success'; ?>">
|
||||||
<?php echo $user['is_active'] ? 'Blocca' : 'Sblocca'; ?>
|
<?php echo $user['is_active'] ? 'Blocca' : 'Sblocca'; ?>
|
||||||
</a>
|
</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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|||||||
23
database/add_email_verification.sql
Normal file
23
database/add_email_verification.sql
Normal 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;
|
||||||
@@ -22,6 +22,9 @@ CREATE TABLE IF NOT EXISTS users (
|
|||||||
last_name VARCHAR(100) NOT NULL COMMENT 'Cognome',
|
last_name VARCHAR(100) NOT NULL COMMENT 'Cognome',
|
||||||
is_admin BOOLEAN DEFAULT FALSE COMMENT 'True se amministratore',
|
is_admin BOOLEAN DEFAULT FALSE COMMENT 'True se amministratore',
|
||||||
is_active BOOLEAN DEFAULT TRUE COMMENT 'Permette di disabilitare account',
|
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',
|
profile_image VARCHAR(255) DEFAULT NULL COMMENT 'URL immagine profilo',
|
||||||
phone VARCHAR(20) DEFAULT NULL COMMENT 'Numero telefono opzionale',
|
phone VARCHAR(20) DEFAULT NULL COMMENT 'Numero telefono opzionale',
|
||||||
created_at DATETIME NOT NULL COMMENT 'Data registrazione',
|
created_at DATETIME NOT NULL COMMENT 'Data registrazione',
|
||||||
@@ -31,6 +34,8 @@ CREATE TABLE IF NOT EXISTS users (
|
|||||||
|
|
||||||
INDEX idx_email (email),
|
INDEX idx_email (email),
|
||||||
INDEX idx_is_admin (is_admin),
|
INDEX idx_is_admin (is_admin),
|
||||||
|
INDEX idx_email_verified (email_verified),
|
||||||
|
INDEX idx_email_token (email_token),
|
||||||
INDEX idx_deleted_at (deleted_at)
|
INDEX idx_deleted_at (deleted_at)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Utenti della piattaforma';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Utenti della piattaforma';
|
||||||
|
|
||||||
@@ -230,6 +235,45 @@ INSERT INTO lessons (title, description, type, video_url, video_platform, thumbn
|
|||||||
NOW()
|
NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- ============================================
|
||||||
|
-- MIGRAZIONE: CONVERSIONE VIDEO (9 Dicembre 2025)
|
||||||
|
-- ============================================
|
||||||
|
-- Aggiunge campo per tracciare conversione video in MP4 H.264
|
||||||
|
|
||||||
|
ALTER TABLE lessons
|
||||||
|
ADD COLUMN IF NOT EXISTS video_converted BOOLEAN DEFAULT FALSE COMMENT 'True se il video è stato convertito in MP4 H.264'
|
||||||
|
AFTER video_platform;
|
||||||
|
|
||||||
|
-- Aggiorna i video esistenti come non convertiti
|
||||||
|
UPDATE lessons
|
||||||
|
SET video_converted = FALSE
|
||||||
|
WHERE type = 'video'
|
||||||
|
AND video_platform = 'local'
|
||||||
|
AND video_url IS NOT NULL
|
||||||
|
AND (video_converted IS NULL OR video_converted = FALSE);
|
||||||
|
|
||||||
|
-- ============================================
|
||||||
|
-- MIGRAZIONE: VERIFICA EMAIL (9 Dicembre 2025)
|
||||||
|
-- ============================================
|
||||||
|
-- Aggiunge campi per sistema di verifica email
|
||||||
|
|
||||||
|
-- Aggiungi campi per verifica email (se non esistono già)
|
||||||
|
ALTER TABLE users
|
||||||
|
ADD COLUMN IF NOT EXISTS email_verified BOOLEAN DEFAULT FALSE COMMENT 'True se email verificata' AFTER is_active,
|
||||||
|
ADD COLUMN IF NOT EXISTS email_token VARCHAR(64) DEFAULT NULL COMMENT 'Token per verifica email' AFTER email_verified,
|
||||||
|
ADD COLUMN IF NOT EXISTS email_token_expires DATETIME DEFAULT NULL COMMENT 'Scadenza token verifica email' AFTER email_token;
|
||||||
|
|
||||||
|
-- Aggiungi indici per performance (se non esistono già)
|
||||||
|
ALTER TABLE users
|
||||||
|
ADD INDEX IF NOT EXISTS idx_email_verified (email_verified),
|
||||||
|
ADD INDEX IF NOT EXISTS idx_email_token (email_token);
|
||||||
|
|
||||||
|
-- Imposta tutti gli utenti esistenti come verificati (per retrocompatibilità)
|
||||||
|
UPDATE users SET email_verified = TRUE WHERE email_verified = FALSE OR email_verified IS NULL;
|
||||||
|
|
||||||
|
-- Imposta admin come verificato
|
||||||
|
UPDATE users SET email_verified = TRUE WHERE is_admin = TRUE;
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- FINE SCRIPT
|
-- FINE SCRIPT
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|||||||
@@ -67,19 +67,21 @@ define('PAYPAL_API_URL', PAYPAL_SANDBOX ?
|
|||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
// Configurazione per l'invio di email
|
// Configurazione per l'invio di email
|
||||||
define('MAIL_FROM', 'pilatesstudio@gmail.com');
|
define('MAIL_FROM', 'rosavirgadamo_pilates@gmail.com');
|
||||||
define('MAIL_FROM_NAME', 'Pilates Studio');
|
define('MAIL_FROM_NAME', 'Pilates Studio');
|
||||||
|
|
||||||
// Usa SMTP per invio email affidabile
|
// Usa SMTP per invio email affidabile
|
||||||
define('USE_SMTP', true); // Imposta false per usare mail() PHP di base
|
define('USE_SMTP', true); // Imposta false per usare mail() PHP di base
|
||||||
|
|
||||||
// Impostazioni SMTP - Gmail
|
// Impostazioni SMTP - Gmail
|
||||||
|
// NOTA: Le email vengono inviate tramite script Python (send_email.py) per maggiore affidabilità
|
||||||
// Per Gmail: usa password applicazione da https://myaccount.google.com/apppasswords
|
// Per Gmail: usa password applicazione da https://myaccount.google.com/apppasswords
|
||||||
|
// Requisito: Python 3.6+ installato sul server (testa con: python3 --version)
|
||||||
define('SMTP_HOST', 'smtp.gmail.com');
|
define('SMTP_HOST', 'smtp.gmail.com');
|
||||||
define('SMTP_PORT', 587);
|
define('SMTP_PORT', 587);
|
||||||
define('SMTP_USERNAME', 'pyco.networking@gmail.com'); // Inserisci la tua email Gmail
|
define('SMTP_USERNAME', 'pyco.networking@gmail.com'); // Inserisci la tua email Gmail
|
||||||
define('SMTP_PASSWORD', 'iaxuxsvggkfmbzpa'); // Password applicazione (16 caratteri)
|
define('SMTP_PASSWORD', 'iaxuxsvggkfmbzpa'); // Password applicazione (16 caratteri)
|
||||||
define('SMTP_ENCRYPTION', 'tls'); // tls o ssl
|
define('SMTP_ENCRYPTION', 'tls'); // tls (porta 587) o ssl (porta 465)
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// CONFIGURAZIONE UPLOAD FILE
|
// CONFIGURAZIONE UPLOAD FILE
|
||||||
|
|||||||
@@ -208,17 +208,22 @@ function get_user_by_id($user_id) {
|
|||||||
* @param string $first_name Nome
|
* @param string $first_name Nome
|
||||||
* @param string $last_name Cognome
|
* @param string $last_name Cognome
|
||||||
* @param bool $is_admin Se è amministratore
|
* @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
|
* @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();
|
$pdo = get_db_connection();
|
||||||
|
|
||||||
$hashed_password = hash_password($password);
|
$hashed_password = hash_password($password);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
INSERT INTO users (email, password, first_name, last_name, is_admin, created_at)
|
INSERT INTO users (
|
||||||
VALUES (?, ?, ?, ?, ?, NOW())
|
email, password, first_name, last_name, is_admin,
|
||||||
|
email_verified, email_token, email_token_expires, created_at
|
||||||
|
)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())
|
||||||
");
|
");
|
||||||
|
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
@@ -226,12 +231,16 @@ function create_user($email, $password, $first_name, $last_name, $is_admin = fal
|
|||||||
$hashed_password,
|
$hashed_password,
|
||||||
$first_name,
|
$first_name,
|
||||||
$last_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();
|
return $pdo->lastInsertId();
|
||||||
|
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
|
error_log("Create user error: " . $e->getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,7 +442,7 @@ function send_email($to, $subject, $message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invia email tramite SMTP (Gmail)
|
* Invia email tramite script Python
|
||||||
*
|
*
|
||||||
* @param string $to Email destinatario
|
* @param string $to Email destinatario
|
||||||
* @param string $subject Oggetto email
|
* @param string $subject Oggetto email
|
||||||
@@ -442,11 +451,75 @@ function send_email($to, $subject, $message) {
|
|||||||
*/
|
*/
|
||||||
function send_smtp_email($to, $subject, $message) {
|
function send_smtp_email($to, $subject, $message) {
|
||||||
try {
|
try {
|
||||||
// Connessione al server SMTP
|
// Prepara dati JSON per lo script Python
|
||||||
$smtp = fsockopen(SMTP_HOST, SMTP_PORT, $errno, $errstr, 30);
|
$data = json_encode([
|
||||||
|
'to' => $to,
|
||||||
|
'subject' => $subject,
|
||||||
|
'html' => $message
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
|
|
||||||
|
// Percorso dello script Python
|
||||||
|
$script_path = __DIR__ . '/../send_email.py';
|
||||||
|
|
||||||
|
// Verifica che lo script esista
|
||||||
|
if (!file_exists($script_path)) {
|
||||||
|
error_log("Email Error: Script send_email.py non trovato");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Esegui script Python
|
||||||
|
$command = 'python3 ' . escapeshellarg($script_path) . ' ' . escapeshellarg($data) . ' 2>&1';
|
||||||
|
exec($command, $output, $return_code);
|
||||||
|
|
||||||
|
// Parse risposta JSON
|
||||||
|
$result = json_decode(implode("\n", $output), true);
|
||||||
|
|
||||||
|
if ($return_code === 0 && isset($result['success']) && $result['success']) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
$error_msg = isset($result['error']) ? $result['error'] : 'Errore sconosciuto';
|
||||||
|
error_log("Email Error: " . $error_msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log("Email Error: " . $e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invia email tramite SMTP PHP nativo (deprecato - usa send_smtp_email)
|
||||||
|
*
|
||||||
|
* @param string $to Email destinatario
|
||||||
|
* @param string $subject Oggetto email
|
||||||
|
* @param string $message Corpo email (HTML)
|
||||||
|
* @return bool True se inviata, false altrimenti
|
||||||
|
*/
|
||||||
|
function send_smtp_email_legacy($to, $subject, $message) {
|
||||||
|
try {
|
||||||
|
// Connessione al server SMTP con supporto SSL/TLS
|
||||||
|
$context = stream_context_create([
|
||||||
|
'ssl' => [
|
||||||
|
'verify_peer' => false,
|
||||||
|
'verify_peer_name' => false,
|
||||||
|
'allow_self_signed' => true
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Per SSL (porta 465) usa protocollo ssl://, per TLS (porta 587) connessione normale
|
||||||
|
$protocol = (SMTP_ENCRYPTION === 'ssl') ? 'ssl://' : '';
|
||||||
|
$smtp = stream_socket_client(
|
||||||
|
$protocol . SMTP_HOST . ':' . SMTP_PORT,
|
||||||
|
$errno,
|
||||||
|
$errstr,
|
||||||
|
30,
|
||||||
|
STREAM_CLIENT_CONNECT,
|
||||||
|
$context
|
||||||
|
);
|
||||||
|
|
||||||
if (!$smtp) {
|
if (!$smtp) {
|
||||||
error_log("SMTP Error: Impossibile connettersi a " . SMTP_HOST . ":" . SMTP_PORT);
|
error_log("SMTP Error: Impossibile connettersi a " . SMTP_HOST . ":" . SMTP_PORT . " - $errstr ($errno)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,12 +543,32 @@ function send_smtp_email($to, $subject, $message) {
|
|||||||
// Inizia TLS se richiesto
|
// Inizia TLS se richiesto
|
||||||
if (SMTP_ENCRYPTION === 'tls') {
|
if (SMTP_ENCRYPTION === 'tls') {
|
||||||
$send("STARTTLS");
|
$send("STARTTLS");
|
||||||
$read();
|
$response = $read();
|
||||||
|
|
||||||
// Usa una versione più compatibile di TLS
|
// Verifica risposta 220
|
||||||
$crypto_method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
|
if (strpos($response, '220') !== 0) {
|
||||||
if (!stream_socket_enable_crypto($smtp, true, $crypto_method)) {
|
error_log("SMTP Error: STARTTLS fallito - " . $response);
|
||||||
error_log("SMTP Error: Impossibile avviare crittografia TLS");
|
fclose($smtp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abilita TLS con metodo compatibile (fallback automatico tra TLSv1.2, TLSv1.1, TLSv1.0)
|
||||||
|
$crypto_methods = [
|
||||||
|
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
|
||||||
|
STREAM_CRYPTO_METHOD_TLS_CLIENT,
|
||||||
|
STREAM_CRYPTO_METHOD_SSLv23_CLIENT
|
||||||
|
];
|
||||||
|
|
||||||
|
$tls_enabled = false;
|
||||||
|
foreach ($crypto_methods as $method) {
|
||||||
|
if (@stream_socket_enable_crypto($smtp, true, $method)) {
|
||||||
|
$tls_enabled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$tls_enabled) {
|
||||||
|
error_log("SMTP Error: Impossibile avviare crittografia TLS con nessun metodo");
|
||||||
fclose($smtp);
|
fclose($smtp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
68
login.php
68
login.php
@@ -39,39 +39,45 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$user = get_user_by_email($email);
|
$user = get_user_by_email($email);
|
||||||
|
|
||||||
if ($user && verify_password($password, $user['password'])) {
|
if ($user && verify_password($password, $user['password'])) {
|
||||||
// Password corretta - effettua il login
|
// Password corretta - verifica se email è confermata
|
||||||
|
|
||||||
// Aggiorna data ultimo accesso
|
// Admin possono sempre accedere
|
||||||
$pdo = get_db_connection();
|
if (!$user['is_admin'] && !$user['email_verified']) {
|
||||||
$stmt = $pdo->prepare("UPDATE users SET last_login = NOW() WHERE id = ?");
|
$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>';
|
||||||
$stmt->execute([$user['id']]);
|
} elseif (!$user['is_active']) {
|
||||||
|
$error = 'Il tuo account è stato disattivato. Contatta l\'amministratore.';
|
||||||
// Log attività
|
|
||||||
$stmt = $pdo->prepare("
|
|
||||||
INSERT INTO activity_log (user_id, action, description, ip_address, user_agent, created_at)
|
|
||||||
VALUES (?, 'login', 'Utente ha effettuato il login', ?, ?, NOW())
|
|
||||||
");
|
|
||||||
$stmt->execute([
|
|
||||||
$user['id'],
|
|
||||||
$_SERVER['REMOTE_ADDR'] ?? null,
|
|
||||||
$_SERVER['HTTP_USER_AGENT'] ?? null
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Imposta la sessione
|
|
||||||
login_user($user['id'], $user['is_admin']);
|
|
||||||
|
|
||||||
// Reindirizza alla pagina appropriata
|
|
||||||
if (isset($_SESSION['redirect_after_login'])) {
|
|
||||||
$redirect = $_SESSION['redirect_after_login'];
|
|
||||||
unset($_SESSION['redirect_after_login']);
|
|
||||||
header("Location: $redirect");
|
|
||||||
} elseif ($user['is_admin']) {
|
|
||||||
header('Location: admin/dashboard.php');
|
|
||||||
} else {
|
} else {
|
||||||
header('Location: user/dashboard.php');
|
// Aggiorna data ultimo accesso
|
||||||
}
|
$pdo = get_db_connection();
|
||||||
exit;
|
$stmt = $pdo->prepare("UPDATE users SET last_login = 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 (?, 'login', 'Utente ha effettuato il login', ?, ?, NOW())
|
||||||
|
");
|
||||||
|
$stmt->execute([
|
||||||
|
$user['id'],
|
||||||
|
$_SERVER['REMOTE_ADDR'] ?? null,
|
||||||
|
$_SERVER['HTTP_USER_AGENT'] ?? null
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Imposta la sessione
|
||||||
|
login_user($user['id'], $user['is_admin']);
|
||||||
|
|
||||||
|
// Reindirizza alla pagina appropriata
|
||||||
|
if (isset($_SESSION['redirect_after_login'])) {
|
||||||
|
$redirect = $_SESSION['redirect_after_login'];
|
||||||
|
unset($_SESSION['redirect_after_login']);
|
||||||
|
header("Location: $redirect");
|
||||||
|
} elseif ($user['is_admin']) {
|
||||||
|
header('Location: admin/dashboard.php');
|
||||||
|
} else {
|
||||||
|
header('Location: user/dashboard.php');
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$error = 'Email o password non corretti';
|
$error = 'Email o password non corretti';
|
||||||
}
|
}
|
||||||
@@ -103,7 +109,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
|
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
<div class="alert alert-error">
|
<div class="alert alert-error">
|
||||||
<?php echo htmlspecialchars($error); ?>
|
<?php echo $error; // Contiene HTML sicuro per link ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
|||||||
58
register.php
58
register.php
@@ -45,14 +45,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
if (get_user_by_email($email)) {
|
if (get_user_by_email($email)) {
|
||||||
$error = 'Questa email è già registrata';
|
$error = 'Questa email è già registrata';
|
||||||
} else {
|
} else {
|
||||||
// Crea il nuovo utente
|
// Genera token di verifica email
|
||||||
$user_id = create_user($email, $password, $first_name, $last_name);
|
$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) {
|
if ($user_id) {
|
||||||
$success = true;
|
$success = true;
|
||||||
|
|
||||||
// Invia email di benvenuto
|
// Invia email di verifica
|
||||||
$subject = "Benvenuto su " . SITE_NAME . "!";
|
$verify_url = SITE_URL . "/verify_email.php?token=" . $email_token;
|
||||||
|
$subject = "Conferma il tuo account su " . SITE_NAME;
|
||||||
$body = "
|
$body = "
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -63,27 +68,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }
|
.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; }
|
.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; }
|
.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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class='container'>
|
<div class='container'>
|
||||||
<div class='header'>
|
<div class='header'>
|
||||||
<h1>Benvenuto su " . SITE_NAME . "!</h1>
|
<h1>Conferma il tuo account</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class='content'>
|
<div class='content'>
|
||||||
<p>Ciao <strong>" . htmlspecialchars($first_name) . "</strong>,</p>
|
<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>
|
<p><strong>I tuoi dati di accesso:</strong></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Email: " . htmlspecialchars($email) . "</li>
|
<li>Email: " . htmlspecialchars($email) . "</li>
|
||||||
<li>Password: quella che hai scelto durante la registrazione</li>
|
<li>Password: quella che hai scelto durante la registrazione</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Ora puoi accedere al catalogo delle nostre lezioni e iniziare il tuo percorso di Pilates!</p>
|
<p>Una volta verificata la tua email, potrai accedere al catalogo delle nostre lezioni e iniziare il tuo percorso di Pilates!</p>
|
||||||
<div style='text-align: center;'>
|
<p>Se non hai richiesto questa registrazione, ignora questa email.</p>
|
||||||
<a href='" . SITE_URL . "/user/dashboard.php' class='button'>Vai alla Dashboard</a>
|
<p>A presto!<br>Il team di " . SITE_NAME . "</p>
|
||||||
</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>
|
|
||||||
</div>
|
</div>
|
||||||
<div class='footer'>
|
<div class='footer'>
|
||||||
<p>Questa è una email automatica, per favore non rispondere a questo messaggio.</p>
|
<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();
|
$pdo = get_db_connection();
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
INSERT INTO activity_log (user_id, action, description, ip_address, user_agent, created_at)
|
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([
|
$stmt->execute([
|
||||||
$user_id,
|
$user_id,
|
||||||
@@ -107,11 +119,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$_SERVER['HTTP_USER_AGENT'] ?? null
|
$_SERVER['HTTP_USER_AGENT'] ?? null
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Login automatico dopo registrazione
|
// NON fare login automatico - utente deve verificare email prima
|
||||||
login_user($user_id, false);
|
// Reindirizza a pagina di conferma
|
||||||
|
header("refresh:3;url=login.php");
|
||||||
// Reindirizza dopo 2 secondi
|
|
||||||
header("refresh:2;url=user/dashboard.php");
|
|
||||||
} else {
|
} else {
|
||||||
$error = 'Errore durante la registrazione. Riprova più tardi.';
|
$error = 'Errore durante la registrazione. Riprova più tardi.';
|
||||||
}
|
}
|
||||||
@@ -154,7 +164,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?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="">
|
<form method="POST" action="">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="first_name" class="form-label">Nome</label>
|
<label for="first_name" class="form-label">Nome</label>
|
||||||
|
|||||||
207
resend_verification.php
Normal file
207
resend_verification.php
Normal 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>© <?php echo date('Y'); ?> <?php echo SITE_NAME; ?>. Tutti i diritti riservati.</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
175
send_email.py
Normal file
175
send_email.py
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
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"""
|
||||||
|
config = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(config_path, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Estrai le define con regex
|
||||||
|
patterns = {
|
||||||
|
'SMTP_HOST': r"define\('SMTP_HOST',\s*'([^']+)'\)",
|
||||||
|
'SMTP_PORT': r"define\('SMTP_PORT',\s*(\d+)\)",
|
||||||
|
'SMTP_USERNAME': r"define\('SMTP_USERNAME',\s*'([^']+)'\)",
|
||||||
|
'SMTP_PASSWORD': r"define\('SMTP_PASSWORD',\s*'([^']+)'\)",
|
||||||
|
'SMTP_ENCRYPTION': r"define\('SMTP_ENCRYPTION',\s*'([^']+)'\)",
|
||||||
|
'MAIL_FROM': r"define\('MAIL_FROM',\s*'([^']+)'\)",
|
||||||
|
'MAIL_FROM_NAME': r"define\('MAIL_FROM_NAME',\s*'([^']+)'\)",
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, pattern in patterns.items():
|
||||||
|
match = re.search(pattern, content)
|
||||||
|
if match:
|
||||||
|
value = match.group(1)
|
||||||
|
# Converti porta in intero
|
||||||
|
if key == 'SMTP_PORT':
|
||||||
|
config[key] = int(value)
|
||||||
|
else:
|
||||||
|
config[key] = value
|
||||||
|
|
||||||
|
return config
|
||||||
|
except Exception as e:
|
||||||
|
print(json.dumps({
|
||||||
|
'success': False,
|
||||||
|
'error': f'Errore lettura config.php: {str(e)}'
|
||||||
|
}))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def send_email(to_email, subject, html_body, config):
|
||||||
|
"""Invia email tramite SMTP"""
|
||||||
|
try:
|
||||||
|
# Crea messaggio
|
||||||
|
msg = MIMEMultipart('alternative')
|
||||||
|
msg['From'] = f"{config['MAIL_FROM_NAME']} <{config['MAIL_FROM']}>"
|
||||||
|
msg['To'] = to_email
|
||||||
|
msg['Subject'] = subject
|
||||||
|
|
||||||
|
# Aggiungi corpo HTML
|
||||||
|
html_part = MIMEText(html_body, 'html', 'utf-8')
|
||||||
|
msg.attach(html_part)
|
||||||
|
|
||||||
|
# Connetti al server SMTP
|
||||||
|
if config['SMTP_ENCRYPTION'] == 'ssl':
|
||||||
|
# SSL diretto (porta 465)
|
||||||
|
server = smtplib.SMTP_SSL(config['SMTP_HOST'], config['SMTP_PORT'], timeout=30)
|
||||||
|
else:
|
||||||
|
# TLS con STARTTLS (porta 587)
|
||||||
|
server = smtplib.SMTP(config['SMTP_HOST'], config['SMTP_PORT'], timeout=30)
|
||||||
|
server.ehlo()
|
||||||
|
server.starttls()
|
||||||
|
server.ehlo()
|
||||||
|
|
||||||
|
# Login
|
||||||
|
server.login(config['SMTP_USERNAME'], config['SMTP_PASSWORD'])
|
||||||
|
|
||||||
|
# Invia email
|
||||||
|
server.send_message(msg)
|
||||||
|
server.quit()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'success': True,
|
||||||
|
'message': f'Email inviata con successo a {to_email}'
|
||||||
|
}
|
||||||
|
|
||||||
|
except smtplib.SMTPAuthenticationError as e:
|
||||||
|
error_msg = f'Autenticazione SMTP fallita per {to_email}: {str(e)}'
|
||||||
|
logging.error(error_msg)
|
||||||
|
return {
|
||||||
|
'success': False,
|
||||||
|
'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': 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': error_msg
|
||||||
|
}
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Funzione principale"""
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print(json.dumps({
|
||||||
|
'success': False,
|
||||||
|
'error': 'Uso: python send_email.py <json_data>'
|
||||||
|
}))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Parse input JSON
|
||||||
|
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': error
|
||||||
|
}))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Leggi configurazione
|
||||||
|
script_dir = Path(__file__).parent
|
||||||
|
config_path = script_dir / 'includes' / 'config.php'
|
||||||
|
config = parse_php_config(config_path)
|
||||||
|
|
||||||
|
# Invia email
|
||||||
|
result = send_email(data['to'], data['subject'], data['html'], config)
|
||||||
|
print(json.dumps(result))
|
||||||
|
|
||||||
|
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': error
|
||||||
|
}))
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
error = f'Errore: {str(e)}'
|
||||||
|
logging.error(error)
|
||||||
|
print(json.dumps({
|
||||||
|
'success': False,
|
||||||
|
'error': error
|
||||||
|
}))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
43
test_python.py
Normal file
43
test_python.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test rapido per verificare che Python e le librerie necessarie siano installate
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def test_imports():
|
||||||
|
"""Verifica che tutte le librerie necessarie siano disponibili"""
|
||||||
|
required_modules = {
|
||||||
|
'smtplib': 'Libreria SMTP (built-in)',
|
||||||
|
'email': 'Libreria email (built-in)',
|
||||||
|
'json': 'Libreria JSON (built-in)',
|
||||||
|
're': 'Libreria regex (built-in)',
|
||||||
|
'pathlib': 'Libreria path (built-in)'
|
||||||
|
}
|
||||||
|
|
||||||
|
print("🐍 Test Python per Pilates Platform")
|
||||||
|
print(f" Python version: {sys.version}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
all_ok = True
|
||||||
|
|
||||||
|
for module, description in required_modules.items():
|
||||||
|
try:
|
||||||
|
__import__(module)
|
||||||
|
print(f"✅ {module:12} - {description}")
|
||||||
|
except ImportError:
|
||||||
|
print(f"❌ {module:12} - MANCANTE!")
|
||||||
|
all_ok = False
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
if all_ok:
|
||||||
|
print("✅ Tutte le librerie necessarie sono installate!")
|
||||||
|
print("✅ Python è pronto per inviare email.")
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
print("❌ Alcune librerie sono mancanti. Installa Python 3.6+")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(test_imports())
|
||||||
196
verify_email.php
Normal file
196
verify_email.php
Normal 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>© <?php echo date('Y'); ?> <?php echo SITE_NAME; ?>. Tutti i diritti riservati.</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user