smtp: add notify_email field; fix admin notification sent to no-reply sender

This commit is contained in:
Pontoporeia
2026-04-30 12:19:33 +02:00
parent bdb68479d5
commit 33987c9b15
7 changed files with 81 additions and 42 deletions

11
TODO.md
View File

@@ -63,6 +63,17 @@
- [ ] Verify TCP reachability from XAMXAM VM to LDAP server (port 636) - [ ] Verify TCP reachability from XAMXAM VM to LDAP server (port 636)
- [ ] See `docs/LDAP_AUTH_PLAN.md` for full phase-by-phase plan - [ ] See `docs/LDAP_AUTH_PLAN.md` for full phase-by-phase plan
## SMTP notify_email fix
- [x] Migration 006: add `notify_email` column to `smtp_settings`
- [x] `SmtpRelay::getSettings()` — include `notify_email` in SELECT + defaults
- [x] `SmtpRelay::updateSettings()` — persist `notify_email`
- [x] `SmtpRelay::getNotifyEmail()` — returns `notify_email` ?? `from_email`
- [x] `request-access.php` — use `getNotifyEmail()` instead of `from_email` for admin notifications
- [x] `actions/settings.php` — wire `smtp_notify_email` POST field
- [x] Template: add "Adresse de notification admin" field to SMTP form
- [x] `schema.sql` — updated DDL
## SMTP credential validation ## SMTP credential validation
- [x] Add `SmtpProbeException` with `field` property for structured error classification - [x] Add `SmtpProbeException` with `field` property for structured error classification

View File

@@ -0,0 +1,4 @@
-- Migration 006: add notify_email to smtp_settings
-- notify_email is the address that receives admin notifications (access requests, etc.)
-- It is separate from from_email (the sender/no-reply address).
ALTER TABLE smtp_settings ADD COLUMN notify_email TEXT NOT NULL DEFAULT '';

View File

@@ -40,6 +40,7 @@ if ($section === 'formulaire') {
'username' => $_POST['smtp_username'] ?? '', 'username' => $_POST['smtp_username'] ?? '',
'from_email' => $_POST['smtp_from_email'] ?? '', 'from_email' => $_POST['smtp_from_email'] ?? '',
'from_name' => $_POST['smtp_from_name'] ?? 'XAMXAM', 'from_name' => $_POST['smtp_from_name'] ?? 'XAMXAM',
'notify_email' => $_POST['smtp_notify_email'] ?? '',
]; ];
// Only update password when user actually typed something. // Only update password when user actually typed something.
$pwd = $_POST['smtp_password'] ?? ''; $pwd = $_POST['smtp_password'] ?? '';

View File

@@ -188,9 +188,9 @@ try {
); );
$plain = htmlToPlain($body); $plain = htmlToPlain($body);
$settings = SmtpRelay::getSettings($db); $notifyEmail = SmtpRelay::getNotifyEmail($db);
if (!empty($settings['from_email'])) { if ($notifyEmail !== '') {
SmtpRelay::send($db, $settings['from_email'], $subject, $body, $plain); SmtpRelay::send($db, $notifyEmail, $subject, $body, $plain);
} }
http_response_code(200); http_response_code(200);

View File

@@ -39,7 +39,7 @@ class SmtpRelay {
*/ */
public static function getSettings(Database $db): array { public static function getSettings(Database $db): array {
$stmt = $db->getPDO()->query( $stmt = $db->getPDO()->query(
"SELECT host, port, encryption, username, password, from_email, from_name "SELECT host, port, encryption, username, password, from_email, from_name, notify_email
FROM v_smtp_active LIMIT 1" FROM v_smtp_active LIMIT 1"
); );
$row = $stmt->fetch(); $row = $stmt->fetch();
@@ -52,9 +52,21 @@ class SmtpRelay {
'password' => '', 'password' => '',
'from_email' => '', 'from_email' => '',
'from_name' => 'XAMXAM', 'from_name' => 'XAMXAM',
'notify_email' => '',
]; ];
} }
/**
* Return the address that should receive admin notification emails.
* Uses notify_email when set, falls back to from_email.
*/
public static function getNotifyEmail(Database $db): string
{
$s = self::getSettings($db);
$notify = trim($s['notify_email'] ?? '');
return $notify !== '' ? $notify : trim($s['from_email'] ?? '');
}
/** /**
* Upsert SMTP settings. * Upsert SMTP settings.
* *
@@ -78,6 +90,7 @@ class SmtpRelay {
password = :password, password = :password,
from_email = :from_email, from_email = :from_email,
from_name = :from_name, from_name = :from_name,
notify_email = :notify_email,
updated_at = CURRENT_TIMESTAMP updated_at = CURRENT_TIMESTAMP
WHERE id = 1" WHERE id = 1"
); );
@@ -90,6 +103,7 @@ class SmtpRelay {
':password' => $merged['password'], ':password' => $merged['password'],
':from_email' => trim($merged['from_email']), ':from_email' => trim($merged['from_email']),
':from_name' => trim($merged['from_name']), ':from_name' => trim($merged['from_name']),
':notify_email' => trim($merged['notify_email'] ?? ''),
]); ]);
} }

View File

@@ -360,6 +360,7 @@ CREATE TABLE IF NOT EXISTS smtp_settings (
password TEXT NOT NULL DEFAULT '', -- stored in clear for now; encrypt later password TEXT NOT NULL DEFAULT '', -- stored in clear for now; encrypt later
from_email TEXT NOT NULL DEFAULT '', from_email TEXT NOT NULL DEFAULT '',
from_name TEXT NOT NULL DEFAULT 'XAMXAM', from_name TEXT NOT NULL DEFAULT 'XAMXAM',
notify_email TEXT NOT NULL DEFAULT '', -- recipient for admin notifications
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
); );

View File

@@ -265,16 +265,24 @@
<legend>Expéditeur par défaut</legend> <legend>Expéditeur par défaut</legend>
<div class="param-grid"> <div class="param-grid">
<div> <div>
<label for="smtp_from_email">Adresse e-mail</label> <label for="smtp_from_email">Adresse e-mail d'expédition</label>
<input type="email" id="smtp_from_email" name="smtp_from_email" <input type="email" id="smtp_from_email" name="smtp_from_email"
value="<?= htmlspecialchars($smtpSettings['from_email']) ?>" value="<?= htmlspecialchars($smtpSettings['from_email']) ?>"
placeholder="noreply@example.com"> placeholder="noreply@example.com">
<small>Adresse utilisée comme expéditeur (champ From:).</small>
</div> </div>
<div> <div>
<label for="smtp_from_name">Nom d'expéditeur</label> <label for="smtp_from_name">Nom d'expéditeur</label>
<input type="text" id="smtp_from_name" name="smtp_from_name" <input type="text" id="smtp_from_name" name="smtp_from_name"
value="<?= htmlspecialchars($smtpSettings['from_name']) ?>"> value="<?= htmlspecialchars($smtpSettings['from_name']) ?>">
</div> </div>
<div>
<label for="smtp_notify_email">Adresse de notification admin</label>
<input type="email" id="smtp_notify_email" name="smtp_notify_email"
value="<?= htmlspecialchars($smtpSettings['notify_email'] ?? '') ?>"
placeholder="admin@example.com">
<small>Reçoit les notifications (demandes daccès, etc.). Si vide, utilise ladresse dexpédition.</small>
</div>
</div> </div>
</fieldset> </fieldset>