// ============================================ // SYSTÈME DE VALIDATION DE LICENCE - VERSION 2.0 // Avec support fichier .lic // ============================================ const LICENSE_API_URL = window.location.protocol + '//' + window.location.hostname + ':9999'; // État global de la licence let currentLicense = null; let currentHostname = null; // ============================================ // INITIALISATION // ============================================ async function initializeLicense() { console.log("Initializing license system v2.0..."); try { // Récupérer le statut de la licence depuis le serveur const response = await fetch(`${LICENSE_API_URL}/license/status`); const data = await response.json(); console.log("License status:", data); currentHostname = data.hostname; if (data.status === 'valid' && data.license) { // Licence valide currentLicense = data.license; displayLicenseInfo(data.license); hideLicenseModal(); } else { // Pas de licence ou licence invalide showLicenseModal(data.error, data.error_code, data.hostname); } } catch (error) { console.error("Error checking license:", error); // En cas d'erreur réseau, afficher le modal showLicenseModal("Impossible de vérifier la licence. Le serveur est-il démarré?", "CONNECTION_ERROR"); } } // ============================================ // AFFICHAGE DU BADGE DE LICENCE // ============================================ function displayLicenseInfo(license) { console.log("Displaying license info:", license); const container = document.getElementById('license-badge-container'); if (!container) { console.error("license-badge-container not found"); return; } // Supprimer l'ancien badge s'il existe const oldBadge = document.getElementById('license-badge'); if (oldBadge) oldBadge.remove(); // Créer le badge const badge = document.createElement('div'); badge.id = 'license-badge'; // Déterminer le style selon le type et les jours restants let badgeStyle = ''; let badgeText = ''; let badgeIcon = '✓'; const daysRemaining = license.days_remaining || 0; const licenseType = license.type_name || license.type || 'Unknown'; if (daysRemaining <= 0) { // Expirée badgeStyle = 'background: linear-gradient(135deg, #f44336 0%, #da190b 100%);'; badgeText = '⚠ Licence expirée'; badgeIcon = '⚠'; } else if (daysRemaining <= 7) { // Expire bientôt badgeStyle = 'background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);'; badgeText = `⚠ ${licenseType} - ${daysRemaining}j restants`; badgeIcon = '⚠'; } else if (license.type === 'trial') { // Essai badgeStyle = 'background: linear-gradient(135deg, #9c27b0 0%, #7b1fa2 100%);'; badgeText = `⏱ Essai - ${daysRemaining}j restants`; badgeIcon = '⏱'; } else { // Licence normale valide badgeStyle = 'background: linear-gradient(135deg, #4caf50 0%, #2e7d32 100%);'; badgeText = `✓ ${licenseType}`; badgeIcon = '✓'; } badge.style.cssText = ` ${badgeStyle} color: white; padding: 10px 16px; border-radius: 8px; font-size: 12px; font-weight: 600; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); cursor: pointer; transition: all 0.3s ease; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; text-align: center; display: flex; align-items: center; gap: 8px; `; badge.innerHTML = ` ${badgeIcon} ${badgeText} `; // Click pour voir les détails badge.onclick = function() { showLicenseDetails(license); }; // Hover effect badge.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-2px)'; this.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.3)'; }); badge.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; this.style.boxShadow = '0 4px 15px rgba(0, 0, 0, 0.2)'; }); container.appendChild(badge); } // ============================================ // MODAL DE DÉTAILS DE LICENCE // ============================================ function showLicenseDetails(license) { const modal = document.createElement('div'); modal.id = 'license-details-modal'; modal.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); display: flex; align-items: center; justify-content: center; z-index: 10000; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; `; const features = (license.features || []).map(f => `${f}`).join(''); const limits = license.limits || {}; const maxApps = limits.max_apps === -1 ? 'Illimité' : limits.max_apps; const maxPushes = limits.max_pushes_per_day === -1 ? 'Illimité' : limits.max_pushes_per_day + '/jour'; modal.innerHTML = `

📋 Détails de la licence

Type
${license.type_name || license.type}
ID
${license.license_id}
Expire
${license.expires}
Jours restants
${license.days_remaining}
Client
${license.customer?.name || 'N/A'} (${license.customer?.email || 'N/A'})
Hostname
${license.hostname || currentHostname}
Limites
Apps: ${maxApps} | Pushes: ${maxPushes}
Fonctionnalités
${features || 'Aucune'}
`; document.body.appendChild(modal); } // ============================================ // MODAL D'UPLOAD DE LICENCE // ============================================ function showLicenseModal(error = null, errorCode = null, hostname = null) { console.log("Showing license modal", { error, errorCode, hostname }); // Supprimer l'ancien modal s'il existe hideLicenseModal(); const detailsModal = document.getElementById('license-details-modal'); if (detailsModal) detailsModal.remove(); const modal = document.createElement('div'); modal.id = 'license-modal'; modal.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); display: flex; align-items: center; justify-content: center; z-index: 10000; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; `; // Message d'erreur si présent let errorHtml = ''; if (error) { let errorStyle = 'background: #ffebee; color: #c62828; border-left: 4px solid #f44336;'; if (errorCode === 'NO_LICENSE') { errorStyle = 'background: #fff3e0; color: #e65100; border-left: 4px solid #ff9800;'; } errorHtml = `
${error}
`; } modal.innerHTML = `

🔐 Git Pusher

Activation de licence requise

${errorHtml}

📋 Hostname Splunk:
${hostname || 'Chargement...'}

Communiquez ce hostname pour obtenir votre licence.

