feat(ucp): NexusPBX v2.5.0 Portail Utilisateur isolé (Refs #4)
This commit is contained in:
1 parent
7922e338e3
commit
72e43f1a9a
18 files changed
+3499
-62
No files matched your search
@@ -338,6 +338,11 @@ $isDevEnv = file_exists(__DIR__ . '/../.dev')
|
||||
<span>• Annuaire d'Entreprise</span>
|
||||
<span id="nav-badge-phonebook" class="px-1.5 py-0.2 text-[10px] rounded-full bg-anthracite-800 text-teal-300 border border-anthracite-700 font-bold">0</span>
|
||||
</button>
|
||||
<button type="button" data-tab="ucp" onclick="switchTab('ucp')"
|
||||
class="tab-btn w-full flex items-center justify-between px-3 py-1.5 rounded-lg text-xs font-medium text-slate-300 hover:bg-anthracite-800 hover:text-white transition">
|
||||
<span>• Portail Utilisateur (UCP)</span>
|
||||
<span id="nav-badge-ucp" class="px-1.5 py-0.2 text-[10px] rounded-full bg-anthracite-800 text-sky-300 border border-anthracite-700 font-bold">0</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2199,6 +2204,7 @@ $isDevEnv = file_exists(__DIR__ . '/../.dev')
|
||||
<select id="manual-ban-jail" class="w-full sm:w-48 px-3 py-2 rounded-lg bg-anthracite-950 border border-anthracite-700 text-xs text-white">
|
||||
<option value="asterisk">Téléphonie SIP</option>
|
||||
<option value="nexus-web">Interface Web Admin</option>
|
||||
<option value="nexus-ucp">Portail Utilisateur (UCP)</option>
|
||||
<option value="sshd">Console SSH</option>
|
||||
</select>
|
||||
<button type="submit"
|
||||
@@ -2281,6 +2287,55 @@ $isDevEnv = file_exists(__DIR__ . '/../.dev')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Portail Utilisateur Isolé (UCP) & Fail2ban dédié -->
|
||||
<div class="p-3.5 rounded-xl bg-anthracite-950 border border-anthracite-700 space-y-3">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<span class="text-xs font-bold uppercase tracking-wider text-sky-300">Portail Utilisateur Isolé (UCP)</span>
|
||||
<p class="text-[11px] text-slate-400 leading-tight mt-0.5">VHost Nginx séparé de l'Admin avec prison Fail2ban <code class="text-sky-300">[nexus-ucp]</code>.</p>
|
||||
</div>
|
||||
<label class="relative inline-flex items-center cursor-pointer shrink-0 mt-0.5">
|
||||
<input type="checkbox" name="ucp_enabled" id="ucp_enabled" value="1" class="sr-only peer" checked>
|
||||
<div class="w-11 h-6 bg-anthracite-700 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-sky-600"></div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-2.5">
|
||||
<div>
|
||||
<label class="block text-[11px] font-medium text-slate-300 mb-1">Port HTTPS UCP</label>
|
||||
<input type="number" name="ucp_https_port" id="ucp_https_port" value="8444" min="0" max="65535"
|
||||
class="w-full px-2.5 py-1.5 rounded-lg bg-anthracite-900 border border-anthracite-700 text-xs text-white font-mono">
|
||||
<p class="text-[10px] text-slate-400 mt-0.5">Défaut : 8444 (0 = désactivé)</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-[11px] font-medium text-slate-300 mb-1">Port HTTP UCP (Proxy)</label>
|
||||
<input type="number" name="ucp_http_port" id="ucp_http_port" value="8084" min="0" max="65535"
|
||||
class="w-full px-2.5 py-1.5 rounded-lg bg-anthracite-900 border border-anthracite-700 text-xs text-white font-mono">
|
||||
<p class="text-[10px] text-slate-400 mt-0.5">Défaut : 8084 (0 = désactivé)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-2.5 pt-1 border-t border-anthracite-800">
|
||||
<div>
|
||||
<label class="block text-[11px] font-medium text-slate-300 mb-1">Max échecs UCP</label>
|
||||
<select name="fail2ban_ucp_maxretry" class="w-full px-2.5 py-1.5 rounded-lg bg-anthracite-900 border border-anthracite-700 text-xs text-white">
|
||||
<option value="2">2 tentatives</option>
|
||||
<option value="3" selected>3 tentatives</option>
|
||||
<option value="5">5 tentatives</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-[11px] font-medium text-slate-300 mb-1">Durée ban UCP</label>
|
||||
<select name="fail2ban_ucp_bantime" class="w-full px-2.5 py-1.5 rounded-lg bg-anthracite-900 border border-anthracite-700 text-xs text-white">
|
||||
<option value="3600" selected>1 heure</option>
|
||||
<option value="43200">12 heures</option>
|
||||
<option value="86400">24 heures</option>
|
||||
<option value="604800">7 jours</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Liste Blanche Permanente (IgnoreIP) -->
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
@@ -2304,6 +2359,80 @@ $isDevEnv = file_exists(__DIR__ . '/../.dev')
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ========================================================= -->
|
||||
<!-- ONGLET UCP : PORTAIL UTILISATEUR & COMPTES -->
|
||||
<!-- ========================================================= -->
|
||||
<section id="tab-ucp" class="tab-panel hidden space-y-6">
|
||||
<!-- En-tête & État d'exposition réseau UCP -->
|
||||
<div class="rounded-2xl bg-anthracite-900 border border-anthracite-800 p-5 flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-11 h-11 rounded-xl bg-sky-500/15 border border-sky-500/30 flex items-center justify-center shrink-0">
|
||||
<svg class="w-6 h-6 text-sky-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex items-center gap-2.5 flex-wrap">
|
||||
<h3 class="text-base font-bold text-white">Portail Utilisateur (UCP)</h3>
|
||||
<span id="ucp-service-status-badge" class="px-2 py-0.5 rounded-full text-[11px] font-semibold bg-emerald-500/15 text-emerald-300 border border-emerald-500/30">
|
||||
Vérification...
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-xs text-slate-400 mt-1">
|
||||
VirtualHost Nginx isolé sur <code class="text-sky-300">/var/www/nexus-pbx/ucp</code> — aucun accès à l'administration, protégé par Fail2ban (<code class="text-sky-300">nexus-ucp</code>).
|
||||
</p>
|
||||
<div id="ucp-access-urls" class="mt-2.5 flex flex-wrap items-center gap-2 text-xs"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2.5 shrink-0">
|
||||
<button type="button" onclick="switchTab('firewall')"
|
||||
class="px-3.5 py-2 rounded-xl bg-anthracite-800 hover:bg-anthracite-750 text-slate-200 border border-anthracite-700 text-xs font-semibold transition flex items-center gap-2">
|
||||
<svg class="w-4 h-4 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
Configurer les Ports & Fail2ban
|
||||
</button>
|
||||
<button type="button" onclick="openUcpUserModal()"
|
||||
class="px-4 py-2 rounded-xl bg-sky-600 hover:bg-sky-500 text-white text-xs font-bold shadow-lg shadow-sky-600/20 transition flex items-center gap-1.5">
|
||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" />
|
||||
</svg>
|
||||
Nouvel Utilisateur UCP
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tableau des utilisateurs UCP -->
|
||||
<div class="rounded-2xl bg-anthracite-900 border border-anthracite-800 overflow-hidden">
|
||||
<div class="px-5 py-4 border-b border-anthracite-800 flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<h4 class="text-sm font-bold text-white">Comptes Portail Utilisateur</h4>
|
||||
<p class="text-[11px] text-slate-400">Chaque compte ne peut gérer que les extensions SIP qui lui sont explicitement assignées.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr class="border-b border-anthracite-800 bg-anthracite-950/60 text-[11px] font-semibold uppercase tracking-wider text-slate-400">
|
||||
<th class="px-5 py-3">Identifiant</th>
|
||||
<th class="px-5 py-3">Nom affiché & Email</th>
|
||||
<th class="px-5 py-3">Extensions liées</th>
|
||||
<th class="px-5 py-3">Statut</th>
|
||||
<th class="px-5 py-3">Dernière connexion</th>
|
||||
<th class="px-5 py-3 text-right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="ucp-users-table-body" class="divide-y divide-anthracite-800/70 text-xs">
|
||||
<tr>
|
||||
<td colspan="6" class="px-5 py-8 text-center text-slate-500">Chargement des utilisateurs UCP...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ========================================================= -->
|
||||
<!-- ONGLET 5 : CODES DE FONCTIONS & SERVICES TÉLÉPHONIQUES -->
|
||||
<!-- ========================================================= -->
|
||||
@@ -5458,6 +5587,83 @@ $isDevEnv = file_exists(__DIR__ . '/../.dev')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========================================================= -->
|
||||
<!-- MODALE UTILISATEUR UCP (CRÉATION / ÉDITION) -->
|
||||
<!-- ========================================================= -->
|
||||
<div id="modal-ucp-user" class="fixed inset-0 z-50 hidden items-center justify-center bg-black/75 backdrop-blur-sm p-4">
|
||||
<div class="w-full max-w-xl rounded-2xl bg-anthracite-900 border border-anthracite-700 shadow-2xl overflow-hidden">
|
||||
<div class="px-6 py-4 border-b border-anthracite-800 flex items-center justify-between bg-anthracite-950/60">
|
||||
<div>
|
||||
<h3 id="ucp-modal-title" class="text-sm font-bold text-white">Nouvel utilisateur UCP</h3>
|
||||
<p class="text-[11px] text-slate-400">Attribuez des identifiants et une ou plusieurs extensions SIP</p>
|
||||
</div>
|
||||
<button type="button" onclick="closeUcpUserModal()" class="text-slate-400 hover:text-white p-1.5 rounded-lg hover:bg-anthracite-800 transition">✕</button>
|
||||
</div>
|
||||
<form id="form-ucp-user" onsubmit="saveUcpUser(event)" class="p-6 space-y-4 max-h-[75vh] overflow-y-auto">
|
||||
<input type="hidden" id="ucp-user-id" value="0">
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-semibold text-slate-300 mb-1.5">Identifiant de connexion <span class="text-rose-400">*</span></label>
|
||||
<input type="text" id="ucp-user-username" required autocomplete="off"
|
||||
placeholder="ex: j.dupont"
|
||||
class="w-full px-3.5 py-2 rounded-xl bg-anthracite-950 border border-anthracite-700 text-sm text-white focus:border-sky-500 focus:outline-none">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-semibold text-slate-300 mb-1.5">Nom complet affiché</label>
|
||||
<input type="text" id="ucp-user-display-name" autocomplete="off"
|
||||
placeholder="ex: Jean Dupont"
|
||||
class="w-full px-3.5 py-2 rounded-xl bg-anthracite-950 border border-anthracite-700 text-sm text-white focus:border-sky-500 focus:outline-none">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs font-semibold text-slate-300 mb-1.5">Adresse Email</label>
|
||||
<input type="email" id="ucp-user-email" autocomplete="off"
|
||||
placeholder="jean.dupont@entreprise.fr"
|
||||
class="w-full px-3.5 py-2 rounded-xl bg-anthracite-950 border border-anthracite-700 text-sm text-white focus:border-sky-500 focus:outline-none">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-semibold text-slate-300 mb-1.5">
|
||||
Mot de passe <span id="ucp-password-hint" class="text-[11px] font-normal text-slate-400">(min. 6 car.)</span>
|
||||
</label>
|
||||
<input type="password" id="ucp-user-password" autocomplete="new-password"
|
||||
placeholder="••••••••"
|
||||
class="w-full px-3.5 py-2 rounded-xl bg-anthracite-950 border border-anthracite-700 text-sm text-white focus:border-sky-500 focus:outline-none">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<label class="text-xs font-semibold text-slate-300">Extensions SIP autorisées</label>
|
||||
<span class="text-[11px] text-slate-400">Cochez un ou plusieurs postes</span>
|
||||
</div>
|
||||
<div id="ucp-user-extensions-container"
|
||||
class="grid grid-cols-1 sm:grid-cols-2 gap-2 max-h-48 overflow-y-auto p-3 rounded-xl bg-anthracite-950 border border-anthracite-800">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="flex items-center gap-2.5 cursor-pointer select-none pt-1">
|
||||
<input type="checkbox" id="ucp-user-enabled" checked
|
||||
class="w-4 h-4 rounded border-anthracite-600 bg-anthracite-950 text-sky-500 focus:ring-sky-500">
|
||||
<span class="text-xs font-medium text-slate-300">Compte actif (autoriser la connexion au portail UCP)</span>
|
||||
</label>
|
||||
|
||||
<div class="pt-3 border-t border-anthracite-800 flex items-center justify-end gap-3">
|
||||
<button type="button" onclick="closeUcpUserModal()"
|
||||
class="px-4 py-2 rounded-xl text-xs font-semibold bg-anthracite-800 hover:bg-anthracite-750 text-slate-300 border border-anthracite-700 transition">
|
||||
Annuler
|
||||
</button>
|
||||
<button type="submit" id="btn-save-ucp-user"
|
||||
class="px-5 py-2 rounded-xl text-xs font-bold bg-sky-600 hover:bg-sky-500 text-white shadow-lg shadow-sky-600/20 transition">
|
||||
Enregistrer l'utilisateur
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/assets/app.js?v=<?= filemtime(__DIR__ . '/assets/app.js') ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user