From 7ba28d3bac90d484a7fdad0a53ec1620f908359a Mon Sep 17 00:00:00 2001 From: Quentin Rouiller Date: Tue, 21 Apr 2026 15:32:44 +0200 Subject: [PATCH] =?UTF-8?q?v5.0.10=20=E2=80=94=20Stabilit=C3=A9=20session?= =?UTF-8?q?=20EV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- background.js | 4 ++- manifest.json | 2 +- viewer.js | 72 +++++++++++++++++++++++++++++++++------------------ 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/background.js b/background.js index 14acfc9..91cf038 100644 --- a/background.js +++ b/background.js @@ -1004,7 +1004,9 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg.type === "openEasyVistaLogin") { // v5.0.9 : ouvre EasyVista dans un nouvel onglet pour provoquer // le SSO Windows automatique (reconnexion transparente). - const origin = msg.origin || "https://itsma.etat-de-vaud.ch"; + // v5.0.10 : fallback sur itsma.vd.ch (externe, accessible de partout) + // au lieu de .etat-de-vaud.ch (inaccessible en télétravail). + const origin = msg.origin || "https://itsma.vd.ch"; try { const tab = await chrome.tabs.create({ url: `${origin}/index.php?eventName=HelpDesk_PlanningItem`, diff --git a/manifest.json b/manifest.json index 999343b..c58d726 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Planification", - "version": "5.0.9", + "version": "5.0.10", "description": "Vue claire et rapide du planning des techniciens EasyVista. Regroupe interventions et réservations par tech, affiche horaires, contact, lieu, catégorie et statut en un coup d'œil.", "permissions": ["activeTab", "scripting", "storage", "tabs", "alarms"], "host_permissions": [ diff --git a/viewer.js b/viewer.js index 8877ca6..0832823 100644 --- a/viewer.js +++ b/viewer.js @@ -152,16 +152,18 @@ let state = { currentData: null, // résultat parsé (techs, stats, ...) loading: false, // v5.0.9 : timestamp (ms) auquel la session EV va expirer. - // On suppose une durée de 30 min à chaque requête EV réussie. - // null = inconnu (pas encore récupéré). sessionExpireAt: null, - // v5.0.9 : true pendant une reconnexion en cours (après clic sur "Me - // reconnecter" tant que la nouvelle session n'est pas détectée) + // v5.0.9 : true pendant une reconnexion en cours reconnecting: false, // v5.0.9 : true si la session est expirée (bannière rouge affichée) sessionExpired: false, // v5.0.9 : true si on a déjà fait le ping de confirmation < 5 min - sessionPingDone: false + sessionPingDone: false, + // v5.0.10 : dernière origine EV connue comme fonctionnelle (itsma.vd.ch + // ou itsma.etat-de-vaud.ch selon qu'on est en externe ou interne). + // Conservée même quand state.session est null, pour savoir où rediriger + // lors de la reconnexion. + lastKnownOrigin: null }; // v5.0.9 : constantes session @@ -263,6 +265,10 @@ async function refreshSessionAndLoad() { return; } state.session = resp.session; + // v5.0.10 : mémoriser l'origine courante pour la reconnexion si besoin + if (resp.session && resp.session.origin) { + state.lastKnownOrigin = resp.session.origin; + } hideSessionNeeded(); hideEvUnreachable(); hideSessionExpiredBanner(); @@ -496,7 +502,12 @@ function bindTopbar() { } }); - document.getElementById("open-ev-btn").addEventListener("click", openEasyVista); + // v5.0.10 : clic "Ouvrir EasyVista" sur l'écran plein → déclenche la + // reconnexion SSO + l'auto-reload du viewer dès que la nouvelle session + // est détectée (au lieu d'ouvrir juste un onglet). + document.getElementById("open-ev-btn").addEventListener("click", () => { + triggerReconnect(); + }); // v4.2 : écran "EasyVista inaccessible" const openEvBtn2 = document.getElementById("open-ev-btn-2"); @@ -527,11 +538,16 @@ function bindTopbar() { } async function openEasyVista() { - // Ouvrir sur le domaine externe (accessible depuis l'extérieur). - // Le domaine interne (itsma.etat-de-vaud.ch) n'est accessible que depuis le réseau VD. - // Une fois connecté, l'extension détectera automatiquement le PHPSESSID quel que - // soit le domaine où tu es connecté. - await chrome.tabs.create({ url: "https://itsma.vd.ch/" }); + // v5.0.10 : ouvrir sur le domaine le plus approprié : + // - lastKnownOrigin si on a déjà eu une session fonctionnelle (respecte + // interne vs externe selon le réseau) + // - session.origin si on a encore la session + // - itsma.vd.ch en fallback (domaine externe accessible de partout, + // même depuis le réseau VD il redirige vers l'interne transparent) + const origin = state.lastKnownOrigin + || (state.session && state.session.origin) + || "https://itsma.vd.ch"; + await chrome.tabs.create({ url: origin + "/" }); } // Navigation ±1 jour en sautant les week-ends @@ -1001,13 +1017,20 @@ function showSessionCriticalModal() { * Appelé au clic "Me reconnecter" dans la bannière. Ouvre EasyVista dans un * nouvel onglet (déclenche Windows SSO Kerberos automatique). Le polling * dans initSessionTimer détectera la nouvelle session et rechargera le viewer. + * + * v5.0.10 : utilise l'origine dynamique (interne ou externe selon le réseau). + * Priorité : lastKnownOrigin (mémorisée quand ça marchait) > session.origin > + * itsma.vd.ch (externe, accessible de partout) en fallback. */ async function triggerReconnect() { state.reconnecting = true; hideSessionExpiredBanner(); showReconnectingBanner(); try { - const origin = (state.session && state.session.origin) || "https://itsma.etat-de-vaud.ch"; + const origin = state.lastKnownOrigin + || (state.session && state.session.origin) + || "https://itsma.vd.ch"; + console.log("[session] triggerReconnect → ouverture de", origin); await sendMessage({ type: "openEasyVistaLogin", origin }); } catch (err) { console.warn("[session] openEasyVistaLogin failed:", err); @@ -6773,18 +6796,19 @@ function showSessionExpiredBanner() { const b = document.getElementById("session-expired-banner"); if (b) { b.classList.remove("hidden"); - // v5.0.9 : s'assurer que la bannière contient le bouton "Me reconnecter" - // et qu'il appelle triggerReconnect (SSO Windows transparent). - if (!b.querySelector(".session-expired-reconnect-btn")) { - // Chercher le premier .banner-content ou injecter du contenu si vide - let content = b.querySelector(".banner-content") || b; - // Si déjà du contenu natif, on ajoute juste le bouton à la fin - const btn = document.createElement("button"); - btn.type = "button"; - btn.className = "session-expired-reconnect-btn"; + // v5.0.10 : rebrancher le bouton "Ouvrir EasyVista" natif pour qu'il + // appelle triggerReconnect() au lieu de juste ouvrir un onglet. Ça + // déclenche la reconnexion SSO ET l'auto-reload du viewer quand la + // nouvelle session est détectée. + // On renomme aussi le bouton pour être explicite. + const btn = b.querySelector("#session-banner-reconnect"); + if (btn && !btn.dataset.boundReconnect) { + btn.dataset.boundReconnect = "1"; btn.textContent = "🔄 Me reconnecter"; - btn.addEventListener("click", () => triggerReconnect()); - content.appendChild(btn); + // Retirer d'éventuels anciens listeners en clonant le bouton + const clone = btn.cloneNode(true); + btn.parentNode.replaceChild(clone, btn); + clone.addEventListener("click", () => triggerReconnect()); } } hideEvUnreachableBanner(); @@ -6800,7 +6824,6 @@ function hideSessionExpiredBanner() { function showReconnectingBanner() { let b = document.getElementById("session-reconnecting-banner"); if (!b) { - // Créer la bannière si elle n'existe pas (dans le topbar) b = document.createElement("div"); b.id = "session-reconnecting-banner"; b.className = "banner-reconnecting"; @@ -6808,7 +6831,6 @@ function showReconnectingBanner() { `; - // L'insérer juste après la topbar const topbar = document.querySelector(".topbar") || document.querySelector("header") || document.body; if (topbar.nextSibling) { topbar.parentNode.insertBefore(b, topbar.nextSibling);