📁
Glissez votre fichier .lic ici
ou cliquez pour sélectionner
Besoin d'une licence ? Contactez-nous
${currentLicense ? `
` : ''}
`; document.body.appendChild(modal); // Récupérer le hostname si pas fourni if (!hostname) { fetch(`${LICENSE_API_URL}/license/hostname`) .then(r => r.json()) .then(d => { const codeEl = modal.querySelector('code'); if (codeEl) codeEl.textContent = d.hostname || 'Inconnu'; currentHostname = d.hostname; }) .catch(() => {}); } } function hideLicenseModal() { const modal = document.getElementById('license-modal'); if (modal) modal.remove(); } // ============================================ // GESTION DU FICHIER // ============================================ let selectedLicenseContent = null; function handleDragOver(event) { event.preventDefault(); event.stopPropagation(); event.currentTarget.style.borderColor = '#667eea'; event.currentTarget.style.background = '#f0f4ff'; } function handleDragLeave(event) { event.preventDefault(); event.stopPropagation(); event.currentTarget.style.borderColor = '#ccc'; event.currentTarget.style.background = '#fafafa'; } function handleDrop(event) { event.preventDefault(); event.stopPropagation(); event.currentTarget.style.borderColor = '#ccc'; event.currentTarget.style.background = '#fafafa'; const files = event.dataTransfer.files; if (files.length > 0) { processFile(files[0]); } } function handleFileSelect(event) { const files = event.target.files; if (files.length > 0) { processFile(files[0]); } } function processFile(file) { console.log("Processing file:", file.name); if (!file.name.endsWith('.lic')) { showLicenseMessage('Veuillez sélectionner un fichier .lic', 'error'); return; } const reader = new FileReader(); reader.onload = function(e) { selectedLicenseContent = e.target.result; // Afficher le nom du fichier document.getElementById('selected-file-info').style.display = 'block'; document.getElementById('selected-file-name').textContent = '📄 ' + file.name; // Activer le bouton const btn = document.getElementById('activate-btn'); btn.disabled = false; btn.style.opacity = '1'; btn.style.cursor = 'pointer'; showLicenseMessage('Fichier prêt à être activé', 'info'); }; reader.onerror = function() { showLicenseMessage('Erreur de lecture du fichier', 'error'); }; reader.readAsText(file); } function clearSelectedFile() { selectedLicenseContent = null; document.getElementById('selected-file-info').style.display = 'none'; document.getElementById('license-file-input').value = ''; const btn = document.getElementById('activate-btn'); btn.disabled = true; btn.style.opacity = '0.5'; const msgEl = document.getElementById('license-message'); msgEl.style.display = 'none'; } // ============================================ // UPLOAD ET ACTIVATION // ============================================ async function uploadLicense() { if (!selectedLicenseContent) { showLicenseMessage('Veuillez sélectionner un fichier de licence', 'error'); return; } showLicenseMessage('⏳ Validation en cours...', 'info'); const btn = document.getElementById('activate-btn'); btn.disabled = true; btn.textContent = 'Validation...'; try { const response = await fetch(`${LICENSE_API_URL}/license/upload`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ license_content: selectedLicenseContent }) }); const result = await response.json(); console.log("Upload result:", result); if (result.success) { showLicenseMessage('✓ Licence activée avec succès!', 'success'); currentLicense = result.license_info; setTimeout(() => { hideLicenseModal(); displayLicenseInfo(result.license_info); }, 1500); } else { showLicenseMessage(result.error || 'Erreur d\'activation', 'error'); btn.disabled = false; btn.textContent = 'Activer la licence'; } } catch (error) { console.error("Upload error:", error); showLicenseMessage('Erreur de connexion au serveur', 'error'); btn.disabled = false; btn.textContent = 'Activer la licence'; } } // ============================================ // UTILITAIRES // ============================================ function showLicenseMessage(message, type) { const msgEl = document.getElementById('license-message'); if (!msgEl) return; msgEl.style.display = 'block'; msgEl.textContent = message; switch (type) { case 'success': msgEl.style.background = '#e8f5e9'; msgEl.style.color = '#2e7d32'; msgEl.style.border = '1px solid #a5d6a7'; break; case 'error': msgEl.style.background = '#ffebee'; msgEl.style.color = '#c62828'; msgEl.style.border = '1px solid #ef9a9a'; break; case 'info': msgEl.style.background = '#e3f2fd'; msgEl.style.color = '#1565c0'; msgEl.style.border = '1px solid #90caf9'; break; } } function showContactInfo() { alert(`Pour obtenir une licence Git Pusher: 1. Copiez votre hostname Splunk affiché ci-dessus 2. Contactez-nous avec: - Votre hostname - Votre email - Le type de licence souhaité Email: support@gitpusher.com Site: https://gitpusher.com`); } // ============================================ // VÉRIFICATION AVANT PUSH // ============================================ async function checkLicenseBeforePush() { try { const response = await fetch(`${LICENSE_API_URL}/license/status`); const data = await response.json(); if (data.status !== 'valid') { alert('⚠️ ' + (data.error || 'Licence invalide ou absente')); showLicenseModal(data.error, data.error_code, data.hostname); return false; } // Vérifier les limites const limits = data.license?.limits || {}; const usage = data.usage || {}; if (limits.max_pushes_per_day > 0 && usage.pushes_today >= limits.max_pushes_per_day) { alert(`⚠️ Limite quotidienne atteinte (${limits.max_pushes_per_day} pushes/jour)`); return false; } return true; } catch (error) { console.error("License check error:", error); alert('⚠️ Impossible de vérifier la licence'); return false; } } // ============================================ // EXPORT POUR UTILISATION EXTERNE // ============================================ window.LicenseManager = { init: initializeLicense, check: checkLicenseBeforePush, showModal: showLicenseModal, getLicense: () => currentLicense, getHostname: () => currentHostname };