88 lines
No EOL
2.5 KiB
TypeScript
88 lines
No EOL
2.5 KiB
TypeScript
import React from 'react';
|
|
import ReactDOM from 'react-dom/client';
|
|
import { BrowserRouter } from 'react-router-dom';
|
|
import { AuthProvider } from 'react-oidc-context';
|
|
import { Toaster } from 'react-hot-toast';
|
|
import App from './App';
|
|
import { oidcConfig } from './src/config/oidc';
|
|
|
|
// Clean up stale OAuth params on page load (e.g., after logout redirect)
|
|
// This prevents "No matching state found in storage" errors
|
|
const cleanupStaleOAuthParams = () => {
|
|
const params = new URLSearchParams(window.location.search);
|
|
const hasOAuthParams = params.has('code') || params.has('state');
|
|
|
|
if (hasOAuthParams) {
|
|
const state = params.get('state');
|
|
// Check if there's a matching state in storage
|
|
const hasMatchingState = state && localStorage.getItem(`oidc.${state}`);
|
|
|
|
if (!hasMatchingState) {
|
|
// Stale params - clean them up
|
|
window.history.replaceState({}, document.title, window.location.pathname);
|
|
}
|
|
}
|
|
};
|
|
|
|
cleanupStaleOAuthParams();
|
|
|
|
const rootElement = document.getElementById('root');
|
|
if (!rootElement) {
|
|
throw new Error("Could not find root element to mount to");
|
|
}
|
|
|
|
const shouldSkipSigninCallback = !window.location.pathname.startsWith('/callback');
|
|
|
|
const onSigninCallback = () => {
|
|
const returnUrl = sessionStorage.getItem('kaboot_auth_return_url');
|
|
sessionStorage.removeItem('kaboot_auth_return_url');
|
|
|
|
if (returnUrl && returnUrl !== '/') {
|
|
window.location.replace(returnUrl);
|
|
} else {
|
|
window.history.replaceState({}, document.title, '/');
|
|
}
|
|
};
|
|
|
|
const root = ReactDOM.createRoot(rootElement);
|
|
root.render(
|
|
<React.StrictMode>
|
|
<BrowserRouter>
|
|
<AuthProvider
|
|
{...oidcConfig}
|
|
skipSigninCallback={shouldSkipSigninCallback}
|
|
onSigninCallback={onSigninCallback}
|
|
onRemoveUser={() => {
|
|
localStorage.removeItem('kaboot_session');
|
|
}}
|
|
>
|
|
<Toaster
|
|
position="top-center"
|
|
toastOptions={{
|
|
duration: 4000,
|
|
style: {
|
|
background: '#333',
|
|
color: '#fff',
|
|
fontWeight: 'bold',
|
|
borderRadius: '1rem',
|
|
padding: '12px 20px',
|
|
},
|
|
success: {
|
|
iconTheme: {
|
|
primary: '#22c55e',
|
|
secondary: '#fff',
|
|
},
|
|
},
|
|
error: {
|
|
iconTheme: {
|
|
primary: '#ef4444',
|
|
secondary: '#fff',
|
|
},
|
|
},
|
|
}}
|
|
/>
|
|
<App />
|
|
</AuthProvider>
|
|
</BrowserRouter>
|
|
</React.StrictMode>
|
|
); |