admin parametres: add shared Identifiants section, trim Emails, restructure PeerTube fieldsets

- admin parametres: move Compte administrateur into Identifiants as a fieldset
- admin parametres: space the account fieldset and drop confirm-password top border
- admin parametres: tighten param-form row spacing, relabel password button
- admin parametres: move password submit button outside the account fieldset
This commit is contained in:
Pontoporeia
2026-08-24 11:35:22 +02:00
parent fb5e856288
commit 138b59f66c
3 changed files with 196 additions and 150 deletions
+25
View File
@@ -1353,6 +1353,22 @@ th.admin-ap-col {
gap: var(--space-m);
}
.param-form > .param-form-actions {
display: flex;
align-items: center;
gap: var(--space-s);
}
/* Spacing between the two fieldsets in the Identifiants section */
.param-account-fieldset {
margin-top: var(--space-l);
}
/* Remove the top border on the confirm-password row (it follows the new-password row) */
.param-form > .param-form-row--flush {
border-top: none;
}
.param-form fieldset {
display: flex;
flex-direction: column;
@@ -1430,11 +1446,16 @@ th.admin-ap-col {
gap: var(--space-3xs);
border-top: 1px solid var(--border-primary);
padding: var(--space-xs) 0;
display: grid;
grid-template-columns: 1fr;
gap: var(--space-3xs);
border-top: 1px solid var(--border-primary);
}
.param-form > div:first-of-type {
border-top: none;
padding-top: 0;
border-top: none;
}
.param-form input[type="password"] {
@@ -1526,6 +1547,10 @@ th.admin-ap-col {
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: var(--space-s);
}
.param-grid > .param-checkbox,
.param-grid > .param-note {
grid-column: 1 / -1;
}
.param-grid label {
display: flex;
flex-direction: column;
+169 -150
View File
@@ -77,6 +77,146 @@
</form>
</section>
<!-- ══════════════════════════════════════════════════════════════
IDENTIFIANTS (common credentials)
══════════════════════════════════════════════════════════════ -->
<?php
// Inline helpers: emit aria-invalid + error <small> when this field is the culprit.
// Shared by the Identifiants and Emails (SMTP) sections below.
$smtpFieldErr = function(string $id) use ($smtpErrorField): string {
return $smtpErrorField === $id ? ' aria-invalid="true"' : '';
};
$smtpFieldMsg = function(string $id, string $msg) use ($smtpErrorField): string {
return $smtpErrorField === $id
? '<small class="param-field-error" id="' . $id . '-error">' . htmlspecialchars($msg) . '</small>'
: '';
};
// Human-readable hints per field (brief — the full message is in the toast)
$smtpHints = [
'smtp_host' => 'Vérifiez l’adresse du serveur SMTP.',
'smtp_port' => 'Vérifiez le numéro de port.',
'smtp_encryption' => 'Vérifiez le mode de chiffrement.',
'smtp_username' => 'Vérifiez le nom d’utilisateur.',
'smtp_password' => 'Mot de passe incorrect.',
];
?>
<section aria-labelledby="settings-identifiants-title">
<h2 id="settings-identifiants-title">Identifiants</h2>
<p>
Identifiants communs partagés par le relay SMTP, la connexion
PeerTube et l'instance Nextcloud utilisés par le script de sauvegarde.
</p>
<form method="post" action="actions/settings.php" class="param-form"
<?= $smtpErrorField ? 'data-smtp-error-field="' . htmlspecialchars($smtpErrorField) . '"' : '' ?>>
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="section" value="smtp">
<fieldset class="param-grid">
<legend>Identifiants communs</legend>
<div>
<label for="smtp_username">Adresse e-mail</label>
<input type="email" id="smtp_username" name="smtp_username"
value="<?= htmlspecialchars($smtpSettings['username']) ?>"
placeholder="xamxam@erg.be"
<?= $smtpFieldErr('smtp_username') ?>
<?= $smtpErrorField === 'smtp_username' ? 'aria-describedby="smtp_username-error"' : '' ?>>
<small>Utilisée pour l'authentification SMTP, PeerTube et Nextcloud.</small>
<?= $smtpFieldMsg('smtp_username', $smtpHints['smtp_username']) ?>
</div>
<div>
<label for="smtp_password">Mot de passe</label>
<input type="password" id="smtp_password" name="smtp_password"
value=""
autocomplete="new-password"
placeholder="Laissez vide pour ne pas modifier"
<?= $smtpFieldErr('smtp_password') ?>
<?= $smtpErrorField === 'smtp_password' ? 'aria-describedby="smtp_password-error"' : '' ?>>
<?= $smtpFieldMsg('smtp_password', $smtpHints['smtp_password']) ?>
</div>
</fieldset>
<button type="submit" class="btn btn--primary">Enregistrer</button>
</form>
<fieldset class="param-account-fieldset">
<legend>Compte administrateur</legend>
<dl class="param-account-status">
<div>
<dt>Authentification PHP</dt>
<dd><?php $badgeType = 'ok'; $badgeValue = $hasPassword; $badgeOkLabel = 'Active'; $badgeWarnLabel = 'Non configurée'; include APP_ROOT . '/templates/partials/status-badge.php'; ?></dd>
</div>
<div>
<dt>Stockage du hash</dt>
<dd>
<code>site_settings (DB)</code>
<?php $badgeType = 'ok'; $badgeValue = $hasPassword; $badgeOkLabel = 'Présent'; $badgeWarnLabel = 'Absent'; include APP_ROOT . '/templates/partials/status-badge.php'; ?>
</dd>
</div>
</dl>
<?php if (!$hasPassword): ?>
<p class="param-note">
Aucun mot de passe PHP configuré. Le formulaire ci-dessous stockera
un hash bcrypt dans la base de données.
</p>
<?php endif; ?>
<form method="post" action="/admin/actions/account.php" class="param-form" autocomplete="off" id="account-password-form">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="redirect" value="/admin/parametres.php">
<?php if ($hasPassword): ?>
<div>
<label for="current_password">Mot de passe actuel</label>
<input type="password" id="current_password"
name="current_password" required autocomplete="current-password">
</div>
<?php endif; ?>
<div>
<label for="new_password">Nouveau mot de passe</label>
<input type="password" id="new_password"
name="new_password" required autocomplete="new-password"
minlength="12">
<small>Minimum 12 caractères.</small>
</div>
<div class="param-form-row--flush">
<label for="confirm_password">Confirmer le mot de passe</label>
<input type="password" id="confirm_password"
name="confirm_password" required autocomplete="new-password">
</div>
</form>
<!-- Danger zone: remove credentials -->
<?php if ($hasPassword): ?>
<fieldset class="param-danger-zone">
<legend>Supprimer la configuration du mot de passe</legend>
<p>
Supprime le hash de la base de données. L'accès admin
ne sera plus protégé (mode développement).
</p>
<?php /* TODO: replace this browser confirm() with a proper <dialog> modal like the other confirmations */ ?>
<form method="post" action="/admin/actions/account.php"
onsubmit="return confirm('Supprimer le mot de passe ? L\'accès admin ne sera plus protégé.')">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="action" value="remove_credentials">
<input type="hidden" name="redirect" value="/admin/parametres.php">
<input type="hidden" name="current_password_remove" value="">
<button type="submit" class="btn btn--danger">Supprimer le mot de passe</button>
</form>
</fieldset>
<?php endif; ?>
</fieldset>
<button type="submit" class="btn btn--primary" form="account-password-form">
Mettre à jour le mot de passe
</button>
</section>
<!-- ══════════════════════════════════════════════════════════════
RELAY SMTP
══════════════════════════════════════════════════════════════ -->
@@ -95,25 +235,6 @@
<?php endif; ?>
</div>
<?php
// Inline helper: emit aria-invalid + error <small> when this field is the culprit
$smtpFieldErr = function(string $id) use ($smtpErrorField): string {
return $smtpErrorField === $id ? ' aria-invalid="true"' : '';
};
$smtpFieldMsg = function(string $id, string $msg) use ($smtpErrorField): string {
return $smtpErrorField === $id
? '<small class="param-field-error" id="' . $id . '-error">' . htmlspecialchars($msg) . '</small>'
: '';
};
// Human-readable hints per field (brief — the full message is in the toast)
$smtpHints = [
'smtp_host' => 'Vérifiez l’adresse du serveur SMTP.',
'smtp_port' => 'Vérifiez le numéro de port.',
'smtp_encryption' => 'Vérifiez le mode de chiffrement.',
'smtp_username' => 'Vérifiez le nom d’utilisateur.',
'smtp_password' => 'Mot de passe incorrect.',
];
?>
<form method="post" action="actions/settings.php" class="param-form"
<?= $smtpErrorField ? 'data-smtp-error-field="' . htmlspecialchars($smtpErrorField) . '"' : '' ?>>
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
@@ -154,28 +275,6 @@
<?= $smtpFieldMsg('smtp_encryption', $smtpHints['smtp_encryption']) ?>
</div>
<div>
<label for="smtp_username">Adresse e-mail</label>
<input type="email" id="smtp_username" name="smtp_username"
value="<?= htmlspecialchars($smtpSettings['username']) ?>"
placeholder="xamxam@erg.be"
<?= $smtpFieldErr('smtp_username') ?>
<?= $smtpErrorField === 'smtp_username' ? 'aria-describedby="smtp_username-error"' : '' ?>>
<small>Adresse utilisée pour l'authentification SMTP et comme expéditeur.</small>
<?= $smtpFieldMsg('smtp_username', $smtpHints['smtp_username']) ?>
</div>
<div>
<label for="smtp_password">Mot de passe</label>
<input type="password" id="smtp_password" name="smtp_password"
value=""
autocomplete="new-password"
placeholder="Laissez vide pour ne pas modifier"
<?= $smtpFieldErr('smtp_password') ?>
<?= $smtpErrorField === 'smtp_password' ? 'aria-describedby="smtp_password-error"' : '' ?>>
<?= $smtpFieldMsg('smtp_password', $smtpHints['smtp_password']) ?>
</div>
<div>
<label for="smtp_from_name">Nom d'expéditeur</label>
<input type="text" id="smtp_from_name" name="smtp_from_name"
@@ -195,25 +294,27 @@
</form>
<!-- Test d'envoi -->
<fieldset class="param-smtp-test">
<legend>Tester l'envoi d'un e-mail</legend>
<p>Envoie un e-mail de test via le relay SMTP configuré ci-dessus.</p>
<?php if (!$smtpConfigured): ?>
<p class="param-note">⚠ Configurez le relay SMTP avant de pouvoir tester l'envoi.</p>
<?php else: ?>
<form method="post" action="actions/smtp-test.php" class="param-form">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<form method="post" action="actions/smtp-test.php" class="param-form param-smtp-test">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<fieldset>
<legend>Tester l'envoi d'un e-mail</legend>
<p>Envoie un e-mail de test via le relay SMTP configuré ci-dessus.</p>
<?php if (!$smtpConfigured): ?>
<p class="param-note">⚠ Configurez le relay SMTP avant de pouvoir tester l'envoi.</p>
<?php else: ?>
<div class="param-smtp-test-row">
<div>
<label for="smtp_test_email">Adresse de destination</label>
<input type="email" id="smtp_test_email" name="test_email"
placeholder="test@example.com" required>
</div>
<button type="submit" class="btn btn--primary">Envoyer le test</button>
</div>
</form>
<?php endif; ?>
</fieldset>
<?php if ($smtpConfigured): ?>
<button type="submit" class="btn btn--primary">Envoyer le test</button>
<?php endif; ?>
</fieldset>
</form>
</section>
<!-- ══════════════════════════════════════════════════════════════
@@ -239,8 +340,8 @@
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="section" value="peertube">
<fieldset>
<legend>Activation</legend>
<fieldset class="param-grid">
<legend>Paramètres Peertube</legend>
<label class="param-checkbox">
<input type="checkbox" name="peertube_upload_enabled" value="1"
<?= $peerTubeEnabled ? 'checked' : '' ?>>
@@ -250,15 +351,10 @@
sur l'instance PeerTube plutôt que stockés localement sur le serveur.</small>
</span>
</label>
</fieldset>
<fieldset class="param-grid">
<legend>Paramètres Peertube</legend>
<p class="param-note">
ℹ L'authentification PeerTube utilise les mêmes identifiants que le
<strong>relay SMTP</strong> configuré ci-dessus.
</p>
<p class="param-note">
ℹ L'authentification PeerTube utilise les identifiants communs configurés ci-dessus.
</p>
<div>
<label for="peertube_instance_url">URL de l'instance PeerTube</label>
@@ -286,98 +382,21 @@
</div>
</fieldset>
<button type="submit" class="btn btn--primary">Enregistrer</button>
<button type="button" class="btn btn--secondary" id="peertube-test-btn"
hx-post="/admin/actions/peertube-test.php"
hx-target="#peertube-test-result"
hx-include="closest form"
hx-indicator="#peertube-test-spinner">
Tester la connexion
</button>
<span id="peertube-test-spinner" class="htmx-indicator" style="display:none;margin-left:var(--space-xs);">⏳</span>
<div class="param-form-actions">
<button type="submit" class="btn btn--primary">Enregistrer</button>
<button type="button" class="btn btn--secondary" id="peertube-test-btn"
hx-post="/admin/actions/peertube-test.php"
hx-target="#peertube-test-result"
hx-include="closest form"
hx-indicator="#peertube-test-spinner">
Tester la connexion
</button>
<span id="peertube-test-spinner" class="htmx-indicator" style="display:none;">⏳</span>
</div>
<div id="peertube-test-result" style="margin-top:var(--space-xs);"></div>
</form>
</section>
<!-- ══════════════════════════════════════════════════════════════
COMPTE ADMINISTRATEUR
══════════════════════════════════════════════════════════════ -->
<section aria-labelledby="settings-account-title">
<h2 id="settings-account-title">Compte administrateur</h2>
<dl class="param-account-status">
<div>
<dt>Authentification PHP</dt>
<dd><?php $badgeType = 'ok'; $badgeValue = $hasPassword; $badgeOkLabel = 'Active'; $badgeWarnLabel = 'Non configurée'; include APP_ROOT . '/templates/partials/status-badge.php'; ?></dd>
</div>
<div>
<dt>Stockage du hash</dt>
<dd>
<code>site_settings (DB)</code>
<?php $badgeType = 'ok'; $badgeValue = $hasPassword; $badgeOkLabel = 'Présent'; $badgeWarnLabel = 'Absent'; include APP_ROOT . '/templates/partials/status-badge.php'; ?>
</dd>
</div>
</dl>
<?php if (!$hasPassword): ?>
<p class="param-note">
Aucun mot de passe PHP configuré. Le formulaire ci-dessous stockera
un hash bcrypt dans la base de données.
</p>
<?php endif; ?>
<form method="post" action="/admin/actions/account.php" class="param-form" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="redirect" value="/admin/parametres.php">
<?php if ($hasPassword): ?>
<div>
<label for="current_password">Mot de passe actuel</label>
<input type="password" id="current_password"
name="current_password" required autocomplete="current-password">
</div>
<?php endif; ?>
<div>
<label for="new_password">Nouveau mot de passe</label>
<input type="password" id="new_password"
name="new_password" required autocomplete="new-password"
minlength="12">
<small>Minimum 12 caractères.</small>
</div>
<div>
<label for="confirm_password">Confirmer le mot de passe</label>
<input type="password" id="confirm_password"
name="confirm_password" required autocomplete="new-password">
</div>
<button type="submit" class="btn btn--primary">
<?= $hasPassword ? 'Mettre à jour le mot de passe' : 'Définir le mot de passe' ?>
</button>
</form>
<!-- Danger zone: remove credentials -->
<?php if ($hasPassword): ?>
<fieldset class="param-danger-zone">
<legend>Supprimer la configuration du mot de passe</legend>
<p>
Supprime le hash de la base de données. L'accès admin
ne sera plus protégé (mode développement).
</p>
<?php /* TODO: replace this browser confirm() with a proper <dialog> modal like the other confirmations */ ?>
<form method="post" action="/admin/actions/account.php"
onsubmit="return confirm('Supprimer le mot de passe ? L\'accès admin ne sera plus protégé.')">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="action" value="remove_credentials">
<input type="hidden" name="redirect" value="/admin/parametres.php">
<input type="hidden" name="current_password_remove" value="">
<button type="submit" class="btn btn--danger">Supprimer le mot de passe</button>
</form>
</fieldset>
<?php endif; ?>
</section>
<!-- ══════════════════════════════════════════════════════════════
SYSTÈME
══════════════════════════════════════════════════════════════ -->