pdf-accessibility/js/app.js
Vadym Samoilenko 112719b2c5 Add Docker stack, frontend redesign, and visual page inspector fix
- 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>
2026-02-25 18:12:44 +00:00

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();
});