This commit is contained in:
Joris Bertomeu
2025-08-19 16:34:19 +02:00
commit 5c6da90f98
33 changed files with 8066 additions and 0 deletions

148
views/dashboard.ejs Normal file
View File

@@ -0,0 +1,148 @@
<div class="container-fluid">
<h1 class="h3 mb-4">Tableau de bord</h1>
<div class="row">
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
Emails totaux</div>
<div class="h5 mb-0 font-weight-bold text-gray-800" id="total-count"><%= totalCount %></div>
</div>
<div class="col-auto">
<i class="fas fa-envelope fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-warning shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">
Emails non lus</div>
<div class="h5 mb-0 font-weight-bold text-gray-800" id="unread-count"><%= unreadCount %></div>
</div>
<div class="col-auto">
<i class="fas fa-envelope-open fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Derniers emails reçus</h6>
<a href="/emails" class="btn btn-sm btn-primary">Voir tous les emails</a>
</div>
<div class="card-body">
<% if(latestEmails && latestEmails.length > 0) { %>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">De</th>
<th scope="col">Sujet</th>
<th scope="col">Statut</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody id="latest-emails">
<% latestEmails.forEach(email => { %>
<tr>
<td><%= new Date(email.receivedAt).toLocaleString() %></td>
<td><%= email.from %></td>
<td><%= email.subject %></td>
<td>
<% if(email.read) { %>
<span class="badge bg-success">Lu</span>
<% } else { %>
<span class="badge bg-warning">Non lu</span>
<% } %>
</td>
<td>
<a href="/emails/<%= email.id %>" class="btn btn-sm btn-info">
<i class="fas fa-eye"></i>
</a>
</td>
</tr>
<% }); %>
</tbody>
</table>
</div>
<% } else { %>
<div class="text-center py-4">
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
<p>Aucun email reçu pour le moment.</p>
</div>
<% } %>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Statut du serveur</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Serveur SMTP :</strong> <span class="text-success">Actif sur <%= settings.smtp?.host || '0.0.0.0' %>:<%= settings.smtp?.port || '2525' %></span></p>
<p><strong>Mode TLS :</strong>
<% if(settings.smtp?.secure) { %>
<span class="text-success">Activé</span>
<% } else { %>
<span class="text-warning">Désactivé</span>
<% } %>
</p>
</div>
<div class="col-md-6">
<p><strong>Notifications Pushover :</strong>
<% if(settings.pushover?.user && settings.pushover?.token) { %>
<span class="text-success">Configurées</span>
<% } else { %>
<span class="text-danger">Non configurées</span>
<% } %>
</p>
<p><strong>Priorité des notifications :</strong>
<%
let priorityText = "Normale";
let priorityClass = "text-info";
if(settings.pushover?.priority === -2) {
priorityText = "Très basse";
priorityClass = "text-muted";
} else if(settings.pushover?.priority === -1) {
priorityText = "Basse";
priorityClass = "text-secondary";
} else if(settings.pushover?.priority === 1) {
priorityText = "Haute";
priorityClass = "text-warning";
} else if(settings.pushover?.priority === 2) {
priorityText = "Urgente";
priorityClass = "text-danger";
}
%>
<span class="<%= priorityClass %>"><%= priorityText %></span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

83
views/email-detail.ejs Normal file
View File

