/* App initialization and MSAL authentication */ // MSAL configuration const msalConfig = { auth: { clientId: '', // Set from data attribute or env authority: '', redirectUri: window.location.origin + window.location.pathname }, cache: { cacheLocation: 'localStorage', storeAuthStateInCookie: false } }; let msalInstance = null; window.msalToken = null; function initMsal() { const el = document.getElementById('msalConfig'); if (!el) return; const tenantId = el.dataset.tenantId; const clientId = el.dataset.clientId; const redirectUri = el.dataset.redirectUri; if (!tenantId || !clientId) return; msalConfig.auth.clientId = clientId; msalConfig.auth.authority = `https://login.microsoftonline.com/${tenantId}`; if (redirectUri) msalConfig.auth.redirectUri = redirectUri; // Load MSAL library dynamically const script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/@azure/msal-browser@2/lib/msal-browser.min.js'; script.onload = () => { msalInstance = new msal.PublicClientApplication(msalConfig); msalInstance.initialize().then(() => { handleMsalRedirect(); }); }; document.head.appendChild(script); } async function handleMsalRedirect() { try { const response = await msalInstance.handleRedirectPromise(); if (response) { window.msalToken = response.accessToken; showAuthenticatedUI(response.account); return; } } catch (e) { console.error('MSAL redirect error:', e); } // Check for existing session const accounts = msalInstance.getAllAccounts(); if (accounts.length > 0) { try { const tokenResponse = await msalInstance.acquireTokenSilent({ scopes: ['User.Read'], account: accounts[0] }); window.msalToken = tokenResponse.accessToken; showAuthenticatedUI(accounts[0]); } catch (e) { // Token expired, show login showLoginUI(); } } else { // Check if we're in dev mode (localhost) — skip MSAL if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { hideAuthOverlay(); } else { showLoginUI(); } } } function showLoginUI() { const overlay = document.getElementById('authOverlay'); if (overlay) overlay.classList.add('active'); } function hideAuthOverlay() { const overlay = document.getElementById('authOverlay'); if (overlay) overlay.classList.remove('active'); } function showAuthenticatedUI(account) { hideAuthOverlay(); const userInfo = document.getElementById('userInfo'); if (userInfo && account) { userInfo.textContent = account.name || account.username; } const logoutBtn = document.getElementById('logoutBtn'); if (logoutBtn) logoutBtn.style.display = 'inline-block'; // Show My Documents link in header const historyLink = document.getElementById('historyLink'); if (historyLink) historyLink.style.display = 'inline-block'; // If URL has ?job_id= open that report directly const params = new URLSearchParams(window.location.search); const jobId = params.get('job_id'); if (jobId) openHistoryJob(jobId); } async function openHistoryJob(jobId) { currentJobId = jobId; const uploadSection = document.getElementById('uploadSection'); const resultsSection = document.getElementById('resultsSection'); if (uploadSection) uploadSection.style.display = 'none'; if (resultsSection) resultsSection.style.display = ''; try { const resp = await getResult(jobId); const result = resp?.data || resp; if (!result || result.error) { alert('Could not load report: ' + (result?.error || 'Unknown error')); return; } displayResults(result); if (resultsSection) resultsSection.scrollIntoView({ behavior: 'smooth' }); } catch (e) { console.error('openHistoryJob failed:', e); alert('Failed to load report.'); } } async function loginWithMicrosoft() { if (!msalInstance) return; try { await msalInstance.loginRedirect({ scopes: ['User.Read'] }); } catch (e) { console.error('Login failed:', e); alert('Login failed. Please try again.'); } } function logout() { if (msalInstance) { msalInstance.logoutRedirect(); } } /* App init */ document.addEventListener('DOMContentLoaded', () => { loadTheme(); initUpload(); initBatchUpload(); initMsal(); });