-
Lucie Bader authored
This reverts commit bc0f72c1
4c4d0ef3
background.js 20.63 KiB
// ─────────────────────────────────────────────────────────────────────────────
// Variables globales
// ─────────────────────────────────────────────────────────────────────────────
let isExtensionActive = true;
let areStatsActive = false;
let originalTabId = null;
let loginTabId = null;
const AUTH_LOGIN_URL = "https://prisms.lezinter.net/fr/login";
const AUTH_BALEX_URL = "https://prisms.lezinter.net/fr/headquarters/balex";
// ─────────────────────────────────────────────────────────────────────────────
// Logs de démarrage
// ─────────────────────────────────────────────────────────────────────────────
log("🚀 ff2BaLex (background) chargé.");
browser.runtime.onInstalled.addListener((details) => {
log("🔔 Extension installée ou mise à jour. Raison :", details.reason);
});
browser.runtime.onStartup.addListener(() => {
log("🔄 Extension démarrée (onStartup).");
});
// ─────────────────────────────────────────────────────────────────────────────
// Suivi des changements dans le stockage
// ─────────────────────────────────────────────────────────────────────────────
browser.storage.onChanged.addListener((changes) => {
if (changes.extensionActive) {
isExtensionActive = changes.extensionActive.newValue;
log("✅ Extension activée :", isExtensionActive);
}
if (changes.statsActive) {
areStatsActive = changes.statsActive.newValue;
log("📊 Statistiques activées :", areStatsActive);
}
refreshAllUI();
});
browser.storage.onChanged.addListener((changes, area) => {
if (area === "local" && changes.accessToken) {
const newToken = changes.accessToken.newValue;
if (newToken) {
browser.storage.local.get("extensionActive").then(({ extensionActive }) => {
if (!extensionActive) {
log("Token ajouté, activation automatique de l'extension.");
browser.storage.local.set({ extensionActive: true });
enableExtensionFeatures();
browser.runtime.sendMessage({
action: "updateUI",
extensionActive: true,
isTrackingActive: true,
autoAdd: true
});
}
});
}
}
});
// ─────────────────────────────────────────────────────────────────────────────
// Fonctions utilitaires
// ─────────────────────────────────────────────────────────────────────────────
async function isUserConnected() {
const { accessToken } = await browser.storage.local.get("accessToken");
return !!accessToken;
}
async function refreshAllUI() {
log("🔄 Rafraîchissement global de l'UI...");
browser.runtime.sendMessage({ action: "refreshUI" });
}
// ─────────────────────────────────────────────────────────────────────────────
// Initialisation du WebWorker
// ─────────────────────────────────────────────────────────────────────────────
let worker = null;
function initWorker() {
if (!worker) {
log("[Background] Initialisation du WebWorker...");
try {
worker = new Worker("src/workers/pyodide_worker.js");
worker.onmessage = (event) => {
log("[Background] Message reçu du WebWorker :", event.data);
};
worker.onerror = (error) => {
console.error("[Background] Erreur dans le WebWorker :", error);
};
log("[Background] WebWorker initialisé avec succès.");
} catch (error) {
console.error("[Background] Échec de l'initialisation du WebWorker :", error);
}
}
}
// Initialisation
initWorker();
worker.postMessage({ command: "pyodide-simplemma" });
// ─────────────────────────────────────────────────────────────────────────────
// Écoute des messages de la popup et transmission au WebWorker
// ─────────────────────────────────────────────────────────────────────────────
browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
log("[Background] Message reçu :", message);
if (!worker) {
initWorker();
}
if (message.command === "toggle-stats") {
log(`[Background] Statistiques ${message.isActive ? "activées" : "désactivées"}`);
await browser.storage.local.set({ isTrackingActive: message.isActive });
// Transmettre l'activation des statistiques au WebWorker
worker.postMessage({ command: "toggle-stats", isActive: message.isActive });
}
if (message.command === "pyodide-simplemma") {
log("[Background] Demande d'initialisation de Pyodide et Simplemma...");
worker.postMessage({ command: "pyodide-simplemma" });
}
return true;
});
// ─────────────────────────────────────────────────────────────────────────────
// Écouter les réponses du WebWorker
// ─────────────────────────────────────────────────────────────────────────────
worker.onmessage = (event) => {
log("[Background] Message du WebWorker :", event.data);
// Pyodide et Simplemma prêts : notifier tous les onglets
if (event.data.type === "pyodide-simplemma" && event.data.status === "success") {
browser.tabs.query({}).then((tabs) => {
tabs.forEach((tab) => {
if (!tab.url || (!tab.url.startsWith("https://") && (!tab.url.startsWith("https://")))) {
return;
}
if (tab.url.includes("sidebar.html")) {
return;
}
try {
let response = browser.tabs.sendMessage(tab.id, { command: "pyodide-simplemma-ready" })
if (response && typeof response.then === "function") {
response.then(() => {
}).catch((error) => {
log("[Background] Impossible d'envoyer un message à l'onglet ${tab.id} : ${error}");
});
}
} catch (error) {
log("[Background] Erreur lors de l'envoi d'un message à l'onglet ${tab.id} : ${error}");
}
});
})
}
}
// ─────────────────────────────────────────────────────────────────────────────
// Fonctions d'authentification & de redirection
// ─────────────────────────────────────────────────────────────────────────────
browser.runtime.onConnect.addListener((port) => {
if (port.name === "auth") {
port.onMessage.addListener(async (message) => {
if (message.action === "toggleAuth") {
log("🔄 toggleAuth reçu via port dans le background.");
const isConnected = await isUserConnected();
if (isConnected) {
await disconnectFromLexicalDB();
} else {
actuallyOpenLoginPage();
}
}
});
}
});
async function actuallyOpenLoginPage() {
log("🔗 Ouverture de la page de connexion.");
// Mémoriser l'onglet actif
const [currentTab] = await browser.tabs.query({ active: true, currentWindow: true });
if (currentTab) {
originalTabId = currentTab.id;
log("✅ Onglet courant mémorisé, ID =", originalTabId);
}
// Ouvre un nouvel onglet pour la page de connexion et l'active
const loginTab = await browser.tabs.create({ url: AUTH_LOGIN_URL, active: true });
loginTabId = loginTab.id;
log("✅ Onglet de login créé, ID =", loginTabId);
// Notifie que l'authentification est en cours
browser.runtime.sendMessage({ action: "authStatusChanged", isLoggedIn: false });
}
// Déconnecte l'utilisateur
async function disconnectFromLexicalDB() {
await browser.storage.local.remove("accessToken");
log("🔓 Token supprimé avec succès.");
await browser.storage.local.remove("lexiconColors");
// Désactivation automatique de l'extension
await browser.storage.local.set({ extensionActive: false });
disableExtensionFeatures();
browser.runtime.sendMessage({
action: "updateUI",
extensionActive: false,
isTrackingActive: false,
autoAdd: false
});
setTimeout(async () => {
await refreshAllUI();
}, 500);
}
// Sauvegarde le token et ferme l'onglet de login si nécessaire
async function saveToken(token) {
log("✅ Sauvegarde du token :", token);
await browser.storage.local.set({ accessToken: token });
if (loginTabId) {
try {
await browser.tabs.remove(loginTabId);
log("🗙 Onglet de login fermé après connexion réussie.");
} catch (err) {
console.warn("Impossible de fermer l'onglet de login :", err);
}
loginTabId = null;
}
if (originalTabId) {
try {
await browser.tabs.update(originalTabId, { active: true });
log("🔙 Retour sur l'onglet initial :", originalTabId);
} catch (err) {
console.warn("Impossible de basculer sur l'onglet initial :", err);
}
originalTabId = null;
}
// Activer automatiquement l'extension
const { extensionActive } = await browser.storage.local.get("extensionActive");
if (!extensionActive) {
await browser.storage.local.set({ extensionActive: true });
enableExtensionFeatures();
browser.runtime.sendMessage({
action: "updateUI",
extensionActive: true,
isTrackingActive: true,
autoAdd: true
});
}
await refreshAllUI();
}
// ─────────────────────────────────────────────────────────────────────────────
// Gestion des messages reçus
// ─────────────────────────────────────────────────────────────────────────────
browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
log("📩 Message reçu dans background.js :", message);
switch (message.action) {
case "toggleAuth": {
const isConnected = await isUserConnected();
if (isConnected) {
await disconnectFromLexicalDB();
await browser.storage.local.remove("lexiconColors");
} else {
actuallyOpenLoginPage();
}
break;
}
case "getDefinitionWiki": {
if (message.selectedText && message.selectedText.trim() !== "") {
log("🌐 Requête Wiktionnaire pour :", message.selectedText);
const definition = await window.fetchWiktionaryDefinition(message.selectedText.trim());
browser.runtime.sendMessage({
action: "fetchWiktionaryDefinitionResponse",
selectedText: message.selectedText,
definitions: [{
source: "Wiktionnaire",
text: definition,
}],
});
} else {
console.warn("⚠️ Texte sélectionné vide. Annulation de la requête.");
}
break;
}
case "checkAuthStatus": {
const connected = await isUserConnected();
sendResponse(connected);
break;
}
case "authStatusChanged": {
log("🔄 Mise à jour de l'état d'authentification :", message.isLoggedIn);
break;
}
case "saveToken": {
if (message.token) {
await saveToken(message.token);
} else {
console.warn("⚠️ Aucune valeur de token reçue.");
}
break;
}
default:
break;
}
return true;
});
// ─────────────────────────────────────────────────────────────────────────────
// Web Navigation : Injection de scripts et récupération du token
// ─────────────────────────────────────────────────────────────────────────────
browser.webNavigation.onCompleted.addListener(async (details) => {
const url = new URL(details.url);
// Injection d'un popup d'instruction sur la page de login
if (url.hostname === "prisms.lezinter.net" && url.pathname === "/fr/login") {
log("📘 Injection du popup d'instruction sur la page de login Prisms.");
showInstructionPopup(details);
}
// Récupération du token sur la page /balex
if (url.hostname === "prisms.lezinter.net" && url.pathname === "/fr/headquarters/balex") {
log("🟢 Page /balex détectée. Tentative de récupération du token.");
try {
await new Promise(resolve => setTimeout(resolve, 3000));
await browser.tabs.executeScript(details.tabId, {
code: `
(function() {
log("🔍 Recherche du token...");
const tokenElement = document.getElementById("accessToken") || document.getElementById("accesToken");
if (tokenElement) {
const token = tokenElement.innerText.trim();
log("🔐 Token détecté :", token);
browser.runtime.sendMessage({ action: "saveToken", token });
} else {
console.error("❌ Token introuvable.");
}
return null;
})();
`
});
} catch (error) {
console.error("❌ Erreur lors de la récupération du token :", error);
}
}
}, { url: [{ hostContains: "prisms.lezinter.net" }] });
// ─────────────────────────────────────────────────────────────────────────────
// Web Request : Redirection automatique vers /balex
// ─────────────────────────────────────────────────────────────────────────────
browser.webRequest.onBeforeRequest.addListener(
function(details) {
if (details.url === "https://prisms.lezinter.net/fr/headquarters/") {
log("🚀 Redirection automatique vers /balex.");
return { redirectUrl: AUTH_BALEX_URL };
}
},
{ urls: ["https://prisms.lezinter.net/fr/headquarters/*"] },
["blocking"]
);
// ─────────────────────────────────────────────────────────────────────────────
// Affichage d'un popup d'instruction sur /fr/login
// ─────────────────────────────────────────────────────────────────────────────
function showInstructionPopup(details) {
browser.tabs.executeScript(details.tabId, {
code: `
if (!document.getElementById("balex-instruction-popup")) {
const popup = document.createElement("div");
popup.id = "balex-instruction-popup";
popup.style.position = "fixed";
popup.style.top = "50%";
popup.style.left = "50%";
popup.style.transform = "translate(-50%, -50%)";
popup.style.backgroundColor = "#a08e9f";
popup.style.color = "#323046";
popup.style.padding = "20px";
popup.style.borderRadius = "10px";
popup.style.boxShadow = "0 2px 10px rgba(0, 0, 0, 0.3)";
popup.style.zIndex = "10000";
popup.style.fontFamily = "Helvetica, sans-serif";
popup.style.fontSize = "14px";
popup.style.width = "300px";
popup.style.textAlign = "center";
popup.innerHTML = \`
<h5 style="color: #fff; font-weight: bold; margin-top: 0;">🔑 Connexion à l'extension</h5>
<p style="margin: 15px 0;">
Après avoir renseigné vos identifiants, cliquez sur
<strong>"Se connecter avec BaLex"</strong>.
</p>
<button id="close-popup-btn" style="
width: 100%;
margin-top: 15px;
padding: 10px;
border: none;
background-color: #8d5c70;
color: #fbfcfc;
font-weight: bold;
cursor: pointer;
border-radius: 5px;
">Fermer</button>
\`;
document.body.appendChild(popup);
const closeBtn = document.getElementById("close-popup-btn");
closeBtn.onclick = () => popup.remove();
}
`
});
}
// ─────────────────────────────────────────────────────────────────────────────
// Gestion de l'activation/désactivation de l'extension
// ─────────────────────────────────────────────────────────────────────────────
// === 1. Initialisation de l'état de l'extension ===
async function initializeExtensionState() {
const { extensionActive } = await browser.storage.local.get("extensionActive");
if (extensionActive === undefined) {
await browser.storage.local.set({ extensionActive: true }); // Activation par défaut
log("🔄 Initialisation : extension activée par défaut.");
enableExtensionFeatures();
} else {
log(`🔄 État actuel de l'extension : ${extensionActive ? "activée" : "désactivée"}`);
if (extensionActive) {
enableExtensionFeatures();
} else {
disableExtensionFeatures();
}
}
}
// === 2. Gestion de l'activation/désactivation de l'extension ===
browser.runtime.onMessage.addListener(async (message) => {
if (message.action === "toggleExtension") {
log(`🔄 Changement d'état de l'extension : ${message.isActive ? "activée" : "désactivée"}`);
await browser.storage.local.set({ extensionActive: message.isActive });
if (!message.isActive) {
disableExtensionFeatures();
} else {
enableExtensionFeatures();
}
browser.runtime.sendMessage({ action: "updateUI" });
}
});
// === 3. Fonction pour désactiver les fonctionnalités de l'extension ===
async function disableExtensionFeatures() {
log("Désactivation des fonctionnalités de l'extension.");
browser.runtime.sendMessage({
action: "updateUI",
autoAdd: false,
isTrackingActive: false,
areStatsActive: false
});
// Suppression d'éventuelles actions spécifiques à la sidebar
log("Les fonctionnalités de la sidebar ne sont plus utilisées.");
}
// === 4. Fonction pour activer les fonctionnalités de l'extension ===
async function enableExtensionFeatures() {
log("Réactivation des fonctionnalités de l'extension.");
browser.runtime.sendMessage({
action: "updateUI",
autoAdd: true,
isTrackingActive: true,
areStatsActive: true
}).catch(err => {
console.warn("Aucun récepteur pour le message updateUI :", err);
});
}
initializeExtensionState();