mirror of
https://github.com/sassanix/Warracker.git
synced 2025-12-31 18:49:39 -06:00
207 lines
9.7 KiB
HTML
207 lines
9.7 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Authenticating...</title>
|
|
<link rel="stylesheet" href="style.css?v=20250119004">
|
|
<script src="theme-loader.js?v=20250119001"></script>
|
|
<style>
|
|
body {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100vh;
|
|
margin: 0;
|
|
background-color: var(--bg-color);
|
|
color: var(--text-color);
|
|
font-family: sans-serif;
|
|
}
|
|
.container {
|
|
text-align: center;
|
|
padding: 20px;
|
|
background-color: var(--card-bg);
|
|
border-radius: 8px;
|
|
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
|
}
|
|
.error-message {
|
|
color: #f44336; /* Red for errors */
|
|
margin-bottom: 15px;
|
|
}
|
|
a {
|
|
color: var(--primary-color);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h2 id="statusMessage">Authenticating, please wait...</h2>
|
|
<div id="errorMessage" class="error-message" style="display: none;"></div>
|
|
<a href="login.html" id="loginLink" style="display: none;">Return to Login</a>
|
|
</div>
|
|
|
|
<script>
|
|
async function fetchUserInfoAndRedirect(token, isNewUser) {
|
|
const statusMessage = document.getElementById('statusMessage');
|
|
const errorMessageEl = document.getElementById('errorMessage');
|
|
const loginLink = document.getElementById('loginLink');
|
|
|
|
try {
|
|
statusMessage.textContent = 'Fetching user information...';
|
|
|
|
// Fetch user info using the token
|
|
const response = await fetch('/api/auth/validate-token', {
|
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
});
|
|
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
if (data.valid && data.user && data.user.id) {
|
|
// Store user info in localStorage
|
|
localStorage.setItem('user_info', JSON.stringify(data.user));
|
|
|
|
// Update status message
|
|
if (isNewUser) {
|
|
statusMessage.textContent = 'Account created successfully! Redirecting...';
|
|
} else {
|
|
statusMessage.textContent = 'Login successful! Redirecting...';
|
|
}
|
|
|
|
// Redirect to the main application page
|
|
setTimeout(() => {
|
|
window.location.href = 'index.html';
|
|
}, 1500);
|
|
} else {
|
|
throw new Error('Invalid user data received');
|
|
}
|
|
} else {
|
|
throw new Error(`Failed to validate token: ${response.status}`);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching user info:', error);
|
|
|
|
// Clear potentially invalid token
|
|
localStorage.removeItem('auth_token');
|
|
localStorage.removeItem('user_info');
|
|
|
|
statusMessage.textContent = 'SSO Login Failed';
|
|
errorMessageEl.textContent = 'Failed to fetch user information. Please try logging in again.';
|
|
errorMessageEl.style.display = 'block';
|
|
loginLink.style.display = 'inline';
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const statusMessage = document.getElementById('statusMessage');
|
|
const errorMessageEl = document.getElementById('errorMessage');
|
|
const loginLink = document.getElementById('loginLink');
|
|
|
|
const params = new URLSearchParams(window.location.search);
|
|
const token = params.get('token');
|
|
const oidcError = params.get('oidc_error');
|
|
const newUser = params.get('new_user');
|
|
|
|
if (oidcError) {
|
|
let message = 'An unknown error occurred during SSO login.';
|
|
switch (oidcError) {
|
|
case 'token_exchange_failed':
|
|
message = 'Failed to exchange authorization code for tokens with the SSO provider.';
|
|
break;
|
|
case 'token_missing':
|
|
message = 'Access token was not received from the SSO provider.';
|
|
break;
|
|
case 'userinfo_fetch_failed':
|
|
message = 'Failed to fetch user information from the SSO provider.';
|
|
break;
|
|
case 'userinfo_missing':
|
|
message = 'User information was not received from the SSO provider.';
|
|
break;
|
|
case 'subject_missing':
|
|
message = 'User subject identifier (sub) was missing from SSO provider response.';
|
|
break;
|
|
case 'email_missing_for_new_user':
|
|
message = 'Email address was not provided by SSO provider, which is required for new user registration.';
|
|
break;
|
|
case 'email_conflict_local_account':
|
|
message = 'The email address from your SSO provider is already associated with an existing local account. Please log in with your local credentials or contact support.';
|
|
break;
|
|
case 'registration_disabled':
|
|
message = 'New user registration via SSO is currently disabled. Only existing users can log in with SSO. Please contact your administrator if you need an account.';
|
|
break;
|
|
case 'user_processing_failed':
|
|
message = 'Failed to process user information after SSO login.';
|
|
break;
|
|
case 'db_error':
|
|
message = 'A database error occurred during SSO login. Please try again later.';
|
|
break;
|
|
case 'internal_error':
|
|
message = 'An internal server error occurred during SSO login. Please try again later.';
|
|
break;
|
|
}
|
|
statusMessage.textContent = 'SSO Login Failed';
|
|
errorMessageEl.textContent = message;
|
|
errorMessageEl.style.display = 'block';
|
|
loginLink.style.display = 'inline';
|
|
} else if (token) {
|
|
localStorage.setItem('auth_token', token);
|
|
|
|
// Fetch user info immediately after storing token to ensure it's available
|
|
// when the main app loads, preventing preference key mismatches
|
|
fetchUserInfoAndRedirect(token, newUser === 'true');
|
|
} else {
|
|
// No token and no error, unexpected state, redirect to login
|
|
statusMessage.textContent = 'Redirecting to login...';
|
|
setTimeout(() => {
|
|
window.location.href = 'login.html';
|
|
}, 1000);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<!-- i18next Local Scripts -->
|
|
<script src="js/lib/i18next.min.js?v=20250119001"></script>
|
|
<script src="js/lib/i18nextHttpBackend.min.js?v=20250119001"></script>
|
|
<script src="js/lib/i18nextBrowserLanguageDetector.min.js?v=20250119001"></script>
|
|
|
|
<!-- i18n Configuration -->
|
|
<script src="js/i18n.js?v=20250119001"></script>
|
|
|
|
<script src="auth-redirect.js?v=20250119001"></script>
|
|
|
|
<!-- Footer Width Fix -->
|
|
<script src="footer-fix.js?v=20251024001"></script>
|
|
|
|
<!-- Footer Content Manager -->
|
|
<script src="footer-content.js?v=20250119001"></script>
|
|
|
|
<!-- Powered by Warracker Footer -->
|
|
<footer class="warracker-footer" id="warrackerFooter">
|
|
<!-- Content will be dynamically generated by footer-content.js -->
|
|
</footer>
|
|
|
|
<script>
|
|
function applyFooterStyles() {
|
|
const footer = document.getElementById('warrackerFooter');
|
|
const link = document.getElementById('warrackerFooterLink');
|
|
const isDarkMode = document.documentElement.getAttribute('data-theme') === 'dark' || document.documentElement.classList.contains('dark-mode') || document.body.classList.contains('dark-mode');
|
|
if (footer) {
|
|
if (isDarkMode) {
|
|
// Dark mode styles - using same background as header (#2d2d2d)
|
|
footer.style.cssText = 'margin-top: 50px; padding: 20px; text-align: center; border-top: 1px solid #444; background-color: #2d2d2d; color: #e0e0e0; font-size: 0.9rem;';
|
|
if (link) link.style.cssText = 'color: #4dabf7; text-decoration: none; font-weight: 500;';
|
|
} else {
|
|
// Light mode styles - using same background as header (#ffffff)
|
|
footer.style.cssText = 'margin-top: 50px; padding: 20px; text-align: center; border-top: 1px solid #e0e0e0; background-color: #ffffff; color: #333333; font-size: 0.9rem;';
|
|
if (link) link.style.cssText = 'color: #3498db; text-decoration: none; font-weight: 500;';
|
|
}
|
|
}
|
|
}
|
|
document.addEventListener('DOMContentLoaded', applyFooterStyles);
|
|
const obs = new MutationObserver(applyFooterStyles);
|
|
obs.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme', 'class'] });
|
|
obs.observe(document.body, { attributes: true, attributeFilter: ['class'] });
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|