Files
eship/Extension/content/content-script.js
2026-01-17 17:07:46 +01:00

311 lines
8.5 KiB
JavaScript

// EShip Extension Content Script
// Injects into protected website to enforce auth and apply tools
(function() {
'use strict';
// State
let isAuthenticated = false;
let currentTools = [];
let blockedOverlay = null;
// Initialize on page load
init();
async function init() {
// Check auth status immediately
const authResponse = await sendMessage({ action: 'CHECK_AUTH' });
if (authResponse.success && authResponse.authenticated) {
isAuthenticated = true;
await loadAndApplyTools();
} else {
isAuthenticated = false;
showBlockedScreen();
}
// Listen for messages from service worker (settings updates)
chrome.runtime.onMessage.addListener(handleMessage);
}
// Send message to service worker
function sendMessage(message) {
return new Promise((resolve) => {
chrome.runtime.sendMessage(message, (response) => {
if (chrome.runtime.lastError) {
resolve({ success: false, error: chrome.runtime.lastError.message });
} else {
resolve(response || { success: false, error: 'No response' });
}
});
});
}
// Handle incoming messages
function handleMessage(request, sender, sendResponse) {
switch (request.action) {
case 'SETTINGS_UPDATED':
currentTools = request.tools;
applyTools();
sendResponse({ success: true });
break;
case 'AUTH_CHANGED':
if (request.authenticated) {
isAuthenticated = true;
hideBlockedScreen();
loadAndApplyTools();
} else {
isAuthenticated = false;
showBlockedScreen();
}
sendResponse({ success: true });
break;
}
return true;
}
// Show blocked screen when not authenticated
function showBlockedScreen() {
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', createBlockedOverlay);
} else {
createBlockedOverlay();
}
}
function createBlockedOverlay() {
// Remove existing overlay if any
hideBlockedScreen();
// Create overlay
blockedOverlay = document.createElement('div');
blockedOverlay.id = 'eship-blocked-overlay';
blockedOverlay.innerHTML = `
<style>
#eship-blocked-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 999999;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
#eship-blocked-overlay .blocked-icon {
font-size: 64px;
margin-bottom: 24px;
}
#eship-blocked-overlay h1 {
color: #FD366E;
font-size: 28px;
margin: 0 0 16px 0;
font-weight: 600;
}
#eship-blocked-overlay p {
color: #9ca3af;
font-size: 16px;
margin: 0 0 32px 0;
text-align: center;
max-width: 400px;
line-height: 1.6;
}
#eship-blocked-overlay .instructions {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
padding: 24px;
max-width: 400px;
}
#eship-blocked-overlay .instructions h2 {
color: #fff;
font-size: 14px;
margin: 0 0 16px 0;
text-transform: uppercase;
letter-spacing: 1px;
}
#eship-blocked-overlay .instructions ol {
color: #d1d5db;
font-size: 14px;
margin: 0;
padding-left: 20px;
line-height: 2;
}
#eship-blocked-overlay .instructions li {
margin-bottom: 4px;
}
</style>
<div class="blocked-icon">&#128274;</div>
<h1>Zugriff gesperrt</h1>
<p>Diese Website ist geschuetzt und erfordert eine Authentifizierung ueber die EShip Browser-Extension.</p>
<div class="instructions">
<h2>So melden Sie sich an:</h2>
<ol>
<li>Klicken Sie auf das EShip-Icon in der Browser-Toolbar</li>
<li>Geben Sie Ihre E-Mail und Passwort ein</li>
<li>Klicken Sie auf "Anmelden"</li>
<li>Die Seite wird automatisch freigeschaltet</li>
</ol>
</div>
`;
document.body.appendChild(blockedOverlay);
// Prevent scrolling on body
document.body.style.overflow = 'hidden';
}
// Hide blocked screen
function hideBlockedScreen() {
if (blockedOverlay) {
blockedOverlay.remove();
blockedOverlay = null;
document.body.style.overflow = '';
}
}
// Load and apply tool settings
async function loadAndApplyTools() {
const response = await sendMessage({ action: 'GET_SETTINGS' });
if (response.success) {
currentTools = response.tools;
applyTools();
}
}
// Apply all enabled tools
function applyTools() {
if (!isAuthenticated) return;
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => executeTools());
} else {
executeTools();
}
}
function executeTools() {
currentTools.forEach(tool => {
if (tool.enabled) {
applyTool(tool);
} else {
removeTool(tool);
}
});
}
// Apply a specific tool
function applyTool(tool) {
switch (tool.id) {
case 'highlight_prices':
applyHighlightPrices(tool.settings);
break;
// Add more tools here as needed
default:
console.log('[EShip] Unknown tool:', tool.id);
}
}
// Remove a specific tool's effects
function removeTool(tool) {
switch (tool.id) {
case 'highlight_prices':
removeHighlightPrices(tool.settings);
break;
default:
break;
}
}
// ============================================
// TOOL: Highlight Prices
// ============================================
function applyHighlightPrices(settings) {
const selector = settings.selector || '.price';
const borderColor = settings.borderColor || '#ff0000';
const borderWidth = settings.borderWidth || '2px';
// Add custom style if not exists
let styleEl = document.getElementById('eship-highlight-prices-style');
if (!styleEl) {
styleEl = document.createElement('style');
styleEl.id = 'eship-highlight-prices-style';
document.head.appendChild(styleEl);
}
styleEl.textContent = `
${selector} {
border: ${borderWidth} solid ${borderColor} !important;
box-shadow: 0 0 8px ${borderColor}40 !important;
border-radius: 4px !important;
padding: 2px 4px !important;
transition: all 0.2s ease !important;
}
`;
// Also add data attribute to track highlighted elements
document.querySelectorAll(selector).forEach(el => {
el.dataset.eshipHighlighted = 'true';
});
console.log('[EShip] Highlight Prices applied with selector:', selector);
}
function removeHighlightPrices(settings) {
// Remove style element
const styleEl = document.getElementById('eship-highlight-prices-style');
if (styleEl) {
styleEl.remove();
}
// Remove data attributes
document.querySelectorAll('[data-eship-highlighted]').forEach(el => {
delete el.dataset.eshipHighlighted;
});
console.log('[EShip] Highlight Prices removed');
}
// ============================================
// Mutation Observer for dynamic content
// ============================================
// Re-apply tools when new content is added
const observer = new MutationObserver((mutations) => {
if (!isAuthenticated) return;
let shouldReapply = false;
mutations.forEach(mutation => {
if (mutation.addedNodes.length > 0) {
shouldReapply = true;
}
});
if (shouldReapply) {
// Debounce reapplication
clearTimeout(observer.timeout);
observer.timeout = setTimeout(() => {
applyTools();
}, 100);
}
});
// Start observing once DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
observer.observe(document.body, { childList: true, subtree: true });
});
} else {
observer.observe(document.body, { childList: true, subtree: true });
}
})();