Sure! Pl
This commit is contained in:
310
Extension/content/content-script.js
Normal file
310
Extension/content/content-script.js
Normal file
@@ -0,0 +1,310 @@
|
||||
// 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">🔒</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 });
|
||||
}
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user