From 5e506bf4fb873bd427ab9c83d4897a01ecb00449 Mon Sep 17 00:00:00 2001 From: Splunk Git Pusher Date: Fri, 6 Mar 2026 15:48:16 +0100 Subject: [PATCH] For EDF Pushed by: admin License: TA9O64YS7EPT (Professional) Timestamp: 2026-03-06T15:48:16.563066 --- .../appserver/static/appIcon.png | Bin 0 -> 847 bytes .../appserver/static/appIcon_2x.png | Bin 0 -> 1450 bytes .../appserver/static/git_pusher.js | 26 +- .../appserver/static/git_pusher.js_old2 | 1055 +++++++++++++++++ .../appserver/static/license_validation.js | 75 +- .../static/license_validation.js_old2 | 972 +++++++++++++++ apps/pusher_app_prem/bin/git_pusher.pid | 2 +- 7 files changed, 2077 insertions(+), 53 deletions(-) create mode 100644 apps/pusher_app_prem/appserver/static/appIcon.png create mode 100644 apps/pusher_app_prem/appserver/static/appIcon_2x.png mode change 100755 => 100644 apps/pusher_app_prem/appserver/static/git_pusher.js create mode 100755 apps/pusher_app_prem/appserver/static/git_pusher.js_old2 mode change 100755 => 100644 apps/pusher_app_prem/appserver/static/license_validation.js create mode 100755 apps/pusher_app_prem/appserver/static/license_validation.js_old2 mode change 100755 => 100644 apps/pusher_app_prem/bin/git_pusher.pid diff --git a/apps/pusher_app_prem/appserver/static/appIcon.png b/apps/pusher_app_prem/appserver/static/appIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..acc6b4b4ee71ee8a092afbd558020aee661d23aa GIT binary patch literal 847 zcmV-V1F-ywP)A4XvA_kR2m0>cGd> z@M;xh@nG8)39nYs!L}{J+9sCHnvR|5dv8e@24SG(1(#5Gt(p$Dz9eSXy2Yi+zj5!5 zEg}q}Aj>eb@LDx>H*XRa3$hG%^Cn@j)`IQb$oH427Hsb}otI}K_xTq95;Eo=U8DdM zuW3)|n+)FECdO3=P~J#9O&bINJWU%!+pe{dl?8~k1&Zvo1sGXb$i70Jt1%La)=(BB zAtMy6p)BUAl!iJ;KFf^Yxw1||PwT1n+ER7eIKQ+I0KjwkS=QcM=X$*ul>%vxcK}H1 z*_Vq9<`V#5=+cw_=G|WX`Y}`=%{i(2>rI00`_ORR1haK0I_%!RIY1 Zk3addLdZtJ)+qo0002ovPDHLkV1i6xi>Uwr literal 0 HcmV?d00001 diff --git a/apps/pusher_app_prem/appserver/static/appIcon_2x.png b/apps/pusher_app_prem/appserver/static/appIcon_2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0c55cd3f4f5555776977833448ddafe68cb14215 GIT binary patch literal 1450 zcmV;b1y%ZqP)^NVr>&~;8H0E%waqedpzr#HL?HF)6Bf}d%yYK^Ba5o zC=iN1{~$+N)-Ev@c2Zi)s474Y-rsaE)QTC|CCflIkv{kLmIWge6Rs6yAqj{+`&Ze( z;lzwSUcy5Z5PkN~vV+5k8QopPqy$jsnLo-F4yT#O6Fiq9K%E1>mpvR#Gh zlzs0+N3#bxLKfOwML85uFtJ_|7xh*H0IamxQA2EWWDfvwIEC?SzA_zRg>Vkl zKgyqfbN3%UJ?gEtY?wLbQDZc`R}zl!I+$3;Xn3zBcDblr4o(PCFy!L(w3kjlmr;|? zL30p^$l98mdOianf0WPbh#?k^>?6Vxj_f09uea;RMgZ(lX^7bk2ZG@RY)r_i;tAXA zJ(X3211Aiz@c1))U%7RT7>vT}!hCFb^XzlnLNV&C=0DBEJf;v1Co}t?IK)zy4-8v5 zyrdw=#hYoL>_Rcc92^FK)J*+wAAM&?BYa(wgdrwVJxFH!_0iuA0mvWC8s|pHyg5j5 zq4?g3Z->lWAZ{C}(}iZ+NS&z*SjRn!5y`G0W_E}@a>S5Mu=SW@1 z1;MrXjR=G7wG_~$k6vWf{k!Pu_jnlnU{yZwePK*`xx836Ef+$`xl zmnM}irBJ$FI<4ofMho?ca<^S429&(=8VjfWhGgf}fpwC_ZUC zznmnrlw7)=#e6Lp8puNsN$26TWHi6P%|R(VS~)p$LH8WwYhI)$t{rA3<{L#<)4t|K z&FddYSv>y$27ROGYg!P6;A>jY?m79;KNT;ktA8qPiw98v;CuTE>u-$;jdut5^V3r? zTWr`o|2VYCMo0f&?DXVC0AP= 2) { + parts[0] = parts[0] + '-api'; + return protocol + '//' + parts.join('.'); + } + + // Dernier fallback : même hostname avec port 9999 return protocol + '//' + hostname + ':9999'; } @@ -79,7 +77,7 @@ const GIT_PUSHER_CONFIG = { // Configuration SH Deployer (peut être modifiée via l'interface) let SH_DEPLOYER_CONFIG = { enabled: false, - host: '10.10.40.14', + host: '', port: 9998, token: '' }; @@ -1052,4 +1050,4 @@ window.GitPusher = { checkServer: checkServerHealth, checkDeployer: checkDeployerHealth, version: GIT_PUSHER_CONFIG.version -}; \ No newline at end of file +}; diff --git a/apps/pusher_app_prem/appserver/static/git_pusher.js_old2 b/apps/pusher_app_prem/appserver/static/git_pusher.js_old2 new file mode 100755 index 00000000..74e7881c --- /dev/null +++ b/apps/pusher_app_prem/appserver/static/git_pusher.js_old2 @@ -0,0 +1,1055 @@ +// ============================================ +// GIT PUSHER - MAIN JAVASCRIPT +// Version 2.1 avec déploiement vers SH Cluster +// ============================================ + +// Configuration par défaut +const DEFAULT_CONFIG = { + api: { + url: '', + port: 9999, + useProxy: true + }, + deployer: { + enabled: false, + host: '', + port: 9998, + token: '', + useSSL: true + } +}; + +// Charger la configuration +function loadAppConfig() { + try { + const stored = localStorage.getItem('git_pusher_config'); + if (stored) { + return JSON.parse(stored); + } + } catch (e) { + console.warn('Erreur chargement config localStorage:', e); + } + return DEFAULT_CONFIG; +} + +// Déterminer l'URL du serveur API +function getServerUrl() { + const config = loadAppConfig(); + const hostname = window.location.hostname; + const protocol = window.location.protocol; + + // Si une URL est configurée, l'utiliser + if (config.api && config.api.url) { + let url = config.api.url; + // Ajouter le port si pas de proxy + if (!config.api.useProxy && config.api.port) { + url = url.replace(/\/$/, '') + ':' + config.api.port; + } + return url; + } + + // Auto-détection basée sur le hostname + // Si accès via le domaine Splunk principal, utiliser le domaine API + if (hostname === 'myprivspldev.jp-engineering.fr') { + return protocol + '//myprivspldev-api.jp-engineering.fr'; + } + + // Si déjà sur le domaine API + if (hostname === 'myprivspldev-api.jp-engineering.fr') { + return protocol + '//' + hostname; + } + + // Si c'est une IP ou localhost, ajouter le port 9999 + if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname) || hostname === 'localhost') { + return protocol + '//' + hostname + ':9999'; + } + + // Par défaut, ajouter le port 9999 + return protocol + '//' + hostname + ':9999'; +} + +// Configuration +const GIT_PUSHER_CONFIG = { + serverUrl: getServerUrl(), + credentialsKey: 'git_pusher_credentials', + deployerConfigKey: 'git_pusher_deployer_config', + version: '2.1.0' +}; + +// Configuration SH Deployer (peut être modifiée via l'interface) +let SH_DEPLOYER_CONFIG = { + enabled: false, + host: '10.10.40.14', + port: 9998, + token: '' +}; + +// État global +let selectedApps = []; +let selectedShClusterApps = []; // Apps sélectionnées pour le SH Cluster +let isProcessing = false; +let deployerAvailable = false; + +// ============================================ +// INITIALISATION +// ============================================ + +require([ + 'jquery', + 'splunkjs/mvc', + 'splunkjs/mvc/searchmanager', + 'splunkjs/mvc/simplexml/ready!' +], function($, mvc, SearchManager) { + + console.log("Git Pusher v2.1 initializing..."); + + // Initialiser le système de licence + if (typeof initializeLicense === 'function') { + initializeLicense(); + } else { + console.warn("License system not loaded"); + } + + // Charger les credentials sauvegardés + loadSavedCredentials(); + + // Charger la config du deployer + loadDeployerConfig(); + + // Vérifier la disponibilité du SH Deployer + checkDeployerHealth(); + + // Récupérer les résultats de recherche pour les apps + const searchManager = mvc.Components.get('dsearch'); + + if (searchManager) { + searchManager.on('search:done', function() { + const results = searchManager.data('results'); + if (results) { + results.on('data', function() { + const rows = results.data().rows; + const fields = results.data().fields; + renderAppsList(rows, fields); + }); + } + }); + } + + // Exposer les fonctions globalement + window.pushDashboards = pushDashboards; + window.resetForm = resetForm; + window.toggleSelectAll = toggleSelectAll; + window.toggleShClusterAllApps = toggleShClusterAllApps; + window.updateSelectedShClusterApps = updateSelectedShClusterApps; + + // Attacher les événements pour la section SH Cluster + setTimeout(function() { + // Checkbox "Deploy to SH Cluster" + const deployCheckbox = document.getElementById('deploy-to-shcluster'); + if (deployCheckbox) { + deployCheckbox.addEventListener('change', function() { + toggleDeployerOptions(); + }); + } + + // Checkbox "All apps" + const allAppsCheckbox = document.getElementById('shcluster-all-apps'); + if (allAppsCheckbox) { + allAppsCheckbox.addEventListener('change', function() { + toggleShClusterAllApps(); + }); + } + + // Bouton configure + const configBtn = document.getElementById('deployer-config-btn'); + if (configBtn) { + configBtn.addEventListener('click', function() { + showDeployerConfigModal(); + }); + } + }, 500); +}); + +// Afficher/masquer les options du deployer +function toggleDeployerOptions() { + const checkbox = document.getElementById('deploy-to-shcluster'); + const appsSection = document.getElementById('deployer-apps-section'); + const authSection = document.getElementById('deployer-auth'); + + if (checkbox && checkbox.checked) { + if (appsSection) appsSection.classList.add('visible'); + if (authSection) authSection.classList.add('visible'); + } else { + if (appsSection) appsSection.classList.remove('visible'); + if (authSection) authSection.classList.remove('visible'); + } +} + +// ============================================ +// RENDU DE LA LISTE DES APPLICATIONS +// ============================================ + +function renderAppsList(rows, fields) { + const container = document.getElementById('dashboard-list'); + if (!container) return; + + // Trouver les index des colonnes + const nameIdx = fields.indexOf('name'); + const labelIdx = fields.indexOf('label'); + const descIdx = fields.indexOf('description'); + + // Générer le HTML + let html = ` +
+
+ + +
+ ${rows.length} apps +
+ `; + + rows.forEach((row, index) => { + const name = row[nameIdx] || ''; + const label = row[labelIdx] || name; + const desc = row[descIdx] || ''; + + // Ignorer certaines apps système + if (name.startsWith('splunk_') || name === 'learned' || name === 'launcher') { + return; + } + + html += ` +
+ + +
+ `; + }); + + container.innerHTML = html; + + console.log(`Rendered ${rows.length} applications`); +} + +// ============================================ +// GESTION DE LA SÉLECTION +// ============================================ + +function updateSelectedApps() { + const checkboxes = document.querySelectorAll('#dashboard-list input[type="checkbox"][data-app-id]'); + selectedApps = []; + + checkboxes.forEach(cb => { + if (cb.checked) { + selectedApps.push({ + id: cb.getAttribute('data-app-id'), + label: cb.getAttribute('data-app-label') + }); + } + }); + + // Mettre à jour le "Select All" + const selectAll = document.getElementById('select-all'); + if (selectAll) { + const allChecked = Array.from(checkboxes).every(cb => cb.checked); + const someChecked = Array.from(checkboxes).some(cb => cb.checked); + selectAll.checked = allChecked; + selectAll.indeterminate = someChecked && !allChecked; + } + + // Mettre à jour la liste des apps pour le SH Cluster + updateShClusterAppsList(); + + console.log(`Selected ${selectedApps.length} apps`); +} + +function updateShClusterAppsList() { + const container = document.getElementById('shcluster-apps-container'); + if (!container) return; + + if (selectedApps.length === 0) { + container.innerHTML = '

Select apps from the left panel first

'; + selectedShClusterApps = []; + return; + } + + // Sauvegarder l'état actuel des checkboxes + const currentState = {}; + const existingCheckboxes = container.querySelectorAll('input[type="checkbox"][data-app-id]'); + existingCheckboxes.forEach(cb => { + currentState[cb.getAttribute('data-app-id')] = cb.checked; + }); + + // Vérifier si la liste a changé (nouvelles apps ajoutées ou apps retirées) + const currentAppIds = Array.from(existingCheckboxes).map(cb => cb.getAttribute('data-app-id')); + const newAppIds = selectedApps.map(app => app.id); + const listChanged = currentAppIds.length !== newAppIds.length || + !currentAppIds.every(id => newAppIds.includes(id)); + + // Ne recréer le HTML que si la liste a changé + if (listChanged || existingCheckboxes.length === 0) { + let html = ''; + selectedApps.forEach((app, index) => { + // Préserver l'état si l'app existait, sinon cocher par défaut + const isChecked = currentState.hasOwnProperty(app.id) ? currentState[app.id] : true; + html += ` +
+ + +
+ `; + }); + + container.innerHTML = html; + } + + // Mettre à jour la liste des apps SH Cluster sélectionnées (sans recréer le HTML) + updateSelectedShClusterApps(); +} + +function updateSelectedShClusterApps() { + const allAppsCheckbox = document.getElementById('shcluster-all-apps'); + + if (allAppsCheckbox && allAppsCheckbox.checked) { + // Toutes les apps sélectionnées pour Git + selectedShClusterApps = [...selectedApps]; + } else { + // Seulement les apps cochées dans la liste SH Cluster + const checkboxes = document.querySelectorAll('#shcluster-apps-container input[type="checkbox"][data-app-id]'); + selectedShClusterApps = []; + + checkboxes.forEach(cb => { + if (cb.checked) { + selectedShClusterApps.push({ + id: cb.getAttribute('data-app-id'), + label: cb.getAttribute('data-app-label') + }); + } + }); + } + + console.log(`Selected ${selectedShClusterApps.length} apps for SH Cluster`); +} + +function toggleShClusterAllApps() { + const allAppsCheckbox = document.getElementById('shcluster-all-apps'); + const appsList = document.getElementById('shcluster-apps-list'); + + if (allAppsCheckbox && appsList) { + if (allAppsCheckbox.checked) { + // Masquer la liste et utiliser toutes les apps + appsList.style.display = 'none'; + selectedShClusterApps = [...selectedApps]; + console.log('SH Cluster: Using all selected apps'); + } else { + // Afficher la liste pour permettre la sélection manuelle + appsList.style.display = 'block'; + // Ne PAS appeler updateSelectedShClusterApps() ici + // L'utilisateur va faire sa sélection manuellement + // La liste garde son état actuel (tous cochés par défaut) + console.log('SH Cluster: Manual selection enabled'); + } + } +} + +function toggleSelectAll(checked) { + const checkboxes = document.querySelectorAll('#dashboard-list input[type="checkbox"][data-app-id]'); + checkboxes.forEach(cb => { + cb.checked = checked; + }); + updateSelectedApps(); +} + +// ============================================ +// PUSH VERS GIT +// ============================================ + +async function pushDashboards() { + console.log("Starting push process..."); + + // Vérifier si déjà en cours + if (isProcessing) { + console.log("Push already in progress"); + return; + } + + // Vérifier la licence AVANT tout + if (typeof checkLicenseBeforePush === 'function') { + const licenseOk = await checkLicenseBeforePush(); + if (!licenseOk) { + console.log("License check failed"); + return; + } + } + + // Récupérer les valeurs du formulaire + const gitUrl = document.getElementById('git-url')?.value?.trim(); + const gitBranch = document.getElementById('git-branch')?.value?.trim() || 'main'; + const gitToken = document.getElementById('git-token')?.value?.trim(); + const commitMessage = document.getElementById('commit-message')?.value?.trim(); + const saveCredentials = document.getElementById('save-credentials')?.checked; + + // Ne PAS rappeler updateSelectedApps() ici car cela réinitialiserait la liste SH Cluster + // La liste selectedApps est déjà à jour grâce aux événements onchange + + // Validation + if (!gitUrl) { + showMessage('error', 'Please enter a Git repository URL'); + return; + } + + if (!gitToken) { + showMessage('error', 'Please enter a Git token or password'); + return; + } + + if (!commitMessage) { + showMessage('error', 'Please enter a commit message'); + return; + } + + if (selectedApps.length === 0) { + showMessage('error', 'Please select at least one application to deploy'); + return; + } + + // Sauvegarder les credentials si demandé + if (saveCredentials) { + saveCredentialsToStorage(gitUrl, gitBranch, gitToken); + } + + // Vérifier si le déploiement vers SH Cluster est activé + const deployToSHCluster = document.getElementById('deploy-to-shcluster')?.checked || false; + const shAuthUser = document.getElementById('sh-auth-user')?.value?.trim() || ''; + const shAuthPass = document.getElementById('sh-auth-pass')?.value?.trim() || ''; + + // La liste selectedShClusterApps est déjà à jour via les événements onchange + // Ne pas rappeler updateSelectedShClusterApps() pour éviter de réinitialiser la sélection + + // Validation des apps SH Cluster si déploiement activé + if (deployToSHCluster && selectedShClusterApps.length === 0) { + showMessage('error', 'Please select at least one application to deploy to SH Cluster'); + return; + } + + // Démarrer le push + isProcessing = true; + showLoading(true, deployToSHCluster); + hideMessages(); + + try { + // Récupérer l'utilisateur courant + const currentUser = await getCurrentUser(); + + // Récupérer les infos de licence depuis le localStorage + const licenseInfo = getLicenseInfo ? getLicenseInfo() : null; + const licenseType = licenseInfo?.type_name || ''; + const licenseId = licenseInfo?.license_id || ''; + + // Construire les paramètres + const params = new URLSearchParams({ + git_url: gitUrl, + git_branch: gitBranch, + git_token: gitToken, + commit_message: commitMessage, + apps: JSON.stringify(selectedApps), + shcluster_apps: JSON.stringify(selectedShClusterApps), // Apps pour le SH Cluster + user: currentUser, + deploy_to_shcluster: deployToSHCluster.toString(), + deployer_host: SH_DEPLOYER_CONFIG.host, + deployer_token: SH_DEPLOYER_CONFIG.token, + license_type: licenseType, + license_id: licenseId + }); + + // Ajouter les credentials SH si fournis + if (shAuthUser) params.append('sh_auth_user', shAuthUser); + if (shAuthPass) params.append('sh_auth_pass', shAuthPass); + + console.log(`Pushing ${selectedApps.length} apps to Git${deployToSHCluster ? `, ${selectedShClusterApps.length} apps to SH Cluster` : ''}`); + + // Appeler le serveur + const response = await fetch(`${GIT_PUSHER_CONFIG.serverUrl}/push?${params.toString()}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + }); + + const result = await response.json(); + console.log("Push result:", result); + + if (result.status === 'success') { + // Incrémenter le compteur d'utilisation côté client + console.log("=== INCREMENT USAGE ==="); + console.log("typeof incrementUsage:", typeof incrementUsage); + console.log("typeof window.incrementUsage:", typeof window.incrementUsage); + + try { + if (typeof window.incrementUsage === 'function') { + const stats = window.incrementUsage(); + console.log("✓ Usage incremented successfully:", stats); + } else if (typeof incrementUsage === 'function') { + const stats = incrementUsage(); + console.log("✓ Usage incremented (local):", stats); + } else { + console.warn("✗ incrementUsage function not available"); + } + } catch (e) { + console.error("✗ Error incrementing usage:", e); + } + + let message = `✅ Successfully deployed ${result.apps_pushed || selectedApps.length} application(s) to Git!`; + + // Ajouter le statut du déploiement SH Cluster + if (deployToSHCluster && result.shcluster_deployment) { + if (result.shcluster_deployment.success) { + message += '\n🚀 SH Cluster deployment triggered successfully!'; + } else { + message += `\n⚠️ SH Cluster deployment failed: ${result.shcluster_deployment.message}`; + } + } + + showMessage('success', message); + + // Reset la sélection après succès + setTimeout(() => { + toggleSelectAll(false); + }, 2000); + } else if (result.error_code === 'LICENSE_ERROR') { + showMessage('error', `🔐 ${result.message}`); + + // Afficher le modal de licence + if (typeof showLicenseModal === 'function') { + showLicenseModal(result.message, result.error_code); + } + } else if (result.error_code === 'APP_LIMIT') { + showMessage('error', `📦 ${result.message}`); + } else { + showMessage('error', result.message || 'Unknown error occurred'); + } + + } catch (error) { + console.error("Push error:", error); + showMessage('error', `Connection error: ${error.message}. Is the Git Pusher server running?`); + } finally { + isProcessing = false; + showLoading(false); + } +} + +// ============================================ +// UTILITAIRES UI +// ============================================ + +function showLoading(show, deployToSHCluster = false) { + const loading = document.getElementById('loading'); + const pushBtn = document.getElementById('push-btn'); + const loadingText = document.querySelector('.loading-text'); + + if (loading) { + loading.classList.toggle('active', show); + } + + if (loadingText && show) { + if (deployToSHCluster) { + loadingText.textContent = 'Deploying to Git and SH Cluster... Please wait'; + } else { + loadingText.textContent = 'Deploying applications to Git... Please wait'; + } + } + + if (pushBtn) { + pushBtn.disabled = show; + if (show) { + pushBtn.textContent = deployToSHCluster ? '⏳ Deploying to Git + SH...' : '⏳ Deploying...'; + } else { + pushBtn.textContent = '✈️ Deploy to Git'; + } + } +} + +function showMessage(type, text) { + hideMessages(); + + const successMsg = document.getElementById('success-msg'); + const errorMsg = document.getElementById('error-msg'); + const successText = document.getElementById('success-text'); + const errorText = document.getElementById('error-text'); + + if (type === 'success' && successMsg && successText) { + successText.textContent = text; + successMsg.classList.add('active'); + + // Auto-hide après 5 secondes + setTimeout(() => { + successMsg.classList.remove('active'); + }, 5000); + } else if (type === 'error' && errorMsg && errorText) { + errorText.textContent = text; + errorMsg.classList.add('active'); + } +} + +function hideMessages() { + const successMsg = document.getElementById('success-msg'); + const errorMsg = document.getElementById('error-msg'); + + if (successMsg) successMsg.classList.remove('active'); + if (errorMsg) errorMsg.classList.remove('active'); +} + +function resetForm(clearCredentials = false) { + // Reset les champs + const commitMessage = document.getElementById('commit-message'); + if (commitMessage) commitMessage.value = ''; + + if (clearCredentials) { + const gitUrl = document.getElementById('git-url'); + const gitToken = document.getElementById('git-token'); + const saveCredentials = document.getElementById('save-credentials'); + + if (gitUrl) gitUrl.value = ''; + if (gitToken) gitToken.value = ''; + if (saveCredentials) saveCredentials.checked = false; + + // Supprimer les credentials sauvegardés + localStorage.removeItem(GIT_PUSHER_CONFIG.credentialsKey); + } + + // Reset la sélection + toggleSelectAll(false); + + // Cacher les messages + hideMessages(); + + console.log("Form reset" + (clearCredentials ? " (with credentials)" : "")); +} + +// ============================================ +// GESTION DES CREDENTIALS +// ============================================ + +function saveCredentialsToStorage(gitUrl, gitBranch, gitToken) { + try { + const credentials = { + gitUrl: gitUrl, + gitBranch: gitBranch, + // Note: En production, envisager une solution plus sécurisée + gitToken: btoa(gitToken), // Encodage basique (pas sécurisé, juste pour l'obfuscation) + savedAt: new Date().toISOString() + }; + + localStorage.setItem(GIT_PUSHER_CONFIG.credentialsKey, JSON.stringify(credentials)); + console.log("Credentials saved"); + } catch (error) { + console.error("Error saving credentials:", error); + } +} + +function loadSavedCredentials() { + try { + const saved = localStorage.getItem(GIT_PUSHER_CONFIG.credentialsKey); + if (!saved) return; + + const credentials = JSON.parse(saved); + + const gitUrl = document.getElementById('git-url'); + const gitBranch = document.getElementById('git-branch'); + const gitToken = document.getElementById('git-token'); + const saveCredentials = document.getElementById('save-credentials'); + + if (gitUrl && credentials.gitUrl) { + gitUrl.value = credentials.gitUrl; + } + + if (gitBranch && credentials.gitBranch) { + gitBranch.value = credentials.gitBranch; + } + + if (gitToken && credentials.gitToken) { + gitToken.value = atob(credentials.gitToken); + } + + if (saveCredentials) { + saveCredentials.checked = true; + } + + console.log("Credentials loaded from storage"); + } catch (error) { + console.error("Error loading credentials:", error); + } +} + +// ============================================ +// RÉCUPÉRATION DE L'UTILISATEUR SPLUNK +// ============================================ + +async function getCurrentUser() { + try { + const response = await fetch('/en-US/splunkd/__raw/services/authentication/current-context?output_mode=json'); + const data = await response.json(); + return data.entry?.[0]?.content?.username || 'unknown'; + } catch (error) { + console.error("Error getting current user:", error); + return 'unknown'; + } +} + +// ============================================ +// VÉRIFICATION DU SERVEUR +// ============================================ + +async function checkServerHealth() { + try { + const response = await fetch(`${GIT_PUSHER_CONFIG.serverUrl}/health`, { + method: 'GET', + timeout: 5000 + }); + const data = await response.json(); + return data.status === 'ok'; + } catch (error) { + console.error("Server health check failed:", error); + return false; + } +} + +// ============================================ +// SH DEPLOYER FUNCTIONS +// ============================================ + +async function checkDeployerHealth() { + try { + const response = await fetch(`${GIT_PUSHER_CONFIG.serverUrl}/deployer/health`, { + method: 'GET', + timeout: 5000 + }); + const data = await response.json(); + + deployerAvailable = data.status === 'ok'; + + // Mettre à jour l'UI + updateDeployerUI(); + + console.log("SH Deployer status:", deployerAvailable ? "Available" : "Unavailable"); + return deployerAvailable; + } catch (error) { + console.error("Deployer health check failed:", error); + deployerAvailable = false; + updateDeployerUI(); + return false; + } +} + +function updateDeployerUI() { + const deployerCheckbox = document.getElementById('deploy-to-shcluster'); + const deployerStatus = document.getElementById('deployer-status'); + const deployerSection = document.getElementById('deployer-section'); + + if (deployerCheckbox) { + deployerCheckbox.disabled = !deployerAvailable; + } + + if (deployerStatus) { + if (deployerAvailable) { + deployerStatus.innerHTML = '● Connected'; + } else { + deployerStatus.innerHTML = '● Disconnected'; + } + } + + if (deployerSection && !deployerAvailable) { + deployerSection.style.opacity = '0.6'; + } +} + +function loadDeployerConfig() { + try { + const saved = localStorage.getItem(GIT_PUSHER_CONFIG.deployerConfigKey); + if (saved) { + const config = JSON.parse(saved); + SH_DEPLOYER_CONFIG = { ...SH_DEPLOYER_CONFIG, ...config }; + console.log("Deployer config loaded"); + } + } catch (error) { + console.error("Error loading deployer config:", error); + } +} + +function saveDeployerConfig() { + try { + localStorage.setItem(GIT_PUSHER_CONFIG.deployerConfigKey, JSON.stringify(SH_DEPLOYER_CONFIG)); + console.log("Deployer config saved"); + } catch (error) { + console.error("Error saving deployer config:", error); + } +} + +function showDeployerConfigModal() { + const modal = document.createElement('div'); + modal.id = 'deployer-config-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; + `; + + modal.innerHTML = ` +
+

⚙️ SH Deployer Configuration

+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ `; + + document.body.appendChild(modal); +} + +function closeDeployerConfigModal() { + const modal = document.getElementById('deployer-config-modal'); + if (modal) modal.remove(); +} + +async function saveDeployerConfigFromModal() { + const host = document.getElementById('deployer-config-host')?.value?.trim(); + const port = parseInt(document.getElementById('deployer-config-port')?.value) || 9998; + const token = document.getElementById('deployer-config-token')?.value?.trim(); + const msgEl = document.getElementById('deployer-config-message'); + + if (!host) { + if (msgEl) { + msgEl.style.display = 'block'; + msgEl.style.background = '#ffebee'; + msgEl.style.color = '#c62828'; + msgEl.textContent = 'Please enter a host'; + } + return; + } + + // Mettre à jour la config + SH_DEPLOYER_CONFIG.host = host; + SH_DEPLOYER_CONFIG.port = port; + SH_DEPLOYER_CONFIG.token = token; + + // Sauvegarder + saveDeployerConfig(); + + // Tester la connexion + if (msgEl) { + msgEl.style.display = 'block'; + msgEl.style.background = '#e3f2fd'; + msgEl.style.color = '#1565c0'; + msgEl.textContent = 'Testing connection...'; + } + + const isHealthy = await checkDeployerHealth(); + + if (isHealthy) { + if (msgEl) { + msgEl.style.background = '#e8f5e9'; + msgEl.style.color = '#2e7d32'; + msgEl.textContent = '✓ Connected successfully!'; + } + setTimeout(closeDeployerConfigModal, 1500); + } else { + if (msgEl) { + msgEl.style.background = '#ffebee'; + msgEl.style.color = '#c62828'; + msgEl.textContent = '✗ Connection failed. Check host and port.'; + } + } +} + +// Vérifier la santé du serveur au démarrage +setTimeout(async () => { + const healthy = await checkServerHealth(); + if (!healthy) { + console.warn("Git Pusher server may not be running"); + } else { + console.log("Git Pusher server is healthy"); + } +}, 1000); + +// ============================================ +// EXPORT FONCTIONS GLOBALES +// ============================================ + +// Exposer les fonctions du deployer globalement pour les onclick du HTML +window.showDeployerConfigModal = showDeployerConfigModal; +window.closeDeployerConfigModal = closeDeployerConfigModal; +window.saveDeployerConfigFromModal = saveDeployerConfigFromModal; + +// Exposer les fonctions principales +window.pushDashboards = pushDashboards; +window.resetForm = resetForm; +window.toggleSelectAll = toggleSelectAll; +window.updateSelectedApps = updateSelectedApps; + +// Fonction toggle pour le HTML +window.toggleDeployerAuth = function() { + var checkbox = document.getElementById('deploy-to-shcluster'); + var authSection = document.getElementById('deployer-auth'); + if (checkbox && authSection) { + authSection.classList.toggle('visible', checkbox.checked); + } +}; + +// ============================================ +// ATTACHEMENT DES ÉVÉNEMENTS AUX BOUTONS +// ============================================ + +(function attachButtonEvents() { + function tryAttach() { + console.log("Trying to attach button events..."); + + // Bouton Deploy to Git + var pushBtn = document.getElementById('push-btn'); + if (pushBtn) { + // Supprimer les anciens listeners + pushBtn.replaceWith(pushBtn.cloneNode(true)); + pushBtn = document.getElementById('push-btn'); + + pushBtn.addEventListener('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + console.log("Deploy button clicked!"); + pushDashboards(); + }); + console.log("✓ Deploy button event attached"); + } else { + console.log("✗ Deploy button not found yet"); + } + + // Bouton Reset - chercher par classe ou contenu + var buttons = document.querySelectorAll('button.btn, button.btn-secondary'); + buttons.forEach(function(btn) { + if (btn.textContent.includes('Reset') || btn.textContent.includes('🔄')) { + // Supprimer les anciens listeners + var newBtn = btn.cloneNode(true); + btn.parentNode.replaceChild(newBtn, btn); + + newBtn.addEventListener('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + console.log("Reset button clicked!"); + resetForm(true); + }); + console.log("✓ Reset button event attached"); + } + }); + + // Bouton Configure Deployer + var configBtn = document.querySelector('.deployer-config-btn'); + if (configBtn) { + // Supprimer les anciens listeners + var newConfigBtn = configBtn.cloneNode(true); + configBtn.parentNode.replaceChild(newConfigBtn, configBtn); + + newConfigBtn.addEventListener('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + console.log("Configure button clicked!"); + showDeployerConfigModal(); + }); + console.log("✓ Configure button event attached"); + } + + // Checkbox deploy to shcluster + var deployCheckbox = document.getElementById('deploy-to-shcluster'); + if (deployCheckbox) { + deployCheckbox.addEventListener('change', function() { + var authSection = document.getElementById('deployer-auth'); + if (authSection) { + authSection.classList.toggle('visible', this.checked); + } + }); + console.log("✓ Deploy checkbox event attached"); + } + + // Si le bouton principal n'est pas encore là, réessayer + if (!pushBtn) { + console.log("Retrying in 500ms..."); + setTimeout(tryAttach, 500); + } else { + console.log("=== All button events attached successfully ==="); + } + } + + // Démarrer après un délai pour laisser le DOM se charger + if (document.readyState === 'complete') { + console.log("Document ready, attaching events in 1s..."); + setTimeout(tryAttach, 1000); + } else { + window.addEventListener('load', function() { + console.log("Window loaded, attaching events in 1s..."); + setTimeout(tryAttach, 1000); + }); + } +})(); + +// ============================================ +// EXPORT POUR DEBUG +// ============================================ + +window.GitPusher = { + config: GIT_PUSHER_CONFIG, + deployerConfig: SH_DEPLOYER_CONFIG, + getSelectedApps: () => selectedApps, + checkServer: checkServerHealth, + checkDeployer: checkDeployerHealth, + version: GIT_PUSHER_CONFIG.version +}; \ No newline at end of file diff --git a/apps/pusher_app_prem/appserver/static/license_validation.js b/apps/pusher_app_prem/appserver/static/license_validation.js old mode 100755 new mode 100644 index a3fe2f17..9a88ad40 --- a/apps/pusher_app_prem/appserver/static/license_validation.js +++ b/apps/pusher_app_prem/appserver/static/license_validation.js @@ -4,62 +4,62 @@ function _d(a,k){return a.map(function(c){return String.fromCharCode(c^k)}).join('')} -var _MiUBIgGA='jF6eQXaxas4w3DbTBbjHZiQ9pKBGtnCQ'; -var _uKlfWBIg='4haWQeriLYkoyXjRgm6X6UHBz45iRbnH'; -var _vbjxOVJJ='NFf8EIHOXxItNBiBn1nSiOVI39nWY4Wo'; -var _NifpYSQF='jetKGSDo6z5wRmmho5pl4ShoEDLXkVTg'; -var _CSSdPwWe='s2M1c6dDT80YSEJOglkKzFWva728EKKd'; -var _VtTpaXDJ='djV609Ci8cH0QhX1OOHpP2HXFkbTwAPW'; -var _RgWpxUDG='GzNPrJtG62D1lXxQqQMqERzrIh6t6qVg'; -var _ZwgnBtAr='6XCIgzQVyOlGYGhIBEaGDoK54C5iw8mb'; -var _EcTaZDmf='zwJaPfiZyz4GZjG4yTqMhme6xYdJmiZY'; -var _QVrhuHpJ='HiWpaGdVoKTfYjVonGJv8QTbS6s2mvQd'; +var _uvQJmWQj='9AFwcZcRbBeXaJqKQLeqZcWcSEyEkGhu'; +var _rIioLjQm='tiWiFVaEItxAFuYv1tgMjnQ84wQKrKs3'; +var _jCFopnuP='0kIsCpE5TFRM4gQxNtJOe1ZAKklHltin'; +var _RPzUZFtx='U6pxCxKo055c5gnUwZpoI9GVyFme2Q2J'; +var _jqqIIADg='cayEoU4uUplCxipTjpvqwFvkxnPcOmsB'; +var _VqTudlrn='hNEfSUIXujr6nEyyJqw6bKYNfhrrop3r'; +var _UpWCTgAQ='ApCX9Dnof3CkyN6RZJBBXokYM1yC3Pkk'; +var _XvSLaAUB='jAkILnmpmYfxNfNEUNezcnfsRinRXWZJ'; +var _MlAcKWHL='NeRhzYoqcPgqj1kAPCKgwQLUPdsThKEF'; +var _NuAcwBOZ='lef3hcLBzEUVO1gCTy53Rl7KyFZclckn'; -function _wxAacnbb(a,b){ +function _KBqzPUPr(a,b){ var c=a^b;var d=c.toString(16); return d.split('').reverse().join(''); } -function _IYCAxJyI(a,b){ +function _exdqMhKG(a,b){ var c=a^b;var d=c.toString(16); return d.split('').reverse().join(''); } -function _gquAYfDh(a,b){ +function _grhEQBqb(a,b){ var c=a^b;var d=c.toString(16); return d.split('').reverse().join(''); } -function _XjtRsyrV(a,b){ +function _fzlnBGMH(a,b){ var c=a^b;var d=c.toString(16); return d.split('').reverse().join(''); } -function _nBWCFFkY(a,b){ +function _MBYSySgW(a,b){ var c=a^b;var d=c.toString(16); return d.split('').reverse().join(''); } -var _ZKiGcoJO=_d([43,43,43,43,43,68,67,65,79,72,38,86,83,68,74,79,69,38,77,67,95,43,43,43,43,43,12],6); -var _nytIOASn=_d([196,192,192,202,192,227,200,199,203,238,226,248,225,226,224,206,176,254,185,203,200,216,204,207,200,200,198,202,200,238,177,200,196,192,192,202,202,238,194,202,200,238,204,200,190,193,177,255,187,189,186,217,194,249,240,189,211,234,206,220,192],137); -var _yCXhseWK=_d([237,135,134,155,183,159,132,191,149,245,136,169,137,141,154,167,169,157,169,156,145,147,145,148,156,159,235,173,178,137,177,172,142,233,230,189,147,155,238,188,151,174,182,172,144,140,168,138,178,159,231,166,174,171,177,238,191,245,230,136,245],222); -var _MALrYRWj=_d([73,89,82,125,44,52,74,104,38,94,119,91,107,106,85,84,77,86,90,120,104,85,118,103,114,48,114,116,84,124,125,117,104,110,76,87,79,114,113,102,93,93,87,79,93,93,71,40,115,80,48,110,45,104,108,90,71,47,102,44,80],31); -var _FUmiltpU=_d([92,61,6,25,49,10,2,16,64,23,37,0,49,67,37,37,27,62,53,57,30,20,10,33,64,23,37,10,69,41,34,58,39,20,54,6,92,61,52,0,74,5,92,25,38,16,70,58,39,66,42,9,37,30,60,48,16,63,75,49,41],115); -var _HZJjkoYo=_d([130,154,156,183,153,182,192,177,168,149,163,195,223,165,200,155,152,129,199,135,181,136,197,191,153,156,152,168,179,199,153,200,135,198,133,130,148,201,147,196,180,154,154,151,197,200,195,167,131,183,132,180,187,155,192,145,170,198,136,134,158],240); -var _ZhewgHyM=_d([178,141,164,185,179,178,128,174,181,146,157,166,129,191,135,181,178,128,172,182,183,142,229,188,228,154,231,184,154,237,153,150,162,181,152,182,179,149,161,189,225,134,179,176,184,182,158,184,182,147,167,179,184,231,161,149,181,237,134,237,172],212); -var _eqxIyaxT=_d([249,200,136,209,210,247,203,155,245,225,239,245,210,136,232,244,150,234,194,149,194,250,236,245,215,198,209,246,197,145,203,217,140,203,246,200,237,201,238,155,241,204,207,213,151,140,144,243,242,251,147,206,228,214,149,197,194,151,197,212,204],163); -var _tzrcGgRV=_d([194,215,208,214,233,239,255,236,194,236,252,210,141,238,222,249,255,149,237,242,208,137,209,251,245,195,216,224,226,237,240,212,205,201,149,145,145,207,200,203,211,208,234,143,233,215,227,194,195,249,219,236,214,227,251,213,207,206,222,237,215],186); -var _vlzAAMhH=_d([94,21,80,112,86,119,124,107,76,19,16,85,86,75,81,22,83,82,23,103,28,96,73,75,28,71,71,114,94,74,101,76,64,76,108,71,114,87,19,105,119,72,29,117,70,93,83,21,66,87,77,21,21,21,19,115,77,67,113,99,79],36); -var _URxOonCc=_d([124,105,25,111,84,70,64,94,64,20,105,79,110,125,75,31,107,25,84,21,29,105,126,21,25,102,97,99,28,127,70,85,68,104,78,67,94,120,7,67,97,93,21,21,24,27,118,96,31,25,122,64,64,86,71,103,78,110,105,96,78],44); -var _YpSnAdLq=_d([39,11,33,32,40,23,34,11,2,61,6,124,6,37,126,26,13,34,12,59,28,0,21,53,0,3,39,54,7,11,9,34,8,41,122,14,13,126,3,24,45,55,44,40,61,53,0,2,44,27,3,32,14,7,43,58,46,11,46,35,21],79); -var _vdQnAYzc=_d([162,155,140,182,213,182,133,183,213,210,208,210,162,144,132,128,150,164,135,144,171,183,139,217,163,171,202,209,183,164,167,133,131,179,165,138,213,187,155,169,145,174,128,166,160,148,162,171,139,175,210,160,148,153,174,217,162,160,150,164,160,160,176,220,220],225); -var _WCjuyzqV=_d([219,252,252,252,252,252,148,159,149,241,129,132,147,157,152,146,241,154,148,136,252,252,252,252,252],209); -var _gkubzYFM=_ZKiGcoJO+_nytIOASn+_yCXhseWK+_MALrYRWj+_FUmiltpU+_HZJjkoYo+_ZhewgHyM+_eqxIyaxT+_tzrcGgRV+_vlzAAMhH+_URxOonCc+_YpSnAdLq+_vdQnAYzc+_WCjuyzqV; -var PUBLIC_KEY_PEM=_gkubzYFM; +var _rVbYrxGd=_d([136,136,136,136,136,231,224,226,236,235,133,245,240,231,233,236,230,133,238,224,252,136,136,136,136,136,175],165); +var _VDYYzLxu=_d([215,211,211,217,211,240,219,212,216,253,241,235,242,241,243,221,163,237,170,216,219,203,223,220,219,219,213,217,219,253,162,219,215,211,211,217,217,253,209,217,219,253,223,219,173,210,162,236,168,174,169,202,209,234,227,174,192,249,221,207,211],154); +var _MVLYDniA=_d([212,190,191,162,142,166,189,134,172,204,177,144,176,180,163,158,144,164,144,165,168,170,168,173,165,166,210,148,139,176,136,149,183,208,223,132,170,162,215,133,174,151,143,149,169,181,145,179,139,166,222,159,151,146,136,215,134,204,223,177,204],231); +var _UAySmvNT=_d([168,184,179,156,205,213,171,137,199,191,150,186,138,139,180,181,172,183,187,153,137,180,151,134,147,209,147,149,181,157,156,148,137,143,173,182,174,147,144,135,188,188,182,174,188,188,166,201,146,177,209,143,204,137,141,187,166,206,135,205,177],254); +var _lvnLtxEJ=_d([181,212,239,240,216,227,235,249,169,254,204,233,216,170,204,204,242,215,220,208,247,253,227,200,169,254,204,227,172,192,203,211,206,253,223,239,181,212,221,233,163,236,181,240,207,249,175,211,206,171,195,224,204,247,213,217,249,214,162,216,192],154); +var _zcAMxLBG=_d([80,72,78,101,75,100,18,99,122,71,113,17,13,119,26,73,74,83,21,85,103,90,23,109,75,78,74,122,97,21,75,26,85,20,87,80,70,27,65,22,102,72,72,69,23,26,17,117,81,101,86,102,105,73,18,67,120,20,90,84,76],34); +var _dGFpAAtk=_d([55,8,33,60,54,55,5,43,48,23,24,35,4,58,2,48,55,5,41,51,50,11,96,57,97,31,98,61,31,104,28,19,39,48,29,51,54,16,36,56,100,3,54,53,61,51,27,61,51,22,34,54,61,98,36,16,48,104,3,104,41],81); +var _cerkuvwZ=_d([196,245,181,236,239,202,246,166,200,220,210,200,239,181,213,201,171,215,255,168,255,199,209,200,234,251,236,203,248,172,246,228,177,246,203,245,208,244,211,166,204,241,242,232,170,177,173,206,207,198,174,243,217,235,168,248,255,170,248,233,241],158); +var _qLGpjZls=_d([145,132,131,133,186,188,172,191,145,191,175,129,222,189,141,170,172,198,190,161,131,218,130,168,166,144,139,179,177,190,163,135,158,154,198,194,194,156,155,152,128,131,185,220,186,132,176,145,144,170,136,191,133,176,168,134,156,157,141,190,132],233); +var _WGewijsJ=_d([135,204,137,169,143,174,165,178,149,202,201,140,143,146,136,207,138,139,206,190,197,185,144,146,197,158,158,171,135,147,188,149,153,149,181,158,171,142,202,176,174,145,196,172,159,132,138,204,155,142,148,204,204,204,202,170,148,154,168,186,150],253); +var _gcFTsAUK=_d([71,82,34,84,111,125,123,101,123,47,82,116,85,70,112,36,80,34,111,46,38,82,69,46,34,93,90,88,39,68,125,110,127,83,117,120,101,67,60,120,90,102,46,46,35,32,77,91,36,34,65,123,123,109,124,92,117,85,82,91,117],23); +var _rfVsSsnX=_d([13,33,11,10,2,61,8,33,40,23,44,86,44,15,84,48,39,8,38,17,54,42,63,31,42,41,13,28,45,33,35,8,34,3,80,36,39,84,41,50,7,29,6,2,23,31,42,40,6,49,41,10,36,45,1,16,4,33,4,9,63],101); +var _VlChvXbg=_d([44,21,2,56,91,56,11,57,91,92,94,92,44,30,10,14,24,42,9,30,37,57,5,87,45,37,68,95,57,42,41,11,13,61,43,4,91,53,21,39,31,32,14,40,46,26,44,37,5,33,92,46,26,23,32,87,44,46,24,42,46,46,62,82,82],111); +var _CkJWebLK=_d([156,187,187,187,187,187,211,216,210,182,198,195,212,218,223,213,182,221,211,207,187,187,187,187,187],150); +var _EnyGSGDD=_rVbYrxGd+_VDYYzLxu+_MVLYDniA+_UAySmvNT+_lvnLtxEJ+_zcAMxLBG+_dGFpAAtk+_cerkuvwZ+_qLGpjZls+_WGewijsJ+_gcFTsAUK+_rfVsSsnX+_VlChvXbg+_CkJWebLK; +var PUBLIC_KEY_PEM=_EnyGSGDD; const DEFAULT_APP_CONFIG = { api: { @@ -90,15 +90,14 @@ function getLicenseServerUrl() { } return url; } - if (hostname === 'myprivspldev.jp-engineering.fr') { - return protocol + '//myprivspldev-api.jp-engineering.fr'; - } - if (hostname === 'myprivspldev-api.jp-engineering.fr') { - return protocol + '//' + hostname; - } if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname) || hostname === 'localhost') { return protocol + '//' + hostname + ':9999'; } + const parts = hostname.split('.'); + if (parts.length >= 2) { + parts[0] = parts[0] + '-api'; + return protocol + '//' + parts.join('.'); + } return protocol + '//' + hostname + ':9999'; } const LICENSE_CONFIG = { @@ -969,4 +968,4 @@ if (document.readyState === 'complete') { window.addEventListener('load', function() { setTimeout(initializeLicense, 100); }); -} \ No newline at end of file +} diff --git a/apps/pusher_app_prem/appserver/static/license_validation.js_old2 b/apps/pusher_app_prem/appserver/static/license_validation.js_old2 new file mode 100755 index 00000000..a3fe2f17 --- /dev/null +++ b/apps/pusher_app_prem/appserver/static/license_validation.js_old2 @@ -0,0 +1,972 @@ + +// Git Pusher License Module v2.1 +// (c) 2026 - Proprietary Software + +function _d(a,k){return a.map(function(c){return String.fromCharCode(c^k)}).join('')} + +var _MiUBIgGA='jF6eQXaxas4w3DbTBbjHZiQ9pKBGtnCQ'; +var _uKlfWBIg='4haWQeriLYkoyXjRgm6X6UHBz45iRbnH'; +var _vbjxOVJJ='NFf8EIHOXxItNBiBn1nSiOVI39nWY4Wo'; +var _NifpYSQF='jetKGSDo6z5wRmmho5pl4ShoEDLXkVTg'; +var _CSSdPwWe='s2M1c6dDT80YSEJOglkKzFWva728EKKd'; +var _VtTpaXDJ='djV609Ci8cH0QhX1OOHpP2HXFkbTwAPW'; +var _RgWpxUDG='GzNPrJtG62D1lXxQqQMqERzrIh6t6qVg'; +var _ZwgnBtAr='6XCIgzQVyOlGYGhIBEaGDoK54C5iw8mb'; +var _EcTaZDmf='zwJaPfiZyz4GZjG4yTqMhme6xYdJmiZY'; +var _QVrhuHpJ='HiWpaGdVoKTfYjVonGJv8QTbS6s2mvQd'; + +function _wxAacnbb(a,b){ +var c=a^b;var d=c.toString(16); +return d.split('').reverse().join(''); +} + + +function _IYCAxJyI(a,b){ +var c=a^b;var d=c.toString(16); +return d.split('').reverse().join(''); +} + + +function _gquAYfDh(a,b){ +var c=a^b;var d=c.toString(16); +return d.split('').reverse().join(''); +} + + +function _XjtRsyrV(a,b){ +var c=a^b;var d=c.toString(16); +return d.split('').reverse().join(''); +} + + +function _nBWCFFkY(a,b){ +var c=a^b;var d=c.toString(16); +return d.split('').reverse().join(''); +} + +var _ZKiGcoJO=_d([43,43,43,43,43,68,67,65,79,72,38,86,83,68,74,79,69,38,77,67,95,43,43,43,43,43,12],6); +var _nytIOASn=_d([196,192,192,202,192,227,200,199,203,238,226,248,225,226,224,206,176,254,185,203,200,216,204,207,200,200,198,202,200,238,177,200,196,192,192,202,202,238,194,202,200,238,204,200,190,193,177,255,187,189,186,217,194,249,240,189,211,234,206,220,192],137); +var _yCXhseWK=_d([237,135,134,155,183,159,132,191,149,245,136,169,137,141,154,167,169,157,169,156,145,147,145,148,156,159,235,173,178,137,177,172,142,233,230,189,147,155,238,188,151,174,182,172,144,140,168,138,178,159,231,166,174,171,177,238,191,245,230,136,245],222); +var _MALrYRWj=_d([73,89,82,125,44,52,74,104,38,94,119,91,107,106,85,84,77,86,90,120,104,85,118,103,114,48,114,116,84,124,125,117,104,110,76,87,79,114,113,102,93,93,87,79,93,93,71,40,115,80,48,110,45,104,108,90,71,47,102,44,80],31); +var _FUmiltpU=_d([92,61,6,25,49,10,2,16,64,23,37,0,49,67,37,37,27,62,53,57,30,20,10,33,64,23,37,10,69,41,34,58,39,20,54,6,92,61,52,0,74,5,92,25,38,16,70,58,39,66,42,9,37,30,60,48,16,63,75,49,41],115); +var _HZJjkoYo=_d([130,154,156,183,153,182,192,177,168,149,163,195,223,165,200,155,152,129,199,135,181,136,197,191,153,156,152,168,179,199,153,200,135,198,133,130,148,201,147,196,180,154,154,151,197,200,195,167,131,183,132,180,187,155,192,145,170,198,136,134,158],240); +var _ZhewgHyM=_d([178,141,164,185,179,178,128,174,181,146,157,166,129,191,135,181,178,128,172,182,183,142,229,188,228,154,231,184,154,237,153,150,162,181,152,182,179,149,161,189,225,134,179,176,184,182,158,184,182,147,167,179,184,231,161,149,181,237,134,237,172],212); +var _eqxIyaxT=_d([249,200,136,209,210,247,203,155,245,225,239,245,210,136,232,244,150,234,194,149,194,250,236,245,215,198,209,246,197,145,203,217,140,203,246,200,237,201,238,155,241,204,207,213,151,140,144,243,242,251,147,206,228,214,149,197,194,151,197,212,204],163); +var _tzrcGgRV=_d([194,215,208,214,233,239,255,236,194,236,252,210,141,238,222,249,255,149,237,242,208,137,209,251,245,195,216,224,226,237,240,212,205,201,149,145,145,207,200,203,211,208,234,143,233,215,227,194,195,249,219,236,214,227,251,213,207,206,222,237,215],186); +var _vlzAAMhH=_d([94,21,80,112,86,119,124,107,76,19,16,85,86,75,81,22,83,82,23,103,28,96,73,75,28,71,71,114,94,74,101,76,64,76,108,71,114,87,19,105,119,72,29,117,70,93,83,21,66,87,77,21,21,21,19,115,77,67,113,99,79],36); +var _URxOonCc=_d([124,105,25,111,84,70,64,94,64,20,105,79,110,125,75,31,107,25,84,21,29,105,126,21,25,102,97,99,28,127,70,85,68,104,78,67,94,120,7,67,97,93,21,21,24,27,118,96,31,25,122,64,64,86,71,103,78,110,105,96,78],44); +var _YpSnAdLq=_d([39,11,33,32,40,23,34,11,2,61,6,124,6,37,126,26,13,34,12,59,28,0,21,53,0,3,39,54,7,11,9,34,8,41,122,14,13,126,3,24,45,55,44,40,61,53,0,2,44,27,3,32,14,7,43,58,46,11,46,35,21],79); +var _vdQnAYzc=_d([162,155,140,182,213,182,133,183,213,210,208,210,162,144,132,128,150,164,135,144,171,183,139,217,163,171,202,209,183,164,167,133,131,179,165,138,213,187,155,169,145,174,128,166,160,148,162,171,139,175,210,160,148,153,174,217,162,160,150,164,160,160,176,220,220],225); +var _WCjuyzqV=_d([219,252,252,252,252,252,148,159,149,241,129,132,147,157,152,146,241,154,148,136,252,252,252,252,252],209); +var _gkubzYFM=_ZKiGcoJO+_nytIOASn+_yCXhseWK+_MALrYRWj+_FUmiltpU+_HZJjkoYo+_ZhewgHyM+_eqxIyaxT+_tzrcGgRV+_vlzAAMhH+_URxOonCc+_YpSnAdLq+_vdQnAYzc+_WCjuyzqV; +var PUBLIC_KEY_PEM=_gkubzYFM; + +const DEFAULT_APP_CONFIG = { + api: { + url: '', + port: 9999, + useProxy: true + } +}; +function loadAppConfigForLicense() { + try { + const stored = localStorage.getItem('git_pusher_config'); + if (stored) { + return JSON.parse(stored); + } + } catch (e) { + console.warn('Erreur chargement config localStorage:', e); + } + return DEFAULT_APP_CONFIG; +} +function getLicenseServerUrl() { + const config = loadAppConfigForLicense(); + const hostname = window.location.hostname; + const protocol = window.location.protocol; + if (config.api && config.api.url) { + let url = config.api.url; + if (!config.api.useProxy && config.api.port) { + url = url.replace(/\/$/, '') + ':' + config.api.port; + } + return url; + } + if (hostname === 'myprivspldev.jp-engineering.fr') { + return protocol + '//myprivspldev-api.jp-engineering.fr'; + } + if (hostname === 'myprivspldev-api.jp-engineering.fr') { + return protocol + '//' + hostname; + } + if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname) || hostname === 'localhost') { + return protocol + '//' + hostname + ':9999'; + } + return protocol + '//' + hostname + ':9999'; +} +const LICENSE_CONFIG = { + storageKey: 'git_pusher_license', + usageKey: 'git_pusher_usage', + version: '2.1.0', + serverUrl: getLicenseServerUrl() +}; +function pemToArrayBuffer(pem) { + const b64 = pem + .replace(/-----BEGIN PUBLIC KEY-----/, '') + .replace(/-----END PUBLIC KEY-----/, '') + .replace(/\s/g, ''); + const binary = atob(b64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return bytes.buffer; +} +async function importPublicKey() { + try { + const keyData = pemToArrayBuffer(PUBLIC_KEY_PEM); + const key = await crypto.subtle.importKey( + 'spki', + keyData, + { + name: 'RSASSA-PKCS1-v1_5', + hash: 'SHA-256' + }, + false, + ['verify'] + ); + return key; + } catch (error) { + console.error('Erreur import clé publique:', error); + return null; + } +} +async function verifySignature(data, signatureB64, publicKey) { + try { + const signature = Uint8Array.from(atob(signatureB64), c => c.charCodeAt(0)); + const dataBuffer = new TextEncoder().encode(data); + const isValid = await crypto.subtle.verify( + 'RSASSA-PKCS1-v1_5', + publicKey, + signature, + dataBuffer + ); + return isValid; + } catch (error) { + console.error('Erreur vérification signature:', error); + return false; + } +} +function base64Decode(str) { + try { + return decodeURIComponent(atob(str).split('').map(function(c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); + } catch (e) { + return atob(str); + } +} +function getCurrentHostname() { + return window.location.hostname.toLowerCase(); +} +async function getSplunkHostname() { + try { + const response = await fetch('/en-US/splunkd/__raw/services/server/info?output_mode=json', { + credentials: 'include' + }); + if (response.ok) { + const data = await response.json(); + const serverName = data.entry?.[0]?.content?.serverName; + if (serverName) { + console.log('Hostname Splunk (server/info):', serverName); + return serverName.toLowerCase(); + } + } + } catch (e) { + console.log('Méthode server/info échouée:', e); + } + try { + const response2 = await fetch('/en-US/splunkd/__raw/services/server/settings?output_mode=json', { + credentials: 'include' + }); + if (response2.ok) { + const data2 = await response2.json(); + const serverName = data2.entry?.[0]?.content?.serverName; + if (serverName) { + console.log('Hostname Splunk (server/settings):', serverName); + return serverName.toLowerCase(); + } + } + } catch (e) { + console.log('Méthode server/settings échouée:', e); + } + console.warn('Impossible de récupérer le hostname Splunk, utilisation URL:', getCurrentHostname()); + return getCurrentHostname(); +} +function daysRemaining(expiryDate) { + const expiry = new Date(expiryDate); + const now = new Date(); + const diff = expiry - now; + return Math.ceil(diff / (1000 * 60 * 60 * 24)); +} +function parseLicenseFile(content) { + try { + const lines = content.trim().split('\n'); + let payloadB64 = null; + for (const line of lines) { + const trimmed = line.trim(); + if (trimmed && !trimmed.startsWith('#')) { + payloadB64 = trimmed; + break; + } + } + if (!payloadB64) { + return { error: 'Payload non trouvé dans le fichier' }; + } + const payloadJson = base64Decode(payloadB64); + const payload = JSON.parse(payloadJson); + if (!payload.license || !payload.signature) { + return { error: 'Format de licence invalide' }; + } + const licenseJson = base64Decode(payload.license); + const licenseData = JSON.parse(licenseJson); + return { + success: true, + licenseJson: licenseJson, + licenseData: licenseData, + signatureB64: payload.signature, + rawPayload: payloadB64 + }; + } catch (error) { + console.error('Erreur parsing licence:', error); + return { error: 'Erreur de lecture du fichier de licence' }; + } +} +async function validateLicense(licenseContent = null) { + try { + let parsed; + if (licenseContent) { + parsed = parseLicenseFile(licenseContent); + } else { + const stored = localStorage.getItem(LICENSE_CONFIG.storageKey); + if (!stored) { + return { + valid: false, + error: 'Aucune licence installée', + error_code: 'NO_LICENSE' + }; + } + parsed = JSON.parse(stored); + } + if (parsed.error) { + return { + valid: false, + error: parsed.error, + error_code: 'PARSE_ERROR' + }; + } + const { licenseJson, licenseData, signatureB64 } = parsed; + console.log('=== DEBUG VALIDATION LICENCE ==='); + console.log('License JSON:', licenseJson); + console.log('License JSON length:', licenseJson.length); + console.log('Signature B64:', signatureB64.substring(0, 50) + '...'); + console.log('Signature B64 length:', signatureB64.length); + console.log('Vérification de la signature RSA...'); + const publicKey = await importPublicKey(); + if (!publicKey) { + console.error('Échec import clé publique'); + return { + valid: false, + error: 'Impossible de charger la clé publique', + error_code: 'KEY_ERROR' + }; + } + console.log('Clé publique importée avec succès'); + const signatureValid = await verifySignature(licenseJson, signatureB64, publicKey); + console.log('Résultat vérification signature:', signatureValid); + if (!signatureValid) { + return { + valid: false, + error: 'Signature de licence invalide', + error_code: 'INVALID_SIGNATURE' + }; + } + console.log('✓ Signature RSA valide'); + const expectedHostname = (licenseData.hostname || '').toLowerCase(); + const currentHostname = await getSplunkHostname(); + console.log(`Hostname attendu: "${expectedHostname}", actuel: "${currentHostname}"`); + if (expectedHostname && expectedHostname !== currentHostname) { + if (!currentHostname.includes(expectedHostname) && !expectedHostname.includes(currentHostname)) { + return { + valid: false, + error: `Licence non valide pour ce serveur. Attendu: ${expectedHostname}, Actuel: ${currentHostname}`, + error_code: 'HOSTNAME_MISMATCH', + expected_hostname: expectedHostname, + current_hostname: currentHostname + }; + } + console.log('✓ Hostname valide (correspondance partielle)'); + } else { + console.log('✓ Hostname valide (exact)'); + } + const expiryDate = licenseData.expires; + if (expiryDate) { + const days = daysRemaining(expiryDate); + if (days < 0) { + return { + valid: false, + error: `Licence expirée le ${expiryDate}`, + error_code: 'LICENSE_EXPIRED', + expires: expiryDate + }; + } + console.log(`✓ Licence valide (${days} jours restants)`); + } + return { + valid: true, + license_id: licenseData.license_id, + type: licenseData.type, + type_name: licenseData.type_name, + customer: licenseData.customer, + hostname: expectedHostname, + issued: licenseData.issued, + expires: expiryDate, + days_remaining: daysRemaining(expiryDate), + limits: licenseData.limits || {}, + features: licenseData.features || [] + }; + } catch (error) { + console.error('Erreur validation licence:', error); + return { + valid: false, + error: error.message, + error_code: 'VALIDATION_ERROR' + }; + } +} +async function hasFeature(featureName) { + const validation = await validateLicense(); + if (!validation.valid) return false; + return validation.features.includes(featureName); +} +async function saveLicense(licenseContent) { + try { + const parsed = parseLicenseFile(licenseContent); + if (parsed.error) { + return { + success: false, + error: parsed.error + }; + } + const validation = await validateLicense(licenseContent); + if (!validation.valid) { + return { + success: false, + error: validation.error, + error_code: validation.error_code + }; + } + localStorage.setItem(LICENSE_CONFIG.storageKey, JSON.stringify(parsed)); + console.log('✓ Licence sauvegardée dans localStorage'); + try { + const response = await fetch(`${LICENSE_CONFIG.serverUrl}/license/save`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + license_content: licenseContent + }) + }); + const serverResult = await response.json(); + if (serverResult.success) { + console.log('✓ Licence sauvegardée sur le serveur'); + } else { + console.warn('⚠ Échec sauvegarde serveur:', serverResult.error); + } + } catch (serverError) { + console.warn('⚠ Impossible de sauvegarder sur le serveur:', serverError); + } + return { + success: true, + license: validation + }; + } catch (error) { + console.error('Erreur sauvegarde licence:', error); + return { + success: false, + error: error.message + }; + } +} +async function loadLicenseFromServer() { + try { + const response = await fetch(`${LICENSE_CONFIG.serverUrl}/license/file`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + }); + const result = await response.json(); + if (result.success && result.content) { + console.log('Licence trouvée sur le serveur, validation en cours...'); + const parsed = parseLicenseFile(result.content); + if (parsed.error) { + console.warn('Erreur parsing licence serveur:', parsed.error); + return false; + } + const validation = await validateLicense(result.content); + if (validation.valid) { + localStorage.setItem(LICENSE_CONFIG.storageKey, JSON.stringify(parsed)); + console.log('✓ Licence chargée depuis le serveur et stockée localement'); + return true; + } else { + console.warn('Licence serveur invalide:', validation.error); + return false; + } + } else { + console.log('Aucune licence sur le serveur'); + return false; + } + } catch (error) { + console.log('Impossible de charger la licence depuis le serveur:', error.message); + return false; + } +} +async function removeLicense() { + localStorage.removeItem(LICENSE_CONFIG.storageKey); + localStorage.removeItem(LICENSE_CONFIG.usageKey); + try { + await fetch(`${LICENSE_CONFIG.serverUrl}/license/delete`, { + method: 'POST' + }); + console.log('Licence supprimée du serveur'); + } catch (e) { + console.warn('Impossible de supprimer la licence du serveur:', e); + } + console.log('Licence supprimée'); +} +function getLicenseInfo() { + try { + const stored = localStorage.getItem(LICENSE_CONFIG.storageKey); + if (!stored) return null; + const parsed = JSON.parse(stored); + return parsed.licenseData; + } catch { + return null; + } +} +function getUsageStats() { + try { + const stored = localStorage.getItem(LICENSE_CONFIG.usageKey); + if (stored) { + return JSON.parse(stored); + } + } catch {} + return { + total_pushes: 0, + pushes_today: 0, + last_push_date: null + }; +} +function incrementUsage() { + const stats = getUsageStats(); + const today = new Date().toISOString().split('T')[0]; + if (stats.last_push_date !== today) { + stats.pushes_today = 0; + stats.last_push_date = today; + } + stats.total_pushes = (stats.total_pushes || 0) + 1; + stats.pushes_today = (stats.pushes_today || 0) + 1; + localStorage.setItem(LICENSE_CONFIG.usageKey, JSON.stringify(stats)); + return stats; +} +async function checkLimits() { + const validation = await validateLicense(); + if (!validation.valid) { + return { + allowed: false, + error: validation.error, + error_code: validation.error_code + }; + } + const limits = validation.limits || {}; + const maxPushes = limits.max_pushes_per_day || -1; + if (maxPushes > 0) { + const stats = getUsageStats(); + const today = new Date().toISOString().split('T')[0]; + let pushesToday = stats.pushes_today || 0; + if (stats.last_push_date !== today) { + pushesToday = 0; + } + if (pushesToday >= maxPushes) { + return { + allowed: false, + error: `Limite quotidienne atteinte (${maxPushes} pushes/jour)`, + error_code: 'DAILY_LIMIT_REACHED' + }; + } + } + return { + allowed: true, + license_type: validation.type_name, + remaining_today: maxPushes > 0 ? maxPushes - getUsageStats().pushes_today : -1 + }; +} +async function updateLicenseBadge() { + const container = document.getElementById('license-badge-container'); + if (!container) return; + const validation = await validateLicense(); + let badgeHtml = ''; + if (validation.valid) { + const daysLeft = validation.days_remaining; + let badgeClass = 'license-badge-valid'; + let icon = '✓'; + if (daysLeft <= 7) { + badgeClass = 'license-badge-expiring'; + icon = '⚠️'; + } else if (daysLeft <= 30) { + badgeClass = 'license-badge-warning'; + icon = '⏳'; + } + badgeHtml = ` +
+ ${icon} + ${validation.type_name} + ${daysLeft}j +
+ `; + } else { + badgeHtml = ` +
+ 🔐 + Activer +
+ `; + } + container.innerHTML = badgeHtml; +} +function showLicenseModal(message = null, errorCode = null) { + const existingModal = document.getElementById('license-modal'); + if (existingModal) existingModal.remove(); + const modal = document.createElement('div'); + modal.id = 'license-modal'; + modal.className = 'license-modal-overlay'; + let errorMessage = ''; + if (message) { + errorMessage = `
${message}
`; + } + modal.innerHTML = ` +
+
+

🔐 Activation de Licence

+ +
+
+ ${errorMessage} +
+
📄
+
+ Glissez-déposez votre fichier .lic ici +
ou cliquez pour sélectionner +
+ +
+
+ Hostname du serveur: + Chargement... +
Communiquez ce hostname pour obtenir votre licence +
+
+
+ +
+ `; + document.body.appendChild(modal); + getSplunkHostname().then(hostname => { + const hostnameDisplay = document.getElementById('current-hostname-display'); + if (hostnameDisplay) { + hostnameDisplay.textContent = hostname; + } + }); + setupLicenseUpload(); +} +function setupLicenseUpload() { + const dropZone = document.getElementById('license-upload-zone'); + const fileInput = document.getElementById('license-file-input'); + if (!dropZone || !fileInput) return; + dropZone.addEventListener('click', () => fileInput.click()); + dropZone.addEventListener('dragover', (e) => { + e.preventDefault(); + dropZone.classList.add('dragover'); + }); + dropZone.addEventListener('dragleave', () => { + dropZone.classList.remove('dragover'); + }); + dropZone.addEventListener('drop', (e) => { + e.preventDefault(); + dropZone.classList.remove('dragover'); + const files = e.dataTransfer.files; + if (files.length > 0) { + handleLicenseFile(files[0]); + } + }); + fileInput.addEventListener('change', (e) => { + if (e.target.files.length > 0) { + handleLicenseFile(e.target.files[0]); + } + }); +} +async function handleLicenseFile(file) { + const resultDiv = document.getElementById('license-validation-result'); + if (!resultDiv) return; + if (!file.name.endsWith('.lic')) { + resultDiv.innerHTML = ` +
+ ❌ Le fichier doit avoir l'extension .lic +
+ `; + return; + } + resultDiv.innerHTML = ` +
+ ⏳ Validation en cours... +
+ `; + try { + const content = await file.text(); + const result = await saveLicense(content); + if (result.success) { + const license = result.license; + resultDiv.innerHTML = ` +
+
+
+ Licence activée avec succès !
+ Type: ${license.type_name}
+ Expire: ${license.expires} (${license.days_remaining} jours)
+ Client: ${license.customer?.name || 'N/A'} +
+
+ `; + updateLicenseBadge(); + setTimeout(() => { + closeLicenseModal(); + }, 3000); + } else { + resultDiv.innerHTML = ` +
+ ❌ ${result.error} +
+ `; + } + } catch (error) { + resultDiv.innerHTML = ` +
+ ❌ Erreur: ${error.message} +
+ `; + } +} +function closeLicenseModal() { + const modal = document.getElementById('license-modal'); + if (modal) modal.remove(); +} +async function showLicenseDetails() { + const validation = await validateLicense(); + if (!validation.valid) { + showLicenseModal(validation.error, validation.error_code); + return; + } + const existingModal = document.getElementById('license-details-modal'); + if (existingModal) existingModal.remove(); + const modal = document.createElement('div'); + modal.id = 'license-details-modal'; + modal.className = 'license-modal-overlay'; + const features = validation.features.map(f => `${f}`).join(' '); + const limits = validation.limits; + const maxApps = limits.max_apps === -1 ? '∞' : limits.max_apps; + const maxPushes = limits.max_pushes_per_day === -1 ? '∞' : limits.max_pushes_per_day; + const usage = getUsageStats(); + modal.innerHTML = ` +
+
+

📋 Détails de la Licence

+ +
+
+ + + + + + + + + + + +
ID${validation.license_id}
Type${validation.type_name}
Client${validation.customer?.name || 'N/A'}
Email${validation.customer?.email || 'N/A'}
Hostname${validation.hostname}
Émise le${validation.issued}
Expire le${validation.expires}
Jours restants${validation.days_remaining}
Apps max${maxApps}
Pushes/jour${maxPushes}
+
+ Fonctionnalités:
+
${features}
+
+
+ Utilisation:
+ Total pushes: ${usage.total_pushes} | Aujourd'hui: ${usage.pushes_today} +
+
+ +
+ `; + document.body.appendChild(modal); +} +function confirmRemoveLicense() { + if (confirm('Êtes-vous sûr de vouloir supprimer cette licence ?')) { + removeLicense(); + const detailsModal = document.getElementById('license-details-modal'); + if (detailsModal) detailsModal.remove(); + updateLicenseBadge(); + alert('Licence supprimée.'); + } +} +async function checkLicenseBeforePush() { + const result = await checkLimits(); + if (!result.allowed) { + showLicenseModal(result.error, result.error_code); + return false; + } + return true; +} +const licenseStyles = ` + +`; +async function initializeLicense() { + console.log('Git Pusher License System v' + LICENSE_CONFIG.version + ' (RSA)'); + if (!document.getElementById('license-styles')) { + const styleEl = document.createElement('div'); + styleEl.id = 'license-styles'; + styleEl.innerHTML = licenseStyles; + document.head.appendChild(styleEl); + } + const stored = localStorage.getItem(LICENSE_CONFIG.storageKey); + if (!stored) { + console.log('Aucune licence en cache, tentative de chargement depuis le serveur...'); + const loadedFromServer = await loadLicenseFromServer(); + if (loadedFromServer) { + console.log('✓ Licence restaurée depuis le serveur'); + } else { + console.log('Aucune licence disponible'); + } + } else { + console.log('Licence trouvée dans le cache local'); + } + updateLicenseBadge(); +} +window.initializeLicense = initializeLicense; +window.validateLicense = validateLicense; +window.saveLicense = saveLicense; +window.removeLicense = removeLicense; +window.loadLicenseFromServer = loadLicenseFromServer; +window.checkLicenseBeforePush = checkLicenseBeforePush; +window.showLicenseModal = showLicenseModal; +window.closeLicenseModal = closeLicenseModal; +window.showLicenseDetails = showLicenseDetails; +window.confirmRemoveLicense = confirmRemoveLicense; +window.updateLicenseBadge = updateLicenseBadge; +window.hasFeature = hasFeature; +window.incrementUsage = incrementUsage; +window.getUsageStats = getUsageStats; +window.getLicenseInfo = getLicenseInfo; +if (document.readyState === 'complete') { + setTimeout(initializeLicense, 100); +} else { + window.addEventListener('load', function() { + setTimeout(initializeLicense, 100); + }); +} \ No newline at end of file diff --git a/apps/pusher_app_prem/bin/git_pusher.pid b/apps/pusher_app_prem/bin/git_pusher.pid old mode 100755 new mode 100644 index f23e4135..da67768e --- a/apps/pusher_app_prem/bin/git_pusher.pid +++ b/apps/pusher_app_prem/bin/git_pusher.pid @@ -1 +1 @@ -656756 +3389471