Dashboard
Pregled stanja
@@ -398,11 +431,41 @@ function getToken(){
async function apiAuth(path, opts){
opts = opts || {};
const h = Object.assign({}, opts.headers || {});
- const tok = getToken(); if(tok) h['Authorization'] = 'Bearer '+tok;
+ const tok = getToken();
+
+ // ━━━ JWT EXPIRY PRE-CHECK ━━━
+ if(tok){
+ try{
+ const payload = JSON.parse(atob(tok.split('.')[1]));
+ if(payload.exp && payload.exp * 1000 < Date.now()){
+ console.warn('[apiAuth] JWT expired client-side, redirecting');
+ ['pgz_access','pgz_refresh','pgz_user','jwt','access_token'].forEach(k => {
+ try{localStorage.removeItem(k); sessionStorage.removeItem(k);}catch(e){}
+ });
+ if(!window.__pgz_redirecting){ window.__pgz_redirecting = true; window.location.href = '/login?reason=expired'; }
+ return {__unauthorized:true, status:401};
+ }
+ }catch(e){ /* token not parseable, continue and let server respond */ }
+ h['Authorization'] = 'Bearer '+tok;
+ }
+
if(opts.body && !(opts.body instanceof FormData) && !h['Content-Type']) h['Content-Type'] = 'application/json';
try {
const r = await fetch(API+path, Object.assign({}, opts, {headers:h}));
- if(r.status === 401){ return {__unauthorized:true, status:401}; }
+ if(r.status === 401){
+ // ━━━ GLOBAL 401 HANDLER — clear + redirect ━━━
+ console.warn('[apiAuth] 401 from server, clearing localStorage + redirecting');
+ ['pgz_access','pgz_refresh','pgz_user','jwt','access_token'].forEach(k => {
+ try{localStorage.removeItem(k); sessionStorage.removeItem(k);}catch(e){}
+ });
+ // Don't redirect from /login itself; allow profile page to handle
+ const onLogin = location.pathname.includes('/login');
+ if(!onLogin && !window.__pgz_redirecting){
+ window.__pgz_redirecting = true;
+ window.location.href = '/login?reason=unauthorized';
+ }
+ return {__unauthorized:true, status:401};
+ }
if(!r.ok) return {__error:true, status:r.status};
if(r.headers.get('content-type')?.includes('application/json')) return await r.json();
return {__ok:true};
diff --git a/static/login.html b/static/login.html
index afa4f0f..dd19ba2 100644
--- a/static/login.html
+++ b/static/login.html
@@ -582,5 +582,22 @@ $('#cookieMore').addEventListener('click', e => { e.preventDefault(); $('#privac
}, 100);
})();
+
+