From 7608839473ec86d9e6258a9e231e6b8599d75f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Raduli=C4=87?= Date: Tue, 5 May 2026 18:22:52 +0200 Subject: [PATCH] Auth fix: apiPost/apiPut/apiDelete uses Bearer token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sport2.html: - apiPost: localStorage pgz_access → Authorization: Bearer - apiPut, apiDelete added - Better error toast Login redirect (multiple files): - Wrap auto-redirect in __pgz_made_api_call check - Don't redirect on initial page load if user has no API call yet --- static/app.html | 2 +- static/sport2.html | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/static/app.html b/static/app.html index 4c1cc86..df1bcc3 100644 --- a/static/app.html +++ b/static/app.html @@ -481,7 +481,7 @@ async function apiAuth(path, opts){ const onLogin = location.pathname.includes('/login'); if(!onLogin && !window.__pgz_redirecting){ window.__pgz_redirecting = true; - window.location.href = '/login?reason=unauthorized'; + window.(window.__pgz_made_api_call ? location.href = '/login?reason=unauthorized' : console.warn('[auth] no token but no API call yet, skipping redirect')); } return {__unauthorized:true, status:401}; } diff --git a/static/sport2.html b/static/sport2.html index 89d01bd..75d03f2 100644 --- a/static/sport2.html +++ b/static/sport2.html @@ -575,25 +575,57 @@ function txt(v, fb){ } async function api(path){ try{ - const r = await fetch(API+path); + const tok = localStorage.getItem('pgz_access') || sessionStorage.getItem('pgz_access') || localStorage.getItem('access_token') || ''; + const headers = {}; + if(tok) headers['Authorization'] = 'Bearer ' + tok; + const r = await fetch(API+path, {headers}); if(!r.ok) throw new Error('HTTP '+r.status); return await r.json(); }catch(e){ - console.error('API error', path, e); + console.error('API GET error', path, e); return null; } } async function apiPost(path, body){ try{ - const r = await fetch(API+path, {method:'POST', headers:{'Content-Type':'application/json'}, body: body?JSON.stringify(body):'{}'}); - if(!r.ok) throw new Error('HTTP '+r.status); + const tok = localStorage.getItem('pgz_access') || sessionStorage.getItem('pgz_access') || localStorage.getItem('access_token') || ''; + const headers = {'Content-Type':'application/json'}; + if(tok) headers['Authorization'] = 'Bearer ' + tok; + const r = await fetch(API+path, {method:'POST', headers, body: body?JSON.stringify(body):'{}'}); + if(!r.ok){ + const errText = await r.text().catch(()=>('')); + throw new Error('HTTP '+r.status+(errText? ': '+errText.slice(0,150):'')); + } return await r.json(); }catch(e){ console.error('API POST error', path, e); + if(typeof showToast === 'function') showToast('Greška: '+e.message, 'err'); return null; } } +async function apiPut(path, body){ + try{ + const tok = localStorage.getItem('pgz_access') || sessionStorage.getItem('pgz_access') || ''; + const headers = {'Content-Type':'application/json'}; + if(tok) headers['Authorization'] = 'Bearer ' + tok; + const r = await fetch(API+path, {method:'PUT', headers, body: JSON.stringify(body||{})}); + if(!r.ok) throw new Error('HTTP '+r.status); + return await r.json(); + }catch(e){ console.error('API PUT error', path, e); return null; } +} + +async function apiDelete(path){ + try{ + const tok = localStorage.getItem('pgz_access') || sessionStorage.getItem('pgz_access') || ''; + const headers = {}; + if(tok) headers['Authorization'] = 'Bearer ' + tok; + const r = await fetch(API+path, {method:'DELETE', headers}); + if(!r.ok) throw new Error('HTTP '+r.status); + return await r.json(); + }catch(e){ console.error('API DELETE error', path, e); return null; } +} + // Cache the latest preview so /apply can pass back the same sources window._enrichPreviews = window._enrichPreviews || {};