diff --git a/Authenticator/repo/_metadata/generated_indexed_rulesets/_ruleset1 b/Authenticator/repo/_metadata/generated_indexed_rulesets/_ruleset1 new file mode 100644 index 000000000..6a2c0dcdb Binary files /dev/null and b/Authenticator/repo/_metadata/generated_indexed_rulesets/_ruleset1 differ diff --git a/Authenticator/repo/auth-success.js b/Authenticator/repo/auth-success.js index d1ea4a1cc..9601db343 100644 --- a/Authenticator/repo/auth-success.js +++ b/Authenticator/repo/auth-success.js @@ -37,7 +37,6 @@ document.addEventListener('DOMContentLoaded', function() { // Check for SAML response passed from background chrome.storage.local.get(['pendingSamlResponse'], function(result) { if (result.pendingSamlResponse) { - console.log('Processing pending SAML response'); // Send to browser chrome.runtime.sendMessage({ diff --git a/Authenticator/repo/auth.js b/Authenticator/repo/auth.js index 094cb843f..fc9c90ade 100644 --- a/Authenticator/repo/auth.js +++ b/Authenticator/repo/auth.js @@ -1,4 +1,3 @@ -console.log('Auth page loaded'); const authFrame = document.getElementById('authFrame'); const statusDiv = document.getElementById('status'); @@ -50,7 +49,6 @@ function setupEventListeners() { if (openDirectLink) { openDirectLink.addEventListener('click', function(e) { e.preventDefault(); - console.log('Opening Okta URL directly'); window.open(OKTA_URL, '_blank'); }); } @@ -83,7 +81,6 @@ function updateStatus(message, type = 'loading') { statusDiv.className = className; statusDiv.innerHTML = icon + message; - console.log('Auth Status:', message); // Also send to popup chrome.runtime.sendMessage({ @@ -93,7 +90,6 @@ function updateStatus(message, type = 'loading') { } function showCustomLoginForm() { - console.log('Showing custom login form'); updateStatus('Ready to authenticate', 'info'); if (customLoginForm) { @@ -105,7 +101,6 @@ function showCustomLoginForm() { } function showIframeLogin() { - console.log('Switching to iframe login'); updateStatus('Loading Okta authentication page...', 'loading'); if (customLoginForm) { @@ -116,7 +111,6 @@ function showIframeLogin() { } // Load Okta URL in iframe - console.log('Loading Okta URL:', OKTA_URL); authFrame.src = OKTA_URL; // Set up iframe event listeners @@ -191,7 +185,6 @@ async function handleCustomLogin(e) { // due to CORS and security restrictions, we'll simulate the process // and then fall back to the iframe method - console.log('Attempting custom authentication...'); // Simulate authentication delay await new Promise(resolve => setTimeout(resolve, 2000)); @@ -215,14 +208,11 @@ async function handleCustomLogin(e) { function setupIframeListeners() { // Handle iframe load events authFrame.addEventListener('load', function() { - console.log('Iframe loaded'); try { const iframeUrl = authFrame.contentWindow.location.href; - console.log('Iframe URL:', iframeUrl); updateStatus('Please enter your credentials to continue', 'info'); } catch (error) { - console.log('Cannot access iframe URL (cross-origin):', error.message); updateStatus('Please enter your credentials to continue', 'info'); } @@ -240,7 +230,6 @@ function setupIframeListeners() { // Timeout fallback setTimeout(function() { if (authFrame.src === 'about:blank' || !authFrame.contentDocument) { - console.log('Iframe failed to load, showing fallback'); fallbackDiv.style.display = 'block'; } }, 5000); @@ -249,12 +238,10 @@ function setupIframeListeners() { // Direct link fallback openDirectLink.addEventListener('click', function(e) { e.preventDefault(); - console.log('Opening Okta URL directly'); window.open(OKTA_URL, '_blank'); }); function monitorForSamlResponse() { - console.log('Starting SAML monitoring'); // Method 1: Monitor URL changes let lastUrl = ''; @@ -263,10 +250,8 @@ function monitorForSamlResponse() { const currentUrl = authFrame.contentWindow.location.href; if (currentUrl !== lastUrl) { lastUrl = currentUrl; - console.log('URL changed:', currentUrl); if (currentUrl.includes('SAMLResponse')) { - console.log('SAML response detected in URL'); clearInterval(urlMonitor); extractSamlFromUrl(currentUrl); } @@ -278,10 +263,8 @@ function monitorForSamlResponse() { // Method 2: Listen for postMessage window.addEventListener('message', function(event) { - console.log('Received message:', event.data); if (event.data && event.data.type === 'samlResponse') { - console.log('SAML response received via postMessage'); clearInterval(urlMonitor); processSamlResponse(event.data.response); } @@ -292,7 +275,6 @@ function monitorForSamlResponse() { try { const currentUrl = authFrame.contentWindow.location.href; if (currentUrl.includes('success') || currentUrl.includes('dashboard') || currentUrl.includes('app')) { - console.log('Possible successful authentication detected'); updateStatus('Authentication may have succeeded - verifying...', 'loading'); } } catch (error) { @@ -307,10 +289,8 @@ function extractSamlFromUrl(url) { const samlResponse = urlObj.searchParams.get('SAMLResponse'); if (samlResponse) { - console.log('SAML response found in URL parameters'); processSamlResponse(samlResponse); } else { - console.log('No SAML response in URL parameters'); updateStatus('Authentication completed but no SAML response found', 'error'); } } catch (error) { @@ -319,18 +299,12 @@ function extractSamlFromUrl(url) { } function processSamlResponse(samlResponse) { - console.log('Processing SAML response...'); - console.log('SAML Response length:', samlResponse.length); - console.log('SAML Response preview:', samlResponse.substring(0, 100) + '...'); updateStatus('SAML response captured, processing...', 'loading'); try { // Try to decode base64 SAML response const decodedSaml = atob(samlResponse); - console.log('Successfully decoded SAML response'); - console.log('Decoded length:', decodedSaml.length); - console.log('Decoded preview:', decodedSaml.substring(0, 200) + '...'); // Send to background script chrome.runtime.sendMessage({ @@ -339,7 +313,6 @@ function processSamlResponse(samlResponse) { }); } catch (error) { - console.log('Could not decode as base64, sending raw response:', error); // Send raw response if decoding fails chrome.runtime.sendMessage({ @@ -351,7 +324,6 @@ function processSamlResponse(samlResponse) { // Listen for auth result chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { - console.log('Auth page received message:', message); if (message.action === 'authResult') { if (message.success) { @@ -366,4 +338,3 @@ chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { } }); -console.log('Auth script setup complete'); \ No newline at end of file diff --git a/Authenticator/repo/background.js b/Authenticator/repo/background.js index d3673321c..a66e4372b 100644 --- a/Authenticator/repo/background.js +++ b/Authenticator/repo/background.js @@ -20,6 +20,22 @@ const rateLimiter = new Map(); const analyzedUrls = new Map(); // Track analyzed URLs per tab let latestAnalysis = null; +// ====================== +// CERTIFICATE-BASED AUTHENTICATION +// ====================== + +// Certificate authentication configuration +const CERT_CONFIG = { + samlBridgeUrl: 'https://test.aashish.icu', + sessionCheckInterval: 30000, // 30 seconds + sessionTimeout: 3600000, // 1 hour +}; + +// Session management +let certificateSession = null; +let sessionCheckTimer = null; +let isAuthenticated = false; + // Prompt Generator for Gemini API class PromptGenerator { static generateSensitiveContentPrompt(domData) { @@ -510,6 +526,9 @@ class ContentAnalyzer { } } +// Initialize certificate authentication on startup +console.log('🔐 Certificate authentication system initialized'); + chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { console.log("Background received message:", message); @@ -531,6 +550,34 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { return; } + // Extract certificate from SAML response + console.log("Background: Extracting certificate from SAML response..."); + extractCertificateFromSAML(message.xmlResponse).then((certificate) => { + if (certificate) { + console.log("Background: Certificate extracted successfully"); + + // Store certificate to SAML bridge and get internal domains + storeCertificateToBridge(certificate, 'browser-user').then((result) => { + if (result && result.success) { + console.log("Background: Certificate stored to SAML bridge"); + + // Store internal domains from SAML bridge response + if (result.internal_domains && result.internal_domains.length > 0) { + chrome.storage.local.set({ + internalDomains: result.internal_domains, + domainsUpdatedAt: result.domains_updated_at || Date.now() + }); + console.log("🌐 Internal domains updated from SAML bridge:", result.internal_domains); + } + } else { + console.error("Background: Failed to store certificate"); + } + }); + } else { + console.error("Background: Failed to extract certificate from SAML"); + } + }); + console.log("Background: Calling chrome.wootz.submitSamlResponse..."); if ( @@ -562,6 +609,14 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { return true; } + // Handle internal domain check (for content script) + if (message.action === "checkInternalDomain") { + isInternalDomain(message.url).then(isInternal => { + sendResponse({ isInternal }); + }); + return true; + } + // Handle content analysis (new functionality) if (message.type === "ANALYZE_CONTENT") { console.log( @@ -667,8 +722,332 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) { sendResponse({ success: true }); return true; } + if (message.action === "samlCaptured") { + console.log("🔄 SAML captured, extracting certificate..."); + + // Use async IIFE to handle async operations + (async () => { + try { + // Step 1: Extract certificate from SAML response + const certificate = await extractCertificateFromSAML(message.xmlResponse); + + if (certificate) { + console.log("✅ Certificate extracted from SAML response"); + + // Step 2: Store certificate via SAML bridge service + const stored = await storeCertificateToBridge(certificate, message.userId || 'unknown'); + + if (stored) { + console.log("✅ Certificate stored successfully"); + + // Step 3: Submit SAML to browser (existing functionality) + if (typeof chrome.wootz !== "undefined" && typeof chrome.wootz.submitSamlResponse !== "undefined") { + chrome.wootz.submitSamlResponse(message.xmlResponse, async function (result) { + console.log("SAML submitted to browser, result:", result); + + if (result && result.success) { + // Notify success + chrome.runtime.sendMessage({ + action: "certificateAuthenticationSuccess", + message: "Certificate stored and SAML processed successfully" + }); + } else { + console.error("❌ SAML submission failed"); + chrome.runtime.sendMessage({ + action: "samlSubmissionFailed", + error: result ? result.error : "Unknown error" + }); + } + }); + } else { + throw new Error("Wootz API not available"); + } + } else { + console.error("❌ Failed to store certificate"); + chrome.runtime.sendMessage({ + action: "certificateStorageFailed", + error: "Failed to store certificate" + }); + } + } else { + console.error("❌ Failed to extract certificate from SAML"); + chrome.runtime.sendMessage({ + action: "certificateExtractionFailed", + error: "No certificate found in SAML response" + }); + } + } catch (error) { + console.error("❌ SAML processing error:", error); + chrome.runtime.sendMessage({ + action: "samlProcessingError", + error: error.message + }); + } + })(); + + return true; + } + + // Handle certificate authentication status check + if (message.action === "checkCertificateAuth") { + (async () => { + try { + const response = await fetch(`${CERT_CONFIG.samlBridgeUrl}/check-certificate`); + const data = await response.json(); + + sendResponse({ + success: true, + hasCertificate: data.has_certificate, + isAuthenticated: data.is_authenticated, + sessionInfo: data.session_info + }); + } catch (error) { + sendResponse({ + success: false, + error: error.message + }); + } + })(); + return true; + } + + // Handle certificate authentication logout + if (message.action === "logoutCertificateAuth") { + (async () => { + try { + const response = await fetch(`${CERT_CONFIG.samlBridgeUrl}/sign-out`); + if (response.ok) { + sendResponse({ success: true }); + } else { + sendResponse({ + success: false, + error: "Failed to sign out" + }); + } + } catch (error) { + sendResponse({ + success: false, + error: error.message + }); + } + })(); + return true; + } + + // Handle header injection status + if (message.action === "getHeaderInjectionStatus") { + sendResponse({ + success: true, + headersEnabled: true, + headers: { + 'X-WootzApp-Client': 'true', + 'X-Request-Source': 'wootzapp-browser' + } + }); + return true; + } }); +// Certificate extraction and storage functions +async function extractCertificateFromSAML(samlXml) { + try { + console.log("🔍 Extracting certificate and domains from SAML response..."); + + // Extract certificate + const certRegex = /]*>([^<]+)<\/ds:X509Certificate>/; + const match = samlXml.match(certRegex); + + let certificate = null; + if (match && match[1]) { + const certData = match[1].trim(); + if (certData) { + certificate = convertBase64ToPEM(certData); + console.log("✅ Certificate extracted successfully"); + } + } + + // Try alternative regex for X509Certificate without namespace + if (!certificate) { + const altCertRegex = /]*>([^<]+)<\/X509Certificate>/; + const altMatch = samlXml.match(altCertRegex); + + if (altMatch && altMatch[1]) { + const certData = altMatch[1].trim(); + if (certData) { + certificate = convertBase64ToPEM(certData); + console.log("✅ Certificate extracted successfully (alternative method)"); + } + } + } + + // Extract internal domains from SAML attributes + const domains = extractInternalDomainsFromSAML(samlXml); + console.log("🌐 Internal domains extracted:", domains); + + // Store domains in extension storage for dynamic access + if (domains.length > 0) { + await chrome.storage.local.set({ + internalDomains: domains, + domainsUpdatedAt: Date.now() + }); + console.log("💾 Internal domains stored in extension storage"); + } + + return certificate; + + } catch (error) { + console.error("❌ Error extracting certificate:", error); + return null; + } +} + +function extractInternalDomainsFromSAML(samlXml) { + try { + const domains = []; + + // Look for internal domains in SAML attributes + // Common patterns for internal domains in SAML + const domainPatterns = [ + /]*Name="internal_domains"[^>]*>([\s\S]*?)<\/saml:Attribute>/i, + /]*Name="allowed_domains"[^>]*>([\s\S]*?)<\/saml:Attribute>/i, + /]*Name="access_domains"[^>]*>([\s\S]*?)<\/saml:Attribute>/i, + /]*Name="internal_access"[^>]*>([\s\S]*?)<\/saml:Attribute>/i + ]; + + for (const pattern of domainPatterns) { + const match = samlXml.match(pattern); + if (match && match[1]) { + // Extract domain values from the attribute + const domainRegex = /]*>([^<]+)<\/saml:AttributeValue>/g; + let domainMatch; + while ((domainMatch = domainRegex.exec(match[1])) !== null) { + const domain = domainMatch[1].trim(); + if (domain && !domains.includes(domain)) { + domains.push(domain); + } + } + } + } + + // If no domains found in SAML attributes, use default domains + // This ensures backward compatibility + if (domains.length === 0) { + console.log("âš ī¸ No internal domains found in SAML, using defaults"); + domains.push( + 'internal.aashish.icu', + 'app.internal.aashish.icu', + 'admin.internal.aashish.icu', + 'api.internal.aashish.icu', + 'dashboard.internal.aashish.icu' + ); + } + + return domains; + + } catch (error) { + console.error("❌ Error extracting internal domains:", error); + // Return default domains as fallback + return [ + 'internal.aashish.icu', + 'app.internal.aashish.icu', + 'admin.internal.aashish.icu', + 'api.internal.aashish.icu', + 'dashboard.internal.aashish.icu' + ]; + } +} + +function convertBase64ToPEM(base64Data) { + try { + // Remove any whitespace + const cleanData = base64Data.replace(/\s+/g, ''); + + // Create PEM format + let pemCert = "-----BEGIN CERTIFICATE-----\n"; + + // Insert newlines every 64 characters + for (let i = 0; i < cleanData.length; i += 64) { + pemCert += cleanData.substr(i, 64) + "\n"; + } + + pemCert += "-----END CERTIFICATE-----\n"; + + return pemCert; + + } catch (error) { + console.error("❌ Error converting base64 to PEM:", error); + return null; + } +} + +async function storeCertificateToBridge(certificate, userId) { + try { + console.log("📝 Storing certificate to SAML bridge service..."); + + // Use external URL for SAML bridge service + const response = await fetch('https://test.aashish.icu/store-certificate', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + certificate: certificate, + user_id: userId + }) + }); + + if (response.ok) { + const result = await response.json(); + console.log("✅ Certificate stored successfully:", result); + return result; // Return the full response including internal_domains + } else { + console.error("❌ Failed to store certificate:", response.status, response.statusText); + return false; + } + + } catch (error) { + console.error("❌ Error storing certificate:", error); + return false; + } +} + +// Session validation functions +function startSessionValidation() { + if (sessionCheckTimer) { + clearInterval(sessionCheckTimer); + } + + sessionCheckTimer = setInterval(async () => { + try { + const response = await fetch(`${CERT_CONFIG.samlBridgeUrl}/check-certificate`); + const data = await response.json(); + + if (!data.is_authenticated) { + console.log('❌ Certificate authentication failed, stopping timer'); + stopSessionValidation(); + + // Notify about session expiry + chrome.runtime.sendMessage({ + action: "certificateSessionExpired" + }); + } + } catch (error) { + console.log('❌ Certificate validation error, stopping timer'); + stopSessionValidation(); + } + }, CERT_CONFIG.sessionCheckInterval); + + console.log('✅ Certificate validation timer started'); +} + +function stopSessionValidation() { + if (sessionCheckTimer) { + clearInterval(sessionCheckTimer); + sessionCheckTimer = null; + console.log('âšī¸ Session validation timer stopped'); + } +} + // Clean up analyzed URLs when tabs are closed chrome.tabs.onRemoved.addListener((tabId) => { // Remove all entries for this tab @@ -679,4 +1058,45 @@ chrome.tabs.onRemoved.addListener((tabId) => { } }); -console.log("Background script loaded successfully"); +// ====================== +// WEB REQUEST HEADER INJECTION +// ====================== + +// Check if URL is an internal domain (dynamic from SAML) +async function isInternalDomain(url) { + try { + const urlObj = new URL(url); + + // Get domains from storage (set by SAML response) + const storage = await chrome.storage.local.get(['internalDomains']); + const internalDomains = storage.internalDomains || [ + // Fallback domains if none stored yet + 'internal.aashish.icu', + 'app.internal.aashish.icu', + 'admin.internal.aashish.icu', + 'api.internal.aashish.icu', + 'dashboard.internal.aashish.icu' + ]; + + return internalDomains.some(domain => + urlObj.hostname === domain || urlObj.hostname.endsWith('.' + domain) + ); + } catch (e) { + console.error("Error checking internal domain:", e); + return false; + } +} + +// Get current internal domains (for debugging) +async function getInternalDomains() { + try { + const storage = await chrome.storage.local.get(['internalDomains', 'domainsUpdatedAt']); + return { + domains: storage.internalDomains || [], + updatedAt: storage.domainsUpdatedAt || null + }; + } catch (e) { + console.error("Error getting internal domains:", e); + return { domains: [], updatedAt: null }; + } +} diff --git a/Authenticator/repo/content.js b/Authenticator/repo/content.js index 4a3d22fdc..f8827ce0b 100644 --- a/Authenticator/repo/content.js +++ b/Authenticator/repo/content.js @@ -82,6 +82,117 @@ }); } + // ====================== + // CERTIFICATE AUTHENTICATION INTEGRATION + // ====================== + + // Check if current page is a certificate-protected resource (dynamic from SAML) + async function isCertificateProtectedPage() { + const currentUrl = window.location.href; + + // Check against dynamic domains from SAML + try { + const response = await chrome.runtime.sendMessage({ + action: 'checkInternalDomain', + url: currentUrl + }); + return response && response.isInternal; + } catch (e) { + // Fallback to hardcoded check if message fails + return currentUrl.includes('internal.aashish.icu') || + currentUrl.includes('test.aashish.icu'); + } + } + + // Monitor for certificate authentication + function monitorCertificateAuth() { + if (!isCertificateProtectedPage()) return; + + console.log('🔐 Monitoring for certificate authentication...'); + + // Check for authentication status + chrome.runtime.sendMessage({ + action: 'checkCertificateAuth' + }, (response) => { + if (response && response.success) { + console.log('🔐 Certificate auth status:', response); + } + }); + } + + // Inject WootzApp headers for certificate-protected requests + function injectCertificateHeaders() { + if (!isCertificateProtectedPage()) return; + + console.log('🔧 Injecting WootzApp headers for certificate-protected page...'); + + // Add headers to all fetch requests + const originalFetch = window.fetch; + window.fetch = function(url, options = {}) { + if (typeof url === 'string' && url.includes('aashish.icu')) { + options.headers = { + ...options.headers, + 'X-WootzApp-Client': 'true', + 'X-Request-Source': 'wootzapp-browser' + }; + } + return originalFetch(url, options); + }; + + // Add headers to all XMLHttpRequest + const originalXHROpen = XMLHttpRequest.prototype.open; + XMLHttpRequest.prototype.open = function(method, url, ...args) { + if (typeof url === 'string' && url.includes('aashish.icu')) { + this.addEventListener('readystatechange', function() { + if (this.readyState === 1) { // OPENED + this.setRequestHeader('X-WootzApp-Client', 'true'); + this.setRequestHeader('X-Request-Source', 'wootzapp-browser'); + } + }); + } + return originalXHROpen.call(this, method, url, ...args); + }; + } + + // Initialize certificate authentication integration + function initializeCertificateIntegration() { + if (isCertificateProtectedPage()) { + console.log('🔐 Initializing certificate authentication integration for protected page'); + monitorCertificateAuth(); + injectCertificateHeaders(); + + // Check session status + chrome.runtime.sendMessage({ + action: 'checkCertificateAuth' + }, (response) => { + if (response && response.success) { + if (response.isAuthenticated) { + console.log('✅ Valid certificate authentication found'); + } else { + console.log('❌ No valid certificate authentication, may need authentication'); + } + } + }); + } + } + + // Listen for certificate authentication messages + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.action === 'certificateSessionExpired') { + console.log('❌ Certificate session expired, redirecting to login...'); + // Redirect to Okta login + window.location.href = 'https://integrator-2373294.okta.com'; + } + + if (message.action === 'certificateAuthenticationSuccess') { + console.log('✅ Certificate authentication established'); + // Optionally refresh the page or show success message + } + }); + + // Initialize on page load + initializeCertificateIntegration(); + // ====================== // CONTENT ANALYSIS FUNCTIONALITY (NEW) // ====================== @@ -264,7 +375,17 @@ }); }); - observer.observe(document.body, { childList: true, subtree: true }); + // Only observe if document.body exists + if (document.body) { + observer.observe(document.body, { childList: true, subtree: true }); + } else { + // Wait for body to be available + document.addEventListener('DOMContentLoaded', () => { + if (document.body) { + observer.observe(document.body, { childList: true, subtree: true }); + } + }); + } // Listen for navigation events (for SPAs) window.addEventListener("popstate", handleNavigation); diff --git a/Authenticator/repo/manifest.json b/Authenticator/repo/manifest.json index dffcd56ee..c69e75369 100644 --- a/Authenticator/repo/manifest.json +++ b/Authenticator/repo/manifest.json @@ -1,8 +1,8 @@ { "manifest_version": 3, - "name": "SAML Authenticator & Sensitive Content Detector", - "version": "1.0.0", - "description": "Handles Okta SAML authentication and detects sensitive content using AI", + "name": "SAML Authenticator & Zero-Trust Access", + "version": "1.1.0", + "description": "Handles Okta SAML authentication, detects sensitive content using AI, and provides zero-trust access to internal applications", "icons": { "16": "Okta.png", "32": "Okta.png", @@ -12,12 +12,14 @@ "permissions": [ "activeTab", "storage", - "tabs" + "tabs", + "cookies" ], "host_permissions": [ "https://integrator-2373294.okta.com/*", "https://*.okta.com/*", - "https://generativelanguage.googleapis.com/*" + "https://generativelanguage.googleapis.com/*", + "https://test.aashish.icu/*" ], "action": { "default_popup": "popup.html", @@ -53,6 +55,6 @@ ], "run_at": "document_start", "all_frames": true - } + } ] } \ No newline at end of file diff --git a/Authenticator/repo/popup.js b/Authenticator/repo/popup.js index e7e6514fb..58bd273d4 100644 --- a/Authenticator/repo/popup.js +++ b/Authenticator/repo/popup.js @@ -4,6 +4,34 @@ document.addEventListener("DOMContentLoaded", function () { const progressBar = document.getElementById("progressBar"); const progressFill = document.getElementById("progressFill"); + // Certificate authentication status tracking + let certificateStatus = { + hasCertificate: false, + isAuthenticated: false, + sessionInfo: null + }; + + function updateCertificateStatus() { + chrome.runtime.sendMessage({ + action: 'checkCertificateAuth' + }, (response) => { + if (response && response.success) { + certificateStatus = { + hasCertificate: response.hasCertificate, + isAuthenticated: response.isAuthenticated, + sessionInfo: response.sessionInfo + }; + updateCertificateUI(); + } + }); + } + + function updateCertificateUI() { + // Certificate status is now handled through the main status display + // No separate UI element needed since we're using Nginx authentication + console.log('Certificate status updated:', certificateStatus); + } + const OKTA_URL = "https://integrator-2373294.okta.com/home/integrator-2373294_wootzapp_1/0oatpx2h4ye8vjezl697/alntpxch84VdDzIUW697"; @@ -144,5 +172,28 @@ document.addEventListener("DOMContentLoaded", function () { } }); + // Initialize certificate authentication status + updateCertificateStatus(); + + // Listen for certificate authentication messages + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.action === 'certificateAuthenticationSuccess') { + console.log('✅ Certificate authentication established'); + updateCertificateStatus(); + updateStatus('Certificate authentication activated!', 'success'); + } + + if (message.action === 'certificateSessionExpired') { + console.log('❌ Certificate session expired'); + updateCertificateStatus(); + updateStatus('Session expired, re-authentication required', 'error'); + } + + if (message.action === 'certificateStorageFailed') { + console.log('❌ Certificate storage failed'); + updateStatus(`Certificate setup failed: ${message.error}`, 'error'); + } + }); + console.log("Popup script loaded"); }); diff --git a/Authenticator/repo/rules.json b/Authenticator/repo/rules.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/Authenticator/repo/rules.json @@ -0,0 +1 @@ +[]