feat(ucp): v2.6.0 provisionnement XML Acrobits GroundWire par poste
This commit is contained in:
1 parent
135a6267db
commit
28efb2d6bc
10 files changed
+359
-30
No files matched your search
+2
-2
@@ -114,7 +114,7 @@ try {
|
||||
'company_logo' => (string)($branding['company_logo'] ?? ''),
|
||||
],
|
||||
'csrf_token' => UcpAuth::getCsrfToken(),
|
||||
'extensions' => UcpManager::getExtensionsState($db, $allowedExts),
|
||||
'extensions' => UcpManager::getExtensionsState($db, $allowedExts, $ucpUserId),
|
||||
'forward_targets' => UcpManager::getForwardTargets($db),
|
||||
'feature_codes' => UcpManager::getFeatureCodesForUser($db),
|
||||
],
|
||||
@@ -130,7 +130,7 @@ try {
|
||||
]);
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'extensions' => UcpManager::getExtensionsState($db, $allowedExts),
|
||||
'extensions' => UcpManager::getExtensionsState($db, $allowedExts, $ucpUserId),
|
||||
'message' => "Paramètres d'appel du poste {$ext} appliqués en direct.",
|
||||
]);
|
||||
break;
|
||||
|
||||
@@ -351,6 +351,44 @@ function renderExtensionsGrid() {
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
${(Number(ext.groundwire_enabled) === 1 && ext.groundwire_deeplink_url && ext.groundwire_xml_url) ? `
|
||||
<div class="pt-3 border-t border-slate-100">
|
||||
<div class="rounded-xl bg-slate-50/80 border border-slate-200/80 p-3 space-y-2.5">
|
||||
<div class="flex flex-wrap items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-1.5 text-xs font-bold text-slate-700">
|
||||
<span>📱</span>
|
||||
<span>GroundWire Mobile</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-[11px] font-medium text-slate-500">
|
||||
<a href="https://apps.apple.com/fr/app/groundwire-voip-sip-softphone/id378503081"
|
||||
target="_blank" rel="noopener noreferrer"
|
||||
class="hover:text-indigo-600 transition underline decoration-slate-300 underline-offset-2">
|
||||
iOS
|
||||
</a>
|
||||
<span class="text-slate-300">•</span>
|
||||
<a href="https://play.google.com/store/apps/details?id=cz.acrobits.softphone.aliengroundwire"
|
||||
target="_blank" rel="noopener noreferrer"
|
||||
class="hover:text-indigo-600 transition underline decoration-slate-300 underline-offset-2">
|
||||
Android
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<a href="${escapeHtml(ext.groundwire_deeplink_url)}"
|
||||
class="inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-xl bg-indigo-50 hover:bg-indigo-100 text-indigo-700 border border-indigo-200 text-xs font-semibold transition flex-1 sm:flex-initial">
|
||||
<span>⚡</span>
|
||||
<span>Configurer dans Groundwire</span>
|
||||
</a>
|
||||
<a href="${escapeHtml(ext.groundwire_xml_url)}"
|
||||
download="groundwire-${escapeHtml(ext.extension)}.xml"
|
||||
class="inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-xl bg-white hover:bg-slate-100 text-slate-700 border border-slate-200 text-xs font-medium transition">
|
||||
<span>⬇</span>
|
||||
<span>Télécharger le XML</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../src/Database.php';
|
||||
require_once __DIR__ . '/../src/FirewallManager.php';
|
||||
require_once __DIR__ . '/../src/AmiClient.php';
|
||||
require_once __DIR__ . '/../src/ConfigGenerator.php';
|
||||
require_once __DIR__ . '/../src/CdrManager.php';
|
||||
require_once __DIR__ . '/../src/PhonebookManager.php';
|
||||
require_once __DIR__ . '/../src/UcpAuth.php';
|
||||
require_once __DIR__ . '/../src/UcpManager.php';
|
||||
|
||||
use App\Database;
|
||||
use App\UcpAuth;
|
||||
use App\UcpManager;
|
||||
|
||||
try {
|
||||
$db = Database::getConnection();
|
||||
|
||||
if (!UcpAuth::isUcpEnabled($db)) {
|
||||
http_response_code(503);
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo "Le portail utilisateur UCP est actuellement désactivé.";
|
||||
exit;
|
||||
}
|
||||
|
||||
$extId = (int)($_GET['ext_id'] ?? $_GET['line_id'] ?? 0);
|
||||
$uid = (int)($_GET['uid'] ?? 0);
|
||||
$token = trim((string)($_GET['token'] ?? ''));
|
||||
|
||||
$authorized = false;
|
||||
|
||||
// 1. Authentification sans session par signature HMAC GET (utilisée par l'application GroundWire / Acrobits)
|
||||
if ($token !== '' && $extId > 0 && $uid > 0) {
|
||||
if (UcpManager::verifyGroundwireToken($db, $extId, $uid, $token)) {
|
||||
$allowed = UcpAuth::getAllowedExtensions($db, $uid);
|
||||
foreach ($allowed as $row) {
|
||||
if ((int)$row['id'] === $extId && (int)($row['groundwire_enabled'] ?? 0) === 1) {
|
||||
$authorized = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Sinon : utilisateur UCP connecté en session et propriétaire de l'extension
|
||||
if (!$authorized && $extId > 0) {
|
||||
UcpAuth::startSession();
|
||||
$sessionUser = UcpAuth::getCurrentUser($db);
|
||||
if ($sessionUser !== null) {
|
||||
$allowed = UcpAuth::getAllowedExtensions($db, (int)$sessionUser['id']);
|
||||
foreach ($allowed as $row) {
|
||||
if ((int)$row['id'] === $extId && (int)($row['groundwire_enabled'] ?? 0) === 1) {
|
||||
$authorized = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$authorized) {
|
||||
http_response_code(403);
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo "Accès refusé ou lien de provisionnement invalide.";
|
||||
exit;
|
||||
}
|
||||
|
||||
$bundle = UcpManager::buildGroundwireXml($db, $extId);
|
||||
$xmlContent = $bundle['xml'];
|
||||
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
header('Content-Type: application/xml; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename="' . $bundle['filename'] . '"');
|
||||
header('Content-Length: ' . strlen($xmlContent));
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
|
||||
echo $xmlContent;
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
http_response_code(404);
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo $e->getMessage();
|
||||
} catch (\Throwable $e) {
|
||||
http_response_code(500);
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo "Erreur interne lors de la génération du profil XML.";
|
||||
}
|
||||
Reference in new issue
Block a user