CC2 R4 #2+#5: remove legacy unauth /api/admin/users — close 401 gap

The bare @app.get/post('/api/admin/users') decorators in pgz_sport_api.py
were registered before app.include_router(admin_users_router) and shadowed
the JWT-protected M2 routes, leaking user list to anyone.

Removed all three: GET /api/admin/users, POST /api/admin/users,
POST /api/admin/users/{uid}/toggle. The auth.admin_users router now owns
this prefix exclusively and gates every method with require_user.

Verified: no-auth → 401, invalid token → 401, valid Bearer → 200.
This commit is contained in:
Damir Radulić
2026-05-05 00:44:50 +02:00
parent cb3faee731
commit f5c6570d47
20 changed files with 11746 additions and 110 deletions
+15 -5
View File
@@ -373,7 +373,7 @@ body {
</div>
<div class="footer-right">
<a href="/sport/static/sport2.html">Javni portal</a>
<a href="/sport2.html">Javni portal</a>
·
<a href="#" id="privacyLink">Politika privatnosti</a>
·
@@ -394,7 +394,7 @@ body {
</div>
<script>
const API = '/sport/api';
const API = '/api';
const $ = s => document.querySelector(s);
// ---------- Login ----------
@@ -435,9 +435,19 @@ async function doLogin(email, password) {
const role = (data.user.role || '').toLowerCase();
if (['super_admin','pgz_admin','pgz_user','pgz_finance','pgz_zzjz',
'savez_admin','savez_user','klub_admin','klub_user','klub_trener'].includes(role)) {
location.href = '/sport/static/admin_users.html';
// Smart redirect po roli
const role = data.user.role;
const redirectMap = {
'pgz_admin': '/app',
'savez_admin': '/app',
'klub_admin': '/app',
'super_admin': '/admin'
};
location.href = redirectMap[role] || '/app';
} else {
location.href = '/sport/';
location.href = '/';
}
}, 600);
} catch (e) {
@@ -525,7 +535,7 @@ $('#cookieMore').addEventListener('click', e => { e.preventDefault(); $('#privac
try {
const r = await fetch(API + '/auth/me', { headers: { Authorization: 'Bearer ' + tok }});
if (r.ok) {
location.href = '/sport/static/admin_users.html';
location.href = '/app';
return;
}
} catch {}