fix(csp): remove all inline styles, scripts, and event handlers for strict CSP compliance
Replace ~50 inline style="" attributes with CSS classes, move 3 inline
<script> blocks to external JS files, replace all inline event handlers
(onclick, onerror) with addEventListener, and remove createElement('style')
from icons.js. All changes support the strict CSP policy (style-src 'self';
script-src 'self') without weakening it.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
// Read error type from URL query parameter
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var errorType = params.get('type') || 'generic';
|
||||
|
||||
var errorTitle = document.getElementById('error-title');
|
||||
var errorMessage = document.getElementById('error-message');
|
||||
var errorAction = document.getElementById('error-action');
|
||||
|
||||
switch(errorType) {
|
||||
case 'invalid-credentials':
|
||||
errorTitle.textContent = 'Login Failed';
|
||||
errorMessage.textContent = 'Invalid username or password. Please check your credentials and try again.';
|
||||
errorAction.textContent = 'Try Again';
|
||||
errorAction.addEventListener('click', function() { history.back(); });
|
||||
break;
|
||||
case 'session-expired':
|
||||
errorTitle.textContent = 'Session Expired';
|
||||
errorMessage.textContent = 'Your session has expired. Please try again.';
|
||||
errorAction.textContent = 'Close Window';
|
||||
errorAction.addEventListener('click', function() { window.close(); });
|
||||
break;
|
||||
case 'not-found':
|
||||
errorTitle.textContent = 'Not Found';
|
||||
errorMessage.textContent = 'The requested page was not found.';
|
||||
errorAction.textContent = 'Close Window';
|
||||
errorAction.addEventListener('click', function() { window.close(); });
|
||||
break;
|
||||
default:
|
||||
errorTitle.textContent = 'Error';
|
||||
errorMessage.textContent = 'An unexpected error occurred. Please try again.';
|
||||
errorAction.textContent = 'Close Window';
|
||||
errorAction.addEventListener('click', function() { window.close(); });
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Extract token from URL path and set form action
|
||||
var pathParts = window.location.pathname.split('/');
|
||||
var token = pathParts[pathParts.length - 1];
|
||||
// Validate token is hex-only to prevent injection
|
||||
if (!/^[0-9a-fA-F]+$/.test(token)) {
|
||||
document.body.innerHTML = '<p>Invalid session token.</p>';
|
||||
throw new Error('Invalid token format');
|
||||
}
|
||||
document.getElementById('login-flow-form').action = '/login/v2/flow/' + token;
|
||||
|
||||
// Check if OIDC is available and configure SSO button
|
||||
(async function() {
|
||||
try {
|
||||
var resp = await fetch('/api/auth/oidc/providers');
|
||||
if (!resp.ok) return;
|
||||
var info = await resp.json();
|
||||
if (!info.enabled) return;
|
||||
|
||||
// Show OIDC section
|
||||
document.getElementById('oidc-section').classList.remove('hidden');
|
||||
|
||||
// Update button text with provider name
|
||||
var btn = document.getElementById('oidc-button');
|
||||
btn.textContent = 'Sign in with ' + (info.provider_name || 'SSO');
|
||||
|
||||
// If password login is disabled, hide the password form
|
||||
if (!info.password_login_enabled) {
|
||||
document.getElementById('login-flow-form').style.display = 'none';
|
||||
}
|
||||
|
||||
// SSO button redirects to the OIDC flow for this NC token
|
||||
btn.addEventListener('click', function() {
|
||||
window.location.href = '/login/v2/flow/' + token + '/oidc';
|
||||
});
|
||||
} catch(e) {
|
||||
// OIDC not available — silently keep password-only mode
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,7 @@
|
||||
document.getElementById('close-window-btn').addEventListener('click', function() {
|
||||
window.close();
|
||||
});
|
||||
// Auto-close after 3 seconds
|
||||
setTimeout(function() {
|
||||
window.close();
|
||||
}, 3000);
|
||||
Reference in New Issue
Block a user