diff --git a/.gitignore b/.gitignore index 753f0ff..529f3e2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ compose.lock ### Test databases ### app/storage/test.db *.db +app/.env ### Logs ### error.log diff --git a/TODO.md b/TODO.md index fbfbfc3..fc35e1e 100644 --- a/TODO.md +++ b/TODO.md @@ -57,17 +57,3 @@ - [x] All `$required = true` callers in `form.php`, `fieldset-tfe-info.php`, `fieldset-academic.php`, `fieldset-licence-explanation.php`, `fieldset-files.php` changed to `!$adminMode` - [x] Hardcoded `required` HTML attributes in `fieldset-tfe-info.php` (synopsis, objet radios), `fieldset-licence-explanation.php` (access type radios), `jury-fieldset.php` (promoteur, lecteurs interne/externe) gated on `!$adminMode` - [x] Dynamic JS `ulbInput.required` in jury fieldset also gated - - [x] Remove server-side validation for orientation, ap, finality, licence, jury roles in `ThesisEditController::save()` — admins can save partial records - - [x] Same for `ThesisCreateController::submit()`: added `$adminMode` param, pass `true` from `admin/actions/formulaire.php` - -- [x] Encrypt SMTP password at rest (AES-256-GCM) - - [x] `app/.env` — holds `APP_KEY` (base64, 32 bytes); added to `.gitignore` - - [x] `src/Crypto.php` — `encrypt()` / `decrypt()` / `isEncrypted()` via OpenSSL AES-256-GCM - - [x] `SmtpRelay::getSettings()` — decrypts password after DB fetch - - [x] `SmtpRelay::updateSettings()` — encrypts password before DB write - - [x] `parametres.php` template — password field no longer pre-filled (ciphertext never sent to browser) - - [x] Migration `018_encrypt_smtp_password.php` — encrypted existing plaintext in DB; moved to applied/ - - [x] `justfile` — `deploy` calls `deploy-env` (uploads `.env` only if remote doesn't exist yet) - - [x] `justfile` — `deploy-env` recipe: safe upload with guards - - [x] `justfile` — `reencrypt-password` recipe: rotates APP_KEY on remote DB - - [x] `scripts/reencrypt-smtp-password.php` — decrypts with old key, re-encrypts with new key, updates `.env` diff --git a/app/migrations/applied/018_encrypt_smtp_password.php b/app/migrations/applied/018_encrypt_smtp_password.php new file mode 100644 index 0000000..e4fc4d1 --- /dev/null +++ b/app/migrations/applied/018_encrypt_smtp_password.php @@ -0,0 +1,48 @@ +#!/usr/bin/env php +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$row = $pdo->query("SELECT password FROM smtp_settings WHERE id = 1")->fetch(PDO::FETCH_ASSOC); + +if (!$row) { + echo "No smtp_settings row found — nothing to do.\n"; + exit(0); +} + +$current = $row['password']; + +if (Crypto::isEncrypted($current)) { + echo "Password already encrypted — nothing to do.\n"; + exit(0); +} + +if ($current === '') { + echo "Password is empty — nothing to do.\n"; + exit(0); +} + +$encrypted = Crypto::encrypt($current); +$pdo->prepare("UPDATE smtp_settings SET password = ? WHERE id = 1")->execute([$encrypted]); + +echo "SMTP password encrypted successfully.\n"; diff --git a/app/src/Crypto.php b/app/src/Crypto.php new file mode 100644 index 0000000..71e24f1 --- /dev/null +++ b/app/src/Crypto.php @@ -0,0 +1,127 @@ += self::IV_LEN + self::TAG_LEN + 1; + } +} diff --git a/app/src/SmtpRelay.php b/app/src/SmtpRelay.php index f51d04d..cb34de2 100644 --- a/app/src/SmtpRelay.php +++ b/app/src/SmtpRelay.php @@ -72,6 +72,11 @@ class SmtpRelay ); $row = $stmt->fetch(); + if ($row) { + require_once __DIR__ . '/Crypto.php'; + $row['password'] = Crypto::decrypt($row['password']); + } + return $row ?: [ 'host' => '', 'port' => 587, @@ -124,12 +129,13 @@ class SmtpRelay WHERE id = 1' ); + require_once __DIR__ . '/Crypto.php'; $stmt->execute([ ':host' => trim($merged['host']), ':port' => $port, ':encryption' => $encryption, ':username' => trim($merged['username']), - ':password' => $merged['password'], + ':password' => Crypto::encrypt($merged['password']), ':from_email' => trim($merged['from_email']), ':from_name' => trim($merged['from_name']), ':notify_email' => trim($merged['notify_email'] ?? ''), diff --git a/app/templates/admin/parametres.php b/app/templates/admin/parametres.php index 12e2b7f..97bb43c 100644 --- a/app/templates/admin/parametres.php +++ b/app/templates/admin/parametres.php @@ -254,7 +254,7 @@