@@ -0,0 +1,83 @@
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<a href="/emails" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left"></i> Retour
</a>
</div>
<div>
<form action="/emails/<%= email.id %>?_method=DELETE" method="POST" class="d-inline" onsubmit="return confirm('Êtes-vous sûr de vouloir supprimer cet email?');">
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash"></i> Supprimer
</button>
</form>
</div>
</div>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary"><%= email.subject %></h6>
</div>
<div class="card-body">
<div class="mb-4">
<div class="row">
<div class="col-md-6">
<p><strong>De:</strong> <%= email.from %></p>
</div>
<div class="col-md-6 text-md-end">
<p><strong>Reçu le:</strong> <%= new Date(email.receivedAt).toLocaleString() %></p>
</div>
</div>
<p><strong>À:</strong> <%= email.to %></p>
<% if(email.attachments && email.attachments > 0) { %>
<p><strong>Pièces jointes:</strong> <%= email.attachments %></p>
<% } %>
</div>
<hr>
<% if(email.html) { %>
<div class="email-content-html mb-3">
<iframe srcdoc="<%= email.html %>" style="width: 100%; height: 500px; border: 1px solid #ddd; border-radius: 0.25rem;"></iframe>
</div>
<div class="accordion">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseText">
Voir en texte brut
</button>
</h2>
<div id="collapseText" class="accordion-collapse collapse">
<div class="accordion-body">
<pre class="text-content" style="white-space: pre-wrap;"><%= email.text %></pre>
</div>
</div>
</div>
</div>
<% } else { %>
<pre class="text-content" style="white-space: pre-wrap;"><%= email.text %></pre>
<% } %>
</div>
</div>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Informations techniques</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>ID:</strong> <%= email.id %></p>
<p><strong>Taille:</strong> <%= email.text ? email.text.length : 0 %> caractères (texte brut)</p>
</div>
<div class="col-md-6">
<p><strong>Format HTML:</strong> <%= email.html ? 'Oui' : 'Non' %></p>
<p><strong>Statut:</strong> <%= email.read ? 'Lu' : 'Non lu' %></p>
</div>
</div>
</div>
</div>
</div>

78
views/emails.ejs Normal file
View File

@@ -0,0 +1,78 @@
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3">Emails reçus</h1>
<div class="btn-group">
<a href="/emails" class="btn btn-outline-primary <%= !filter ? 'active' : '' %>">Tous</a>
<a href="/emails?read=false" class="btn btn-outline-primary <%= filter === 'false' ? 'active' : '' %>">Non lus</a>
<a href="/emails?read=true" class="btn btn-outline-primary <%= filter === 'true' ? 'active' : '' %>">Lus</a>
</div>
</div>
<div class="card shadow">
<div class="card-body">
<% if(emails && emails.length > 0) { %>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">De</th>
<th scope="col">Sujet</th>
<th scope="col">Statut</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<% emails.forEach(email => { %>
<tr class="<%= !email.read ? 'table-warning' : '' %>">
<td>
<span class="timestamp" data-timestamp="<%= email.receivedAt %>">
<%= new Date(email.receivedAt).toLocaleString() %>
</span>
</td>
<td><%= email.from %></td>
<td><%= email.subject %></td>
<td>
<% if(email.read) { %>
<span class="badge bg-success">Lu</span>
<% } else { %>
<span class="badge bg-warning">Non lu</span>
<% } %>
</td>
<td>
<div class="btn-group">
<a href="/emails/<%= email.id %>" class="btn btn-sm btn-info">
<i class="fas fa-eye"></i>
</a>
<form action="/emails/<%= email.id %>?_method=DELETE" method="POST" onsubmit="return confirm('Êtes-vous sûr de vouloir supprimer cet email?');" class="d-inline">
<button type="submit" class="btn btn-sm btn-danger">
<i class="fas fa-trash"></i>
</button>
</form>
</div>
</td>
</tr>
<% }); %>
</tbody>
</table>
</div>
<% } else { %>
<div class="text-center py-5">
<i class="fas fa-inbox fa-4x text-muted mb-3"></i>
<h5>Aucun email trouvé</h5>
<p class="text-muted">
<% if (filter === 'true') { %>
Il n'y a pas d'emails lus.
<% } else if (filter === 'false') { %>
Il n'y a pas d'emails non lus.
<% } else { %>
Les emails reçus apparaîtront ici.
<% } %>
</p>
</div>
<% } %>
</div>
</div>
</div>

22
views/error.ejs Normal file
View File

@@ -0,0 +1,22 @@
<%- include('layouts/main', { title: 'Erreur' }) %>
<div class="container-fluid">
<div class="text-center mt-5">
<div class="error mx-auto" data-text="Error">
<i class="fas fa-exclamation-triangle fa-3x text-danger mb-3"></i>
</div>
<h3 class="text-danger">Une erreur est survenue</h3>
<p class="lead text-gray-800 mb-4"><%= message %></p>
<% if (process.env.NODE_ENV !== 'production' && error) { %>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Détails de l'erreur</h6>
</div>
<div class="card-body">
<pre class="text-danger"><%= error.stack || error.message || error %></pre>
</div>
</div>
<% } %>
<a href="/">&larr; Retour à l'accueil</a>
</div>
</div>

16
views/index.ejs Normal file
View File

