Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/XcluadeAgent.Api/Components/App.razor
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,64 @@
.syncing {
animation: pulse 2s infinite;
}

/* Hide body until auth check completes */
body.auth-checking {
visibility: hidden;
}
</style>
<script>
// Auth check - runs BEFORE page renders
(function() {
var currentPath = window.location.pathname;
var publicPaths = ['/login', '/forgot-password', '/reset-password'];

// Skip auth check for public paths
if (publicPaths.some(function(p) { return currentPath.startsWith(p); })) {
return;
}

var token = localStorage.getItem('authToken');

// No token - redirect to login immediately
if (!token) {
window.location.replace('/login');
return;
}

// Check if token is expired
try {
var parts = token.split('.');
if (parts.length === 3) {
var payload = parts[1];
// Add padding for base64
while (payload.length % 4) {
payload += '=';
}
var decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
var data = JSON.parse(decoded);

if (data.exp) {
var expDate = new Date(data.exp * 1000);
if (expDate < new Date()) {
// Token expired - clear and redirect
localStorage.removeItem('authToken');
localStorage.removeItem('refreshToken');
localStorage.removeItem('user');
window.location.replace('/login');
return;
}
}
}
} catch (e) {
// Invalid token - clear and redirect
localStorage.removeItem('authToken');
localStorage.removeItem('refreshToken');
localStorage.removeItem('user');
window.location.replace('/login');
}
})();
</script>
</head>

<body>
Expand Down
Loading