Files
eship/Extension/content-script.js

198 lines
6.5 KiB
JavaScript

// Content Script läuft auf der Web-App-Seite
// Lauscht auf window.postMessage von der Web-App und leitet an Background weiter
const MESSAGE_SOURCE = "eship-webapp";
// Markiere Extension als verfügbar - MEHRFACH versuchen, da Timing variieren kann
function setExtensionFlag() {
try {
const hasChrome = typeof chrome !== 'undefined';
const hasRuntime = hasChrome && chrome.runtime;
const runtimeId = hasRuntime ? chrome.runtime.id : null;
if (typeof window !== 'undefined' && hasChrome && hasRuntime && runtimeId) {
// WICHTIG: Content Scripts haben einen isolierten Context
// window.__EBAY_EXTENSION__ wird im Content Script Context gesetzt,
// aber die Web-App läuft im Page Context - diese sind getrennt!
// Daher verlassen wir uns hauptsächlich auf postMessage
window.__EBAY_EXTENSION__ = true;
window.__EBAY_EXTENSION_ID__ = runtimeId; // Extension-ID für chrome.runtime.sendMessage
console.log('[ESHIP-CONTENT] window.__EBAY_EXTENSION__ set to true, ID:', runtimeId);
return true;
}
} catch (e) {
console.error('[ESHIP-CONTENT] Error setting flag:', e);
}
return false;
}
// Versuche Flag sofort zu setzen
console.log('[ESHIP-CONTENT] Content script loaded');
console.log('[ESHIP-CONTENT] URL:', window.location.href);
console.log('[ESHIP-CONTENT] ReadyState:', document.readyState);
if (!setExtensionFlag()) {
// Wenn window nicht verfügbar, warte auf DOMContentLoaded oder document.readyState
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
setExtensionFlag();
});
} else {
// DOM ist bereits geladen, versuche nochmal
setTimeout(() => {
setExtensionFlag();
}, 0);
}
} else {
}
// Sende Extension-ID an Web-App via postMessage (da Content Script Isolation verhindert, dass window-Properties geteilt werden)
// Die Web-App kann dann die Extension-ID in ihrem eigenen Context speichern
function sendExtensionIdToWebApp() {
try {
const runtimeId = chrome.runtime?.id;
const hasRuntime = !!chrome.runtime;
const hasId = !!runtimeId;
const currentUrl = window.location.href;
if (runtimeId) {
const message = {
source: "eship-extension",
type: "EXTENSION_ID",
extensionId: runtimeId
};
// Sende Extension-ID an Web-App
window.postMessage(message, "*");
} else {
}
} catch (e) {
console.error('[ESHIP-CONTENT] Error sending extension ID:', e);
}
}
// Sende Extension-ID sofort beim Laden (wichtig für Seiten-Reload)
sendExtensionIdToWebApp();
// Sende auch nach kurzen Verzögerungen (falls Web-App noch nicht bereit ist)
setTimeout(sendExtensionIdToWebApp, 100);
setTimeout(sendExtensionIdToWebApp, 500);
setTimeout(sendExtensionIdToWebApp, 1000);
setTimeout(sendExtensionIdToWebApp, 2000);
// Kontinuierlich postMessage senden, damit die Web-App die Extension erkennen kann
// (auch wenn der User die Extension NACH dem Laden der Seite installiert)
let extensionAnnounceInterval = setInterval(() => {
sendExtensionIdToWebApp();
}, 2000); // Alle 2 Sekunden senden
// Stoppe das Intervall nach 5 Minuten (um Ressourcen zu sparen, aber lange genug für Onboarding)
setTimeout(() => {
if (extensionAnnounceInterval) {
clearInterval(extensionAnnounceInterval);
extensionAnnounceInterval = null;
}
}, 300000); // 5 Minuten
window.addEventListener("message", (event) => {
// PING_EXTENSION Handler: Web-App fragt aktiv nach Extension
// Akzeptiere sowohl "eship-webapp" als auch "eship-webapp-page-context"
if ((event.data?.source === MESSAGE_SOURCE || event.data?.source === "eship-webapp-page-context") && event.data?.type === "PING_EXTENSION") {
// Verwende console.log als Fallback, da fetch möglicherweise fehlschlägt
console.log('[ESHIP-CONTENT] Received PING_EXTENSION, responding...', event.data);
// Antworte sofort mit Extension-ID
const runtimeId = chrome.runtime?.id;
console.log('[ESHIP-CONTENT] Runtime ID:', runtimeId);
if (runtimeId) {
const response = {
source: "eship-extension",
type: "EXTENSION_ID",
extensionId: runtimeId,
requestId: event.data?.requestId
};
console.log('[ESHIP-CONTENT] Sending response:', response);
window.postMessage(response, "*");
// Setze user_extension_load auf true im Backend
// Hole JWT aus Storage und sende an Backend
chrome.storage.local.get("auth_jwt").then((data) => {
const jwt = data.auth_jwt;
if (jwt) {
// Backend-Endpoint aufrufen
fetch("http://localhost:3000/api/user/set-extension-loaded", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${jwt}`
}
})
.then(res => res.json())
.then(result => {
console.log('[ESHIP-CONTENT] user_extension_load set to true:', result);
})
.catch(err => {
console.error('[ESHIP-CONTENT] Failed to set user_extension_load:', err);
});
} else {
console.warn('[ESHIP-CONTENT] No JWT found, cannot set user_extension_load');
}
});
} else {
console.error('[ESHIP-CONTENT] No runtime ID available!');
}
return;
}
// Sicherheitscheck: Nur Nachrichten von derselben Origin akzeptieren
if (event.data?.source !== MESSAGE_SOURCE && event.data?.source !== "eship-webapp-page-context") return;
// Auth Messages (JWT)
if (event.data.type === "AUTH_JWT" || event.data.type === "AUTH_CLEARED") {
chrome.runtime.sendMessage(
{
type: event.data.type,
jwt: event.data.jwt,
},
(response) => {
// Antwort zurück an Web-App senden
window.postMessage(
{
source: "eship-extension",
type: event.data.type,
response: response,
},
"*"
);
}
);
return;
}
// eBay Parsing Request (PARSE_URL)
if (event.data.action === "PARSE_URL" && event.data.url) {
chrome.runtime.sendMessage(
{
action: "PARSE_URL",
url: event.data.url,
},
(response) => {
// Antwort zurück an Web-App senden
window.postMessage(
{
source: "eship-extension",
messageId: event.data.messageId,
ok: response?.ok,
data: response?.data,
error: response?.error,
},
"*"
);
}
);
return;
}
});