diff --git a/_audit/playwright_20260505_0923/01_login_page.png b/_audit/playwright_20260505_0923/01_login_page.png new file mode 100644 index 0000000..29bc849 Binary files /dev/null and b/_audit/playwright_20260505_0923/01_login_page.png differ diff --git a/_audit/playwright_20260505_0923/02_post_login.png b/_audit/playwright_20260505_0923/02_post_login.png new file mode 100644 index 0000000..594b8ee Binary files /dev/null and b/_audit/playwright_20260505_0923/02_post_login.png differ diff --git a/_audit/playwright_20260505_0923/03_app_dashboard.png b/_audit/playwright_20260505_0923/03_app_dashboard.png new file mode 100644 index 0000000..594b8ee Binary files /dev/null and b/_audit/playwright_20260505_0923/03_app_dashboard.png differ diff --git a/_audit/playwright_20260505_0923/04_profile_view.png b/_audit/playwright_20260505_0923/04_profile_view.png new file mode 100644 index 0000000..9aa26a9 Binary files /dev/null and b/_audit/playwright_20260505_0923/04_profile_view.png differ diff --git a/_audit/playwright_20260505_0923/05_post_logout.png b/_audit/playwright_20260505_0923/05_post_logout.png new file mode 100644 index 0000000..594b8ee Binary files /dev/null and b/_audit/playwright_20260505_0923/05_post_logout.png differ diff --git a/_audit/playwright_20260505_0923/m01_mobile_login.png b/_audit/playwright_20260505_0923/m01_mobile_login.png new file mode 100644 index 0000000..a549588 Binary files /dev/null and b/_audit/playwright_20260505_0923/m01_mobile_login.png differ diff --git a/_audit/playwright_20260505_0923/m02_mobile_app.png b/_audit/playwright_20260505_0923/m02_mobile_app.png new file mode 100644 index 0000000..208c528 Binary files /dev/null and b/_audit/playwright_20260505_0923/m02_mobile_app.png differ diff --git a/_audit/playwright_20260505_0923/m03_mobile_sidebar_open.png b/_audit/playwright_20260505_0923/m03_mobile_sidebar_open.png new file mode 100644 index 0000000..d8d5da0 Binary files /dev/null and b/_audit/playwright_20260505_0923/m03_mobile_sidebar_open.png differ diff --git a/_audit/playwright_20260505_0923/m04_mobile_sport2_homepage.png b/_audit/playwright_20260505_0923/m04_mobile_sport2_homepage.png new file mode 100644 index 0000000..8dd170a Binary files /dev/null and b/_audit/playwright_20260505_0923/m04_mobile_sport2_homepage.png differ diff --git a/_audit/playwright_20260505_0923/results.json b/_audit/playwright_20260505_0923/results.json new file mode 100644 index 0000000..4c58836 --- /dev/null +++ b/_audit/playwright_20260505_0923/results.json @@ -0,0 +1,67 @@ +{ + "tests": [ + { + "name": "Login page loads", + "status": "PASS" + }, + { + "name": "Login persists JWT", + "status": "PASS", + "url": "https://sport.rinet.one/app", + "token_len": 519 + }, + { + "name": "Profile section accessible", + "status": "PASS" + }, + { + "name": "PGŽ logo clickable", + "status": "PASS", + "href": "/" + }, + { + "name": "Logout clears tokens", + "status": "FAIL", + "msg": "token still present: len=519" + }, + { + "name": "Mobile login renders", + "status": "PASS", + "viewport": "width=device-width,initial-scale=1" + }, + { + "name": "Mobile login → app", + "status": "PASS" + }, + { + "name": "Mobile hamburger button", + "status": "PASS", + "visible": true + }, + { + "name": "Mobile sidebar opens", + "status": "PASS" + }, + { + "name": "Mobile homepage no horizontal scroll", + "status": "PASS", + "body_w": 375, + "viewport": 375 + } + ], + "screenshots": [ + "/opt/pgz-sport/_audit/playwright_20260505_0923/01_login_page.png", + "/opt/pgz-sport/_audit/playwright_20260505_0923/02_post_login.png", + "/opt/pgz-sport/_audit/playwright_20260505_0923/03_app_dashboard.png", + "/opt/pgz-sport/_audit/playwright_20260505_0923/04_profile_view.png", + "/opt/pgz-sport/_audit/playwright_20260505_0923/05_post_logout.png", + "/opt/pgz-sport/_audit/playwright_20260505_0923/m01_mobile_login.png", + "/opt/pgz-sport/_audit/playwright_20260505_0923/m02_mobile_app.png", + "/opt/pgz-sport/_audit/playwright_20260505_0923/m03_mobile_sidebar_open.png", + "/opt/pgz-sport/_audit/playwright_20260505_0923/m04_mobile_sport2_homepage.png" + ], + "summary": { + "passed": 9, + "failed": 1 + } +} \ No newline at end of file diff --git a/_audit/sub4_enrich.py b/_audit/sub4_enrich.py index 1ba39f3..7dfb618 100644 --- a/_audit/sub4_enrich.py +++ b/_audit/sub4_enrich.py @@ -113,11 +113,11 @@ def verify_content(url: str, naziv: str): """ status, final_url, body = get_snippet(url, max_kb=50) if status < 200 or status >= 400 or not body: - return (status, final_url, 0, False, False) + return (status, final_url, 0, False, False, True, []) try: text = body.decode("utf-8", errors="ignore") except Exception: - return (status, final_url, 0, False, False) + return (status, final_url, 0, False, False, True, []) text_low = strip_diacritics(text).lower() substr = strip_diacritics(naziv_substr(naziv)).lower() diff --git a/static/app.html b/static/app.html index a4a1d83..fabde83 100644 --- a/static/app.html +++ b/static/app.html @@ -749,14 +749,23 @@ function navTo(id){ $$('.nav-i').forEach(el => el.classList.toggle('active', el.dataset.id===id)); loadSection(); } -function logout(){ +async function logout(){ if(!confirm('Odjava iz aplikacije?')) return; - try { - localStorage.removeItem('app-role'); - localStorage.removeItem('jwt'); - } catch(e){} - alert('Odjavljen. (Production: redirect na /login)'); - window.location.href = '/static/sport2.html'; + // Call backend to revoke JWT + try{ + const tok = getToken(); + if(tok){ + await fetch(API+'/auth/logout', { + method:'POST', + headers:{'Authorization':'Bearer '+tok} + }).catch(()=>{}); + } + }catch(e){} + // Clear ALL session keys (not just demo placeholders) + ['pgz_access','pgz_refresh','pgz_user','app-role','jwt','access_token','refresh_token','pgz_session_id'].forEach(k => { + try{localStorage.removeItem(k); sessionStorage.removeItem(k);}catch(e){} + }); + window.location.href = '/login'; } //=========== SECTION TITLES ===========