Compare commits
2
Commits
v1.6.1
..
4caef3abef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4caef3abef | ||
|
|
986e8e2e3c |
No files matched your search
@@ -47,30 +47,34 @@
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
nexus-pbx/
|
nexus-pbx/
|
||||||
|
├── install.sh # Script d'installation automatisé tout-en-un (Debian 12 / 13)
|
||||||
├── public/ # Racine Web Nginx
|
├── public/ # Racine Web Nginx
|
||||||
│ ├── index.php # Interface Web SPA moderne
|
│ ├── index.php # Interface Web SPA moderne
|
||||||
│ ├── api.php # API RESTful backend
|
│ ├── api.php # API RESTful backend
|
||||||
│ ├── phonebook.php # Générateur XML Yealink Remote Phonebook
|
│ ├── phonebook.php # Générateur XML Yealink Remote Phonebook
|
||||||
│ ├── assets/ # JavaScript (app.js), styles Tailwind CSS
|
│ ├── assets/ # Logo, Favicon, JS (app.js), styles Tailwind CSS
|
||||||
│ └── avatars/ # Photos des contacts de l'annuaire
|
│ └── avatars/ # Photos des contacts de l'annuaire
|
||||||
├── src/ # Classes PHP d'orchestration
|
├── src/ # Classes PHP d'orchestration
|
||||||
│ ├── AmiClient.php # Client Asterisk Manager Interface (AMI)
|
│ ├── AmiClient.php # Client Asterisk Manager Interface (AMI)
|
||||||
│ ├── Auth.php # Authentification & sessions
|
│ ├── Auth.php # Authentification & sessions
|
||||||
│ ├── BackupManager.php # Moteur de sauvegarde locale & distante SSH
|
│ ├── BackupManager.php # Moteur Disaster Recovery & sauvegardes
|
||||||
│ ├── CertificateManager.php # Gestionnaire SSL & Certbot
|
│ ├── CdrManager.php # Moteur Journal d'appels & CDR
|
||||||
|
│ ├── CertificateManager.php # Gestionnaire SSL & Certbot ACME
|
||||||
│ ├── ConfigGenerator.php # Générateur dynamique de conf Asterisk (pjsip, extensions)
|
│ ├── ConfigGenerator.php # Générateur dynamique de conf Asterisk (pjsip, extensions)
|
||||||
│ ├── Database.php # Connexion PDO SQLite
|
│ ├── Database.php # Connexion PDO SQLite
|
||||||
│ ├── FirewallManager.php # Moteur Pare-feu & règles Nginx
|
│ ├── FirewallManager.php # Moteur Pare-feu Fail2ban & Nginx
|
||||||
│ ├── PhonebookManager.php # Moteur d'annuaire et export XML
|
│ ├── PhonebookManager.php # Moteur d'annuaire et export XML
|
||||||
│ ├── SystemChecker.php # Diagnostic de santé système
|
│ ├── SystemChecker.php # Diagnostic de santé système
|
||||||
│ └── SystemMetrics.php # Monitoring CPU, RAM, Disque, Asterisk
|
│ └── SystemMetrics.php # Monitoring CPU, RAM, Disque, Asterisk
|
||||||
├── scripts/ # Scripts CLI et daemons système
|
├── scripts/ # Scripts CLI et daemons système
|
||||||
│ ├── setup-debian.sh # Script d'installation automatisé Debian 12 / 13
|
│ ├── update.sh # Script de mise à jour OTA (nexus-update)
|
||||||
│ ├── nexus-firewall # Script de gestion iptables/nftables
|
│ ├── nexus-firewall # Outil CLI Pare-feu & Fail2ban
|
||||||
│ └── nexus_autobackup.php# Cronjob de sauvegarde automatique
|
│ ├── nexus-banner.sh # Bannière d'accueil interactive SSH/Console
|
||||||
|
│ ├── nexus_autobackup.php# Cronjob de sauvegarde automatique
|
||||||
|
│ └── voicemail_pass_sync.php # Synchronisation code PIN messagerie vocale
|
||||||
└── storage/ # Données persistantes (exclues du Git)
|
└── storage/ # Données persistantes (exclues du Git)
|
||||||
├── database.sqlite # Base de données applicative
|
├── database.sqlite # Base de données applicative
|
||||||
├── backups/ # Archives de sauvegarde
|
├── system_backups/ # Archives de sauvegarde Disaster Recovery
|
||||||
└── sounds/ # Fichiers audio MoH et annonces
|
└── sounds/ # Fichiers audio MoH et annonces
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -4922,7 +4922,13 @@ function renderBackups() {
|
|||||||
? `<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-emerald-500/20 text-emerald-300 border border-emerald-500/30">Local</span>`
|
? `<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-emerald-500/20 text-emerald-300 border border-emerald-500/30">Local</span>`
|
||||||
: `<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-purple-500/20 text-purple-300 border border-purple-500/30">Distant (SSH)</span>`;
|
: `<span class="px-2 py-0.5 rounded-full text-[10px] font-bold bg-purple-500/20 text-purple-300 border border-purple-500/30">Distant (SSH)</span>`;
|
||||||
|
|
||||||
const versionBadge = `<span class="px-1.5 py-0.2 rounded text-[10px] font-mono font-bold bg-indigo-500/20 text-indigo-300 border border-indigo-500/30">v${escapeHtml(b.version || '1.2.0')}</span>`;
|
const versionBadge = `<span class="px-1.5 py-0.2 rounded text-[10px] font-mono font-bold bg-indigo-500/20 text-indigo-300 border border-indigo-500/30">v${escapeHtml(b.version || '1.6.2')}</span>`;
|
||||||
|
let srcBadge = '';
|
||||||
|
if (b.source === 'pre-update') {
|
||||||
|
srcBadge = `<span class="px-1.5 py-0.2 rounded text-[10px] font-bold bg-amber-500/20 text-amber-300 border border-amber-500/30" title="Sauvegarde automatique pré-mise à jour">Pré-MàJ</span>`;
|
||||||
|
} else if (b.source === 'scheduled') {
|
||||||
|
srcBadge = `<span class="px-1.5 py-0.2 rounded text-[10px] font-bold bg-cyan-500/20 text-cyan-300 border border-cyan-500/30" title="Sauvegarde planifiée automatique">Auto</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<tr class="hover:bg-anthracite-750 transition">
|
<tr class="hover:bg-anthracite-750 transition">
|
||||||
@@ -4933,6 +4939,7 @@ function renderBackups() {
|
|||||||
</svg>
|
</svg>
|
||||||
<span class="truncate max-w-xs sm:max-w-md">${escapeHtml(b.filename)}</span>
|
<span class="truncate max-w-xs sm:max-w-md">${escapeHtml(b.filename)}</span>
|
||||||
${versionBadge}
|
${versionBadge}
|
||||||
|
${srcBadge}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-3 text-slate-300 whitespace-nowrap">${escapeHtml(b.date_formatted)}</td>
|
<td class="px-4 py-3 text-slate-300 whitespace-nowrap">${escapeHtml(b.date_formatted)}</td>
|
||||||
|
|||||||
-198
@@ -1,198 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# ==============================================================================
|
|
||||||
# NexusPBX - Script de Réparation Automatique des Permissions & Services
|
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
|
||||||
echo "[ERREUR] Ce script doit être exécuté en root."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "-> Correction des répertoires Git et mise à jour..."
|
|
||||||
git config --global --add safe.directory /var/www/nexus-pbx 2>/dev/null || true
|
|
||||||
cd /var/www/nexus-pbx
|
|
||||||
git fetch origin main
|
|
||||||
git reset --hard origin/main
|
|
||||||
|
|
||||||
echo "-> Installation des dépendances système indispensables (ACL, ffmpeg, rsync, sox, sshpass)..."
|
|
||||||
which ffmpeg >/dev/null 2>&1 && which rsync >/dev/null 2>&1 && which setfacl >/dev/null 2>&1 && which sshpass >/dev/null 2>&1 || (apt-get update -y && apt-get install -y --no-install-recommends acl ffmpeg rsync sox sshpass)
|
|
||||||
|
|
||||||
echo "-> Création des dossiers et des fichiers de journalisation..."
|
|
||||||
mkdir -p /etc/fail2ban/filter.d /etc/asterisk /var/log/asterisk /var/log/asterisk/cdr-csv /var/log/nexus-pbx /var/www/nexus-pbx/storage/backups
|
|
||||||
|
|
||||||
touch /var/log/asterisk/messages /var/log/asterisk/security.log /var/log/asterisk/cdr-csv/Master.csv /var/log/nexus_security.log
|
|
||||||
chown asterisk:asterisk /var/log/asterisk/messages /var/log/asterisk/security.log /var/log/asterisk/cdr-csv/Master.csv 2>/dev/null || true
|
|
||||||
chmod 0664 /var/log/asterisk/messages /var/log/asterisk/security.log /var/log/asterisk/cdr-csv/Master.csv 2>/dev/null || true
|
|
||||||
chown www-data:asterisk /var/log/nexus_security.log 2>/dev/null || true
|
|
||||||
chmod 0664 /var/log/nexus_security.log 2>/dev/null || true
|
|
||||||
|
|
||||||
echo "-> Filtres Fail2ban Nexus-Web..."
|
|
||||||
cat << 'EOF' > /etc/fail2ban/filter.d/nexus-web.conf
|
|
||||||
[Definition]
|
|
||||||
failregex = ^.*\[NEXUS-WEB-AUTH-FAIL\]:\s*<HOST>.*$
|
|
||||||
ignoreregex =
|
|
||||||
EOF
|
|
||||||
chmod 0644 /etc/fail2ban/filter.d/nexus-web.conf
|
|
||||||
|
|
||||||
echo "-> Génération et application de /etc/fail2ban/jail.local..."
|
|
||||||
php -r '
|
|
||||||
require_once "/var/www/nexus-pbx/src/Database.php";
|
|
||||||
require_once "/var/www/nexus-pbx/src/FirewallManager.php";
|
|
||||||
$st = App\FirewallManager::getSettings();
|
|
||||||
App\FirewallManager::generateJailLocal(
|
|
||||||
$st["fail2ban_whitelist_ips"],
|
|
||||||
(int)$st["fail2ban_sip_maxretry"],
|
|
||||||
(int)$st["fail2ban_sip_findtime"],
|
|
||||||
(int)$st["fail2ban_sip_bantime"],
|
|
||||||
(int)$st["fail2ban_web_maxretry"],
|
|
||||||
(int)$st["fail2ban_web_bantime"],
|
|
||||||
(int)$st["admin_https_port"]
|
|
||||||
);
|
|
||||||
App\FirewallManager::applyNginxConfig((int)$st["admin_https_port"], (int)$st["certbot_strict_port80"]);
|
|
||||||
' 2>/dev/null || true
|
|
||||||
|
|
||||||
echo "-> Droits applicatifs et ACL POSIX (/etc/asterisk et /var/www/nexus-pbx)..."
|
|
||||||
usermod -aG asterisk www-data 2>/dev/null || true
|
|
||||||
usermod -aG www-data asterisk 2>/dev/null || true
|
|
||||||
|
|
||||||
mkdir -p /var/www/nexus-pbx/public/avatars /var/www/nexus-pbx/storage/sounds /var/www/nexus-pbx/storage/backups /var/www/nexus-pbx/storage/system_backups /etc/letsencrypt /var/log/letsencrypt /var/lib/letsencrypt
|
|
||||||
chgrp -R asterisk /etc/letsencrypt 2>/dev/null || true
|
|
||||||
chmod -R g+rX /etc/letsencrypt 2>/dev/null || true
|
|
||||||
chown -R www-data:asterisk /var/www/nexus-pbx
|
|
||||||
chmod 2775 /var/www/nexus-pbx/storage /var/www/nexus-pbx/storage/backups /var/www/nexus-pbx/storage/system_backups /var/www/nexus-pbx/storage/sounds /var/www/nexus-pbx/public/avatars 2>/dev/null || true
|
|
||||||
|
|
||||||
touch /etc/asterisk/pjsip.conf \
|
|
||||||
/etc/asterisk/pjsip.custom.conf \
|
|
||||||
/etc/asterisk/extensions.conf \
|
|
||||||
/etc/asterisk/extensions.custom.conf \
|
|
||||||
/etc/asterisk/musiconhold.conf \
|
|
||||||
/etc/asterisk/musiconhold.custom.conf \
|
|
||||||
/etc/asterisk/voicemail.conf \
|
|
||||||
/etc/asterisk/voicemail.custom.conf \
|
|
||||||
/etc/asterisk/modules.conf \
|
|
||||||
/etc/asterisk/rtp.conf \
|
|
||||||
/etc/asterisk/features.conf 2>/dev/null || true
|
|
||||||
|
|
||||||
# Désactivation des modules ODBC/IMAP incompatibles sur Debian (évite conflit bloquant app_voicemail)
|
|
||||||
if ! grep -q 'noload => app_voicemail_odbc.so' /etc/asterisk/modules.conf 2>/dev/null; then
|
|
||||||
if grep -q '\[modules\]' /etc/asterisk/modules.conf 2>/dev/null; then
|
|
||||||
sed -i '/\[modules\]/a noload => app_voicemail_odbc.so\nnoload => app_voicemail_imap.so' /etc/asterisk/modules.conf 2>/dev/null || true
|
|
||||||
else
|
|
||||||
printf '[modules]\nautoload=yes\nnoload => app_voicemail_odbc.so\nnoload => app_voicemail_imap.so\n' >> /etc/asterisk/modules.conf
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Inclusions Asterisk et configuration messagerie vocale
|
|
||||||
if ! grep -q 'pjsip.custom.conf' /etc/asterisk/pjsip.conf 2>/dev/null; then
|
|
||||||
printf '\n#tryinclude "pjsip.custom.conf"\n' >> /etc/asterisk/pjsip.conf
|
|
||||||
fi
|
|
||||||
if ! grep -q 'extensions.custom.conf' /etc/asterisk/extensions.conf 2>/dev/null; then
|
|
||||||
printf '\n#tryinclude "extensions.custom.conf"\n' >> /etc/asterisk/extensions.conf
|
|
||||||
fi
|
|
||||||
if ! grep -q 'musiconhold.custom.conf' /etc/asterisk/musiconhold.conf 2>/dev/null; then
|
|
||||||
sed -i 's/^\[default\]/;[default]/' /etc/asterisk/musiconhold.conf 2>/dev/null || true
|
|
||||||
sed -i 's/^mode=files/;mode=files/' /etc/asterisk/musiconhold.conf 2>/dev/null || true
|
|
||||||
sed -i 's/^directory=moh/;directory=moh/' /etc/asterisk/musiconhold.conf 2>/dev/null || true
|
|
||||||
printf '\n#tryinclude "/etc/asterisk/musiconhold.custom.conf"\n' >> /etc/asterisk/musiconhold.conf
|
|
||||||
fi
|
|
||||||
if ! grep -q 'voicemail.custom.conf' /etc/asterisk/voicemail.conf 2>/dev/null; then
|
|
||||||
sed -i 's/^1234 => 4242/;1234 => 4242/' /etc/asterisk/voicemail.conf 2>/dev/null || true
|
|
||||||
sed -i 's/^;\s*passwordlocation\s*=\s*spooldir/passwordlocation=spooldir/' /etc/asterisk/voicemail.conf 2>/dev/null || true
|
|
||||||
sed -i 's|^;\s*externpassnotify\s*=.*|externpassnotify=/usr/bin/php /var/www/nexus-pbx/scripts/voicemail_pass_sync.php|' /etc/asterisk/voicemail.conf 2>/dev/null || true
|
|
||||||
printf '\n#tryinclude "voicemail.custom.conf"\n' >> /etc/asterisk/voicemail.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p /var/lib/asterisk/sounds/custom /var/lib/asterisk/moh /var/spool/asterisk/voicemail/default 2>/dev/null || true
|
|
||||||
for lang in fr en es; do
|
|
||||||
if [ -d "/usr/share/asterisk/sounds/$lang" ] && [ ! -e "/var/lib/asterisk/sounds/$lang" ]; then
|
|
||||||
ln -sf "/usr/share/asterisk/sounds/$lang" "/var/lib/asterisk/sounds/$lang" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
if [ -d "/var/lib/asterisk/sounds/$lang" ] && [ ! -e "/var/lib/asterisk/sounds/$lang/custom" ]; then
|
|
||||||
ln -sf /var/lib/asterisk/sounds/custom "/var/lib/asterisk/sounds/$lang/custom" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ ! -e "/usr/share/asterisk/sounds/custom" ]; then
|
|
||||||
ln -sf /var/lib/asterisk/sounds/custom /usr/share/asterisk/sounds/custom 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
chown -R asterisk:asterisk /etc/asterisk /var/lib/asterisk /var/spool/asterisk /var/log/asterisk 2>/dev/null || true
|
|
||||||
chmod -R 775 /etc/asterisk /var/lib/asterisk/sounds /var/lib/asterisk/moh /var/spool/asterisk /var/log/asterisk 2>/dev/null || true
|
|
||||||
chmod 2775 /etc/asterisk /var/lib/asterisk/sounds /var/lib/asterisk/sounds/custom /var/lib/asterisk/moh /var/spool/asterisk /var/spool/asterisk/voicemail /var/log/asterisk /var/log/asterisk/cdr-csv 2>/dev/null || true
|
|
||||||
chmod 2750 /etc/asterisk/keys 2>/dev/null || true
|
|
||||||
chmod 0664 /etc/asterisk/*.conf /etc/asterisk/*.custom.conf 2>/dev/null || true
|
|
||||||
|
|
||||||
setfacl -R -m u:www-data:rwx,g:asterisk:rwx /etc/asterisk /var/lib/asterisk/sounds /var/lib/asterisk/moh /var/spool/asterisk /var/log/asterisk 2>/dev/null || true
|
|
||||||
setfacl -R -d -m u:www-data:rwx,g:asterisk:rwx /etc/asterisk /var/lib/asterisk/sounds /var/lib/asterisk/moh /var/spool/asterisk /var/log/asterisk 2>/dev/null || true
|
|
||||||
|
|
||||||
chown root:asterisk /etc/fail2ban/jail.local /etc/nginx/sites-available/nexus-pbx 2>/dev/null || true
|
|
||||||
chmod 0664 /etc/fail2ban/jail.local /etc/nginx/sites-available/nexus-pbx 2>/dev/null || true
|
|
||||||
setfacl -m u:www-data:rw /etc/fail2ban/jail.local /etc/nginx/sites-available/nexus-pbx 2>/dev/null || true
|
|
||||||
|
|
||||||
cat << 'EOF' > /etc/sudoers.d/nexus-pbx
|
|
||||||
www-data ALL=(ALL) NOPASSWD: /usr/sbin/asterisk, /usr/sbin/nginx, /usr/bin/systemctl, /usr/bin/fail2ban-client, /bin/fail2ban-client, /var/www/nexus-pbx/scripts/nexus-firewall, /usr/bin/certbot, /usr/sbin/nft, /usr/sbin/iptables, /var/www/nexus-pbx/scripts/update.sh, /usr/local/bin/nexus-update
|
|
||||||
EOF
|
|
||||||
chmod 0440 /etc/sudoers.d/nexus-pbx
|
|
||||||
|
|
||||||
echo "-> Autorisation d'écriture systemd pour PHP-FPM (Debian 12/13 ProtectSystem)..."
|
|
||||||
for fpm_svc in /lib/systemd/system/php*-fpm.service /usr/lib/systemd/system/php*-fpm.service; do
|
|
||||||
if [ -f "$fpm_svc" ]; then
|
|
||||||
svc_name=$(basename "$fpm_svc")
|
|
||||||
mkdir -p "/etc/systemd/system/${svc_name}.d"
|
|
||||||
cat << 'EOF_OVERRIDE' > "/etc/systemd/system/${svc_name}.d/override.conf"
|
|
||||||
[Service]
|
|
||||||
ProtectSystem=false
|
|
||||||
ReadWritePaths=/etc/asterisk /etc/fail2ban /etc/nginx /var/log /var/lib/asterisk /var/spool/asterisk /var/www /usr/local/bin /etc/sudoers.d
|
|
||||||
EOF_OVERRIDE
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
systemctl daemon-reload
|
|
||||||
|
|
||||||
echo "-> Configuration des limites d'upload PHP (512 Mo)..."
|
|
||||||
for php_dir in /etc/php/*; do
|
|
||||||
if [ -d "$php_dir/fpm/conf.d" ]; then
|
|
||||||
cat << 'EOF_PHP' > "$php_dir/fpm/conf.d/99-nexus.ini"
|
|
||||||
upload_max_filesize = 512M
|
|
||||||
post_max_size = 512M
|
|
||||||
memory_limit = 512M
|
|
||||||
max_execution_time = 300
|
|
||||||
max_input_time = 300
|
|
||||||
EOF_PHP
|
|
||||||
fi
|
|
||||||
if [ -d "$php_dir/cli/conf.d" ]; then
|
|
||||||
cat << 'EOF_PHP' > "$php_dir/cli/conf.d/99-nexus.ini"
|
|
||||||
upload_max_filesize = 512M
|
|
||||||
post_max_size = 512M
|
|
||||||
memory_limit = 512M
|
|
||||||
max_execution_time = 300
|
|
||||||
max_input_time = 300
|
|
||||||
EOF_PHP
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "-> Génération des configurations Asterisk..."
|
|
||||||
php -r '
|
|
||||||
require_once "/var/www/nexus-pbx/src/Database.php";
|
|
||||||
require_once "/var/www/nexus-pbx/src/ConfigGenerator.php";
|
|
||||||
$db = App\Database::getConnection();
|
|
||||||
$gen = new App\ConfigGenerator($db);
|
|
||||||
$gen->writeAllConfigs();
|
|
||||||
' 2>/dev/null || true
|
|
||||||
|
|
||||||
echo "-> Redémarrage des services..."
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl restart php*-fpm 2>/dev/null || true
|
|
||||||
PHP_SVC=$(systemctl list-unit-files --type=service 2>/dev/null | grep -E "php.*-fpm" | awk '{print $1}' | head -n 1 || echo "")
|
|
||||||
if [ -n "$PHP_SVC" ]; then
|
|
||||||
systemctl restart "$PHP_SVC" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
systemctl restart asterisk 2>/dev/null || true
|
|
||||||
systemctl restart fail2ban 2>/dev/null || true
|
|
||||||
systemctl restart nginx 2>/dev/null || true
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=========================================================="
|
|
||||||
echo " [OK] Réparation terminée ! Toutes les permissions sont actives."
|
|
||||||
echo "=========================================================="
|
|
||||||
/var/www/nexus-pbx/scripts/nexus-banner.sh --force || true
|
|
||||||
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Redirection vers le script d'installation principal
|
|
||||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
exec bash "$DIR/install.sh" "$@"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
setup-debian.sh
|
|
||||||
+12
-9
@@ -81,15 +81,18 @@ fi
|
|||||||
|
|
||||||
echo -e "\n${C_YELLOW}-> Mise à jour vers la version v${REMOTE_VER}...${C_RESET}"
|
echo -e "\n${C_YELLOW}-> Mise à jour vers la version v${REMOTE_VER}...${C_RESET}"
|
||||||
|
|
||||||
# 1. Sauvegarde préventive automatique
|
# 1. Sauvegarde préventive automatique (Disaster Recovery complète)
|
||||||
echo -e "${C_GRAY}[1/6] Création d'une sauvegarde préventive du système...${C_RESET}"
|
echo -e "${C_GRAY}[1/6] Création d'une sauvegarde préventive du système (Disaster Recovery)...${C_RESET}"
|
||||||
mkdir -p "$APP_DIR/storage/backups"
|
php -r '
|
||||||
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
|
require_once "/var/www/nexus-pbx/src/Database.php";
|
||||||
BACKUP_FILE="$APP_DIR/storage/backups/pre-update-${BACKUP_DATE}.tar.gz"
|
require_once "/var/www/nexus-pbx/src/BackupManager.php";
|
||||||
tar -czf "$BACKUP_FILE" \
|
try {
|
||||||
-C "$APP_DIR/storage" database.sqlite \
|
$res = App\BackupManager::createBackup("pre-update");
|
||||||
-C /etc/asterisk pjsip.custom.conf extensions.custom.conf 2>/dev/null || true
|
echo " ✓ Sauvegarde Disaster Recovery créée : " . $res["filename"] . " (" . $res["size_formatted"] . ")\n";
|
||||||
echo -e "${C_GREEN} ✓ Sauvegarde de sécurité créée : $(basename "$BACKUP_FILE")${C_RESET}"
|
} catch (\Throwable $e) {
|
||||||
|
echo " ! Avertissement sauvegarde préventive : " . $e->getMessage() . "\n";
|
||||||
|
}
|
||||||
|
' || true
|
||||||
|
|
||||||
# 2. Application des derniers fichiers de code Git
|
# 2. Application des derniers fichiers de code Git
|
||||||
echo -e "${C_GRAY}[2/6] Déploiement des nouveaux fichiers de code...${C_RESET}"
|
echo -e "${C_GRAY}[2/6] Déploiement des nouveaux fichiers de code...${C_RESET}"
|
||||||
|
|||||||
+36
-5
@@ -11,7 +11,22 @@ use InvalidArgumentException;
|
|||||||
class BackupManager
|
class BackupManager
|
||||||
{
|
{
|
||||||
public const BACKUP_DIR = '/var/www/nexus-pbx/storage/system_backups';
|
public const BACKUP_DIR = '/var/www/nexus-pbx/storage/system_backups';
|
||||||
public const VERSION = '1.2.0';
|
public const VERSION = '1.6.2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne dynamiquement la version courante de NexusPBX lue depuis version.json
|
||||||
|
*/
|
||||||
|
public static function getAppVersion(): string
|
||||||
|
{
|
||||||
|
$vFile = dirname(__DIR__) . '/version.json';
|
||||||
|
if (file_exists($vFile)) {
|
||||||
|
$data = json_decode((string)file_get_contents($vFile), true);
|
||||||
|
if (!empty($data['version'])) {
|
||||||
|
return (string)$data['version'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self::VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise le répertoire des sauvegardes.
|
* Initialise le répertoire des sauvegardes.
|
||||||
@@ -182,7 +197,8 @@ class BackupManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
$timestamp = date('Ymd_His');
|
$timestamp = date('Ymd_His');
|
||||||
$filename = "nexus_backup_v" . self::VERSION . "_{$timestamp}.tar.gz";
|
$currentVer = self::getAppVersion();
|
||||||
|
$filename = "nexus_backup_v{$currentVer}_{$timestamp}.tar.gz";
|
||||||
$localArchivePath = self::BACKUP_DIR . '/' . $filename;
|
$localArchivePath = self::BACKUP_DIR . '/' . $filename;
|
||||||
|
|
||||||
// 2. Préparation du dossier de staging
|
// 2. Préparation du dossier de staging
|
||||||
@@ -268,7 +284,7 @@ class BackupManager
|
|||||||
|
|
||||||
// G. Création du Manifeste
|
// G. Création du Manifeste
|
||||||
$manifest = [
|
$manifest = [
|
||||||
'nexus_version' => self::VERSION,
|
'nexus_version' => $currentVer,
|
||||||
'created_at' => date('c'),
|
'created_at' => date('c'),
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'filename' => $filename,
|
'filename' => $filename,
|
||||||
@@ -360,6 +376,14 @@ class BackupManager
|
|||||||
// Tenter de lire le manifest depuis l'archive sans l'extraire entièrement
|
// Tenter de lire le manifest depuis l'archive sans l'extraire entièrement
|
||||||
$manifest = self::readManifestFromTar($file);
|
$manifest = self::readManifestFromTar($file);
|
||||||
|
|
||||||
|
$archiveVer = $manifest['nexus_version'] ?? null;
|
||||||
|
if (!$archiveVer && preg_match('/_v([0-9]+\.[0-9]+(?:\.[0-9]+)?)/', $name, $vm)) {
|
||||||
|
$archiveVer = $vm[1];
|
||||||
|
}
|
||||||
|
if (!$archiveVer) {
|
||||||
|
$archiveVer = self::getAppVersion();
|
||||||
|
}
|
||||||
|
|
||||||
$backups[] = [
|
$backups[] = [
|
||||||
'filename' => $name,
|
'filename' => $name,
|
||||||
'storage_type' => 'local',
|
'storage_type' => 'local',
|
||||||
@@ -367,7 +391,7 @@ class BackupManager
|
|||||||
'size_formatted' => self::formatBytes($size),
|
'size_formatted' => self::formatBytes($size),
|
||||||
'timestamp' => $mtime,
|
'timestamp' => $mtime,
|
||||||
'date_formatted' => date('d/m/Y H:i:s', $mtime),
|
'date_formatted' => date('d/m/Y H:i:s', $mtime),
|
||||||
'version' => $manifest['nexus_version'] ?? self::VERSION,
|
'version' => $archiveVer,
|
||||||
'source' => $manifest['source'] ?? 'local',
|
'source' => $manifest['source'] ?? 'local',
|
||||||
'is_local' => true,
|
'is_local' => true,
|
||||||
];
|
];
|
||||||
@@ -807,6 +831,13 @@ class BackupManager
|
|||||||
$name = basename($fullPath);
|
$name = basename($fullPath);
|
||||||
|
|
||||||
if (str_ends_with($name, '.tar.gz')) {
|
if (str_ends_with($name, '.tar.gz')) {
|
||||||
|
$remoteVer = null;
|
||||||
|
if (preg_match('/_v([0-9]+\.[0-9]+(?:\.[0-9]+)?)/', $name, $vm)) {
|
||||||
|
$remoteVer = $vm[1];
|
||||||
|
}
|
||||||
|
if (!$remoteVer) {
|
||||||
|
$remoteVer = self::getAppVersion();
|
||||||
|
}
|
||||||
$results[] = [
|
$results[] = [
|
||||||
'filename' => $name,
|
'filename' => $name,
|
||||||
'storage_type' => 'ssh',
|
'storage_type' => 'ssh',
|
||||||
@@ -814,7 +845,7 @@ class BackupManager
|
|||||||
'size_formatted' => self::formatBytes($size),
|
'size_formatted' => self::formatBytes($size),
|
||||||
'timestamp' => $timestamp > 0 ? $timestamp : time(),
|
'timestamp' => $timestamp > 0 ? $timestamp : time(),
|
||||||
'date_formatted' => date('d/m/Y H:i:s', $timestamp > 0 ? $timestamp : time()),
|
'date_formatted' => date('d/m/Y H:i:s', $timestamp > 0 ? $timestamp : time()),
|
||||||
'version' => self::VERSION,
|
'version' => $remoteVer,
|
||||||
'source' => 'distant (SSH)',
|
'source' => 'distant (SSH)',
|
||||||
'is_local' => false,
|
'is_local' => false,
|
||||||
];
|
];
|
||||||
|
|||||||
+6
-7
@@ -1,16 +1,15 @@
|
|||||||
{
|
{
|
||||||
"version": "1.6.1",
|
"version": "1.6.2",
|
||||||
"codename": "Helios",
|
"codename": "Helios",
|
||||||
"release_date": "2026-11-05",
|
"release_date": "2026-11-05",
|
||||||
"min_php_version": "8.2",
|
"min_php_version": "8.2",
|
||||||
"changelog": [
|
"changelog": [
|
||||||
|
"Sauvegarde & Restauration : versionnage dynamique automatique basé sur la version installée (résolution du tag figé v1.2.0)",
|
||||||
|
"Mises à jour système OTA : déclenchement garanti d'une sauvegarde Disaster Recovery complète pré-mise à jour (visible et restaurable dans l'interface)",
|
||||||
|
"Interface Sauvegardes : nouveau badge identifiant la source (Pré-MàJ, Auto, Manuel)",
|
||||||
"Identité visuelle officielle : intégration du nouveau logo NexusPBX 3D haute définition épuré et du favicon",
|
"Identité visuelle officielle : intégration du nouveau logo NexusPBX 3D haute définition épuré et du favicon",
|
||||||
"Nouveau slogan télécom : « Supervision & Téléphonie IP • Powered by Asterisk »",
|
"Nouveau slogan télécom : « Supervision & Téléphonie IP • Powered by Asterisk »",
|
||||||
"Amélioration des scripts d'installation et de mise à jour : initialisation automatique des permissions et ACLs du module CDR (Master.csv)",
|
"Module Journal d'Appels & CDR avec filtres et export CSV",
|
||||||
"Nouveau module Journal d'Appels & CDR : traçabilité complète des flux entrants, sortants, internes et services avec détection automatique des Trunks SIP et postes associés",
|
"Support universel TLSv1.2/TLSv1.3 et suppression CertificateRequest pour postes Yealink"
|
||||||
"Filtres multicritères CDR en temps réel (période, direction, statut décroché/manqué, recherche textuelle) et export CSV Excel",
|
|
||||||
"Optimisation TLS SIP PJSIP : négociation universelle TLSv1.2/TLSv1.3 (method=sslv23)",
|
|
||||||
"Suppression de CertificateRequest en mode TLS standard pour compatibilité totale avec les téléphones IP Yealink, Fanvil et Grandstream",
|
|
||||||
"Plafond d'expiration d'enregistrement SIP standard (maximum_expiration = 300s, default = 120s) garantissant la reconnexion automatique rapide de tous les postes"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user