v5.0.10 — Stabilité session EV

This commit is contained in:
Quentin Rouiller
2026-04-21 15:32:44 +02:00
parent e17f604d9e
commit 7ba28d3bac
3 changed files with 51 additions and 27 deletions
+3 -1
View File
@@ -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`,
+1 -1
View File
@@ -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": [
+47 -25
View File
@@ -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() {
<span class="banner-spinner"></span>
<span class="banner-text">Reconnexion à EasyVista en cours Connectez-vous dans l'onglet qui vient de s'ouvrir.</span>
`;
// 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);