- Redesigned frontend with Outfit/Figtree typography, coral accent palette, noise texture, glassmorphism header, and staggered animations - Split monolithic index.html into modular JS (app, api, upload, batch, results, page-viewer, utils) and extracted CSS - Fixed worker.py to generate page images for Visual Page Inspector - Added Docker Compose stack (web, worker, redis, postgres) - Added batch upload, HTML report export, rate limiting, and Redis queue - Extended test suite with checker, remediation, worker, and DB tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
123 lines
3.5 KiB
JavaScript
123 lines
3.5 KiB
JavaScript
/* 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://alcdn.msauth.net/browser/2.38.3/js/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';
|
|
}
|
|
|
|
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();
|
|
});
|