@@ -0,0 +1,16 @@
<!-- Page d'accueil - redirige vers le tableau de bord -->
<%- include('layouts/main', { title: 'Accueil' }) %>
<script>
window.location.href = "/dashboard";
</script>
<div class="container-fluid">
<div class="text-center mt-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Redirection...</span>
</div>
<p class="mt-3">Redirection vers le tableau de bord...</p>
<p>Si vous n'êtes pas redirigé automatiquement, <a href="/dashboard">cliquez ici</a>.</p>
</div>
</div>

97
views/layouts/main.ejs Normal file
View File

@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mail Notifier - <%= typeof title !== 'undefined' ? title : 'Serveur de mail avec notifications' %></title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Custom CSS -->
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="container-fluid">
<div class="row">
<% if (typeof hideNavbar === 'undefined' || !hideNavbar) { %>
<!-- Sidebar -->
<div class="col-md-3 col-lg-2 px-0 bg-dark position-fixed" style="min-height:100vh">
<div class="d-flex flex-column p-3 text-white bg-dark" style="height:100%">
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-white text-decoration-none">
<i class="fas fa-envelope me-2"></i>
<span class="fs-4">Mail Notifier</span>
</a>
<hr>
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a href="/" class="nav-link text-white <%= (typeof activePage !== 'undefined' && activePage === 'dashboard') ? 'active' : '' %>">
<i class="fas fa-tachometer-alt me-2"></i>
Tableau de bord
</a>
</li>
<li>
<a href="/emails" class="nav-link text-white <%= (typeof activePage !== 'undefined' && activePage === 'emails') ? 'active' : '' %>">
<i class="fas fa-envelope-open-text me-2"></i>
Emails reçus
</a>
</li>
<li>
<a href="/settings" class="nav-link text-white <%= (typeof activePage !== 'undefined' && activePage === 'settings') ? 'active' : '' %>">
<i class="fas fa-cog me-2"></i>
Paramètres
</a>
</li>
</ul>
<hr>
<div>
<a href="/logout" class="nav-link text-white">
<i class="fas fa-sign-out-alt me-2"></i>
Déconnexion
</a>
</div>
</div>
</div>
<!-- Main content -->
<div class="col-md-9 col-lg-10 ms-auto p-4">
<% } else { %>
<!-- Full width content (for login page) -->
<div class="col-12 p-0">
<% } %>
<!-- Flash messages -->
<% if(typeof success_msg !== 'undefined' && success_msg.length > 0) { %>
<div class="alert alert-success alert-dismissible fade show">
<%= success_msg %>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<% } %>
<% if(typeof error_msg !== 'undefined' && error_msg.length > 0) { %>
<div class="alert alert-danger alert-dismissible fade show">
<%= error_msg %>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<% } %>
<% if(typeof error !== 'undefined' && error.length > 0) { %>
<div class="alert alert-danger alert-dismissible fade show">
<%= error %>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<% } %>
<!-- Content -->
<%- typeof body !== 'undefined' ? body : '' %>
</div>
</div>
</div>
<!-- Bootstrap JS Bundle -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<!-- Custom JS -->
<script src="/js/main.js"></script>
</body>
</html>

27
views/login.ejs Normal file
View File

@@ -0,0 +1,27 @@
<%- include('layouts/main', { hideNavbar: true, title: 'Connexion' }) %>
<div class="min-vh-100 d-flex align-items-center justify-content-center bg-light">
<div class="card shadow-sm" style="width: 400px;">
<div class="card-body p-4">
<div class="text-center mb-4">
<i class="fas fa-envelope fa-3x text-primary mb-3"></i>
<h3>Mail Notifier</h3>
<p class="text-muted">Connexion à l'interface d'administration</p>
</div>
<form action="/login" method="POST">
<div class="mb-3">
<label for="username" class="form-label">Nom d'utilisateur</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Mot de passe</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary">Se connecter</button>
</div>
</form>
</div>
</div>
</div>

13
views/not-found.ejs Normal file
View File

@@ -0,0 +1,13 @@
<%- include('layouts/main', { title: 'Page non trouvée' }) %>
<div class="container-fluid">
<div class="text-center mt-5">
<div class="error mx-auto" data-text="404">
<i class="fas fa-search fa-3x text-warning mb-3"></i>
</div>
<h3 class="text-warning">Page non trouvée</h3>
<p class="lead text-gray-800 mb-5">La page que vous recherchez n'existe pas</p>
<p class="text-gray-500 mb-0">Il semble que vous ayez trouvé un bug dans la matrice...</p>
<a href="/">&larr; Retour à l'accueil</a>
</div>
</div>

View File

@@ -0,0 +1,6 @@
<!-- Footer partial - inclus dans certaines vues -->
<footer class="mt-auto py-3 bg-light">
<div class="container-fluid text-center">
<span class="text-muted">Mail Notifier &copy; <%= new Date().getFullYear() %> | Serveur mail local avec notifications Pushover</span>
</div>
</footer>

21
views/partials/header.ejs Normal file
View File

@@ -0,0 +1,21 @@
<!-- Header partial - inclus dans certaines vues -->
<header class="bg-white shadow-sm mb-4">
<div class="d-flex justify-content-between align-items-center p-3">
<h1 class="h4 mb-0"><%= typeof pageTitle !== 'undefined' ? pageTitle : 'Mail Notifier' %></h1>
<% if (typeof showActions !== 'undefined' && showActions) { %>
<div class="btn-group">
<% if (typeof actionButtons !== 'undefined') { %>
<% actionButtons.forEach(function(button) { %>
<a href="<%= button.href %>" class="btn <%= button.class || 'btn-outline-primary' %>">
<% if (button.icon) { %>
<i class="fas fa-<%= button.icon %> me-1"></i>
<% } %>
<%= button.text %>
</a>
<% }); %>
<% } %>
</div>
<% } %>
</div>
</header>

173
views/settings.ejs Normal file
View File

@@ -0,0 +1,173 @@
<div class="container-fluid">
<h1 class="h3 mb-4">Paramètres</h1>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Configuration</h6>
</div>
<div class="card-body">
<form action="/settings" method="POST">
<h5 class="mb-3">Serveur SMTP</h5>
<div class="row mb-4">
<div class="col-md-6">
<div class="mb-3">
<label for="smtpHost" class="form-label">Hôte</label>
<input type="text" class="form-control" id="smtpHost" name="smtpHost" value="<%= settings.smtp?.host || '0.0.0.0' %>">
<div class="form-text">Adresse IP à laquelle le serveur SMTP sera lié</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="smtpPort" class="form-label">Port</label>
<input type="number" class="form-control" id="smtpPort" name="smtpPort" value="<%= settings.smtp?.port || 2525 %>">
<div class="form-text">Port sur lequel le serveur SMTP écoutera</div>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-md-6">
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="smtpSecure" name="smtpSecure" value="true" <%= settings.smtp?.secure ? 'checked' : '' %>>
<label class="form-check-label" for="smtpSecure">
Connexion sécurisée (TLS)
</label>
<div class="form-text">Activer TLS pour les connexions SMTP</div>
</div>
</div>
<div class="col-md-6">
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="smtpAuthOptional" name="smtpAuthOptional" value="true" <%= settings.smtp?.authOptional ? 'checked' : '' %>>
<label class="form-check-label" for="smtpAuthOptional">
Authentification optionnelle
</label>
<div class="form-text">Permettre les connexions sans authentification</div>
</div>
</div>
</div>
<hr class="my-4">
<h5 class="mb-3">Notifications Pushover</h5>
<div class="row mb-4">
<div class="col-md-6">
<div class="mb-3">
<label for="pushoverUser" class="form-label">Clé utilisateur</label>
<input type="text" class="form-control" id="pushoverUser" name="pushoverUser" value="<%= settings.pushover?.user || '' %>">
<div class="form-text">Votre clé utilisateur Pushover</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="pushoverToken" class="form-label">Token d'application</label>
<input type="text" class="form-control" id="pushoverToken" name="pushoverToken" value="<%= settings.pushover?.token || '' %>">
<div class="form-text">Token API de votre application Pushover</div>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<div class="mb-3">
<label for="pushoverTitle" class="form-label">Titre des notifications</label>
<input type="text" class="form-control" id="pushoverTitle" name="pushoverTitle" value="<%= settings.pushover?.title || 'Mail Notifier' %>">
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="pushoverSound" class="form-label">Son</label>
<select class="form-select" id="pushoverSound" name="pushoverSound">
<option value="pushover" <%= settings.pushover?.sound === 'pushover' ? 'selected' : '' %>>Pushover (défaut)</option>
<option value="bike" <%= settings.pushover?.sound === 'bike' ? 'selected' : '' %>>Bike</option>
<option value="bugle" <%= settings.pushover?.sound === 'bugle' ? 'selected' : '' %>>Bugle</option>
<option value="cashregister" <%= settings.pushover?.sound === 'cashregister' ? 'selected' : '' %>>Cash Register</option>
<option value="classical" <%= settings.pushover?.sound === 'classical' ? 'selected' : '' %>>Classical</option>
<option value="cosmic" <%= settings.pushover?.sound === 'cosmic' ? 'selected' : '' %>>Cosmic</option>
<option value="falling" <%= settings.pushover?.sound === 'falling' ? 'selected' : '' %>>Falling</option>
<option value="gamelan" <%= settings.pushover?.sound === 'gamelan' ? 'selected' : '' %>>Gamelan</option>
<option value="incoming" <%= settings.pushover?.sound === 'incoming' ? 'selected' : '' %>>Incoming</option>
<option value="magic" <%= settings.pushover?.sound === 'magic' ? 'selected' : '' %>>Magic</option>
<option value="none" <%= settings.pushover?.sound === 'none' ? 'selected' : '' %>>Aucun son</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="pushoverPriority" class="form-label">Priorité</label>
<select class="form-select" id="pushoverPriority" name="pushoverPriority">
<option value="-2" <%= settings.pushover?.priority === -2 ? 'selected' : '' %>>Très basse (-2)</option>
<option value="-1" <%= settings.pushover?.priority === -1 ? 'selected' : '' %>>Basse (-1)</option>
<option value="0" <%= settings.pushover?.priority === 0 || !settings.pushover?.priority ? 'selected' : '' %>>Normale (0)</option>
<option value="1" <%= settings.pushover?.priority === 1 ? 'selected' : '' %>>Haute (1)</option>
<option value="2" <%= settings.pushover?.priority === 2 ? 'selected' : '' %>>Urgente (2)</option>
</select>
<div class="form-text">Les notifications urgentes (2) contournent le mode silencieux et nécessitent une confirmation</div>
</div>
</div>
</div>
<div class="mb-4">
<button type="button" class="btn btn-info" id="testPushover" onclick="document.getElementById('testPushoverForm').submit();">
<i class="fas fa-bell"></i> Tester les notifications
</button>
<div class="form-text">Envoie une notification de test pour vérifier votre configuration</div>
</div>
<hr class="my-4">
<h5 class="mb-3">Administration</h5>
<div class="row mb-4">
<div class="col-md-6">
<div class="mb-3">
<label for="adminUsername" class="form-label">Nom d'utilisateur</label>
<input type="text" class="form-control" id="adminUsername" name="adminUsername" value="<%= settings.admin?.username || 'admin' %>">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="adminPassword" class="form-label">Mot de passe</label>
<input type="password" class="form-control" id="adminPassword" name="adminPassword" placeholder="Laisser vide pour ne pas changer">
<div class="form-text">Laisser vide pour conserver le mot de passe actuel</div>
</div>
</div>
</div>
<div class="form-check mb-4">
<input class="form-check-input" type="checkbox" id="enableAuth" name="enableAuth" value="true" <%= settings.admin?.enableAuth ? 'checked' : '' %>>
<label class="form-check-label" for="enableAuth">
Activer l'authentification
</label>
<div class="form-text">Si désactivé, aucune connexion ne sera requise pour accéder à l'interface d'administration</div>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<button type="submit" class="btn btn-primary">
<i class="fas fa-save"></i> Enregistrer les paramètres
</button>
</div>
</form>
<!-- Formulaire de test Pushover (soumis via JS) -->
<form id="testPushoverForm" action="/test-pushover" method="POST" class="d-none"></form>
</div>
</div>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Informations système</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Version:</strong> <%= settings.version || '1.0.0' %></p>
<p><strong>Mode:</strong> <%= process.env.NODE_ENV || 'development' %></p>
</div>
<div class="col-md-6">
<p><strong>Démarré le:</strong> <%= settings.createdAt ? new Date(settings.createdAt).toLocaleString() : new Date().toLocaleString() %></p>
<p><strong>Modifié le:</strong> <%= settings.updatedAt ? new Date(settings.updatedAt).toLocaleString() : new Date().toLocaleString() %></p>
</div>
</div>
</div>
</div>
</div>