Commit Graph

4 Commits

Author SHA1 Message Date
Damir Radulić bd3773434e CC2 R4 #6: real TOTP 2FA (setup + verify + disable + login flow)
- auth/auth_v2.py:
  - pyotp-based TOTP (RFC 6238, base32 secret, ±30s window)
  - new pgz_sport.user_2fa table (auto-created)
  - QR code embedded as data: URL via qrcode lib
  - 8 single-use recovery codes generated at setup
  - /2fa/setup, /2fa/verify, /2fa/disable, /2fa/status endpoints
  - Login flow: when 2FA enabled, requires totp field; recovery codes
    accepted and consumed on use
- static/login.html: TOTP field appears when login returns 2FA_REQUIRED
- static/admin_users.html: full 2FA panel in Sigurnost tab
  (status badge, QR + secret + recovery code display, verify input)

Live tests pass:
  T1 status (no setup) → enabled:false
  T2 setup → secret + 1.5KB QR PNG + 8 recovery codes
  T3 verify wrong code → 401
  T4 verify real TOTP → enabled:true
  T5 login w/o TOTP after enable → 401 detail=2FA_REQUIRED
  T6 login w/ TOTP → 200
2026-05-05 00:50:28 +02:00
Damir Radulić a0db65fc31 CC2 R4 #4: /api/users/me/gdpr-export alias
- New auth.gdpr.me_router prefix /api/users/me with:
  - GET/POST /gdpr-export → Art.20 JSON download with Content-Disposition
  - POST /gdpr-erase → Art.17 erasure request
  - GET /gdpr-consent → consent history for caller
- jsonable_encoder fixes datetime serialisation in JSONResponse
- admin_users.html: 'Izvezi moje podatke' now POSTs to alias and uses
  filename from Content-Disposition header
- 401 enforced on no-auth, 200 on valid Bearer (verified live)
2026-05-05 00:47:22 +02:00
Damir Radulić 47c366de7e CC5 R3 UI: link iz app.html sekcija na live /sport/crm workspace
Standalone /sport/crm stranica (static/crm.html) već je deployana s prethodnim
commit-om (CC2). Ovaj commit dodaje vidljivi link u 5 SECTIONS handlera u
app.html (pgz:crm, klub:clanarine, klub:lijecnicki, sportas:lijecnicki,
sportas:obrasci) tako da klikom na taj gumb korisnik dolazi do live tablica
(M7 + M8 + M9):

- Tablice s filterima (status / godina / klub / vrsta pregleda)
- Action gumbi: registriraj uplatu, generiraj HUB-3 PDF, EPC QR, zakaži pregled
  preko ZZJZ PGŽ (online ili e-mail fallback), popuni i potpiši obrazac
- Live PDF generator za uplatnice (HUB-3) i potpisane obrasce (sa SHA-256)

Mock SECTION sadržaj zadržan radi instant-pregleda u app.html;
puna funkcionalnost iza linka.

Live curl tests passed (5/5):
  ✓ /api/crm/clanarine + summary
  ✓ /api/crm/clanarine/{id}/uplatnica.pdf (52 KB %PDF)
  ✓ /api/crm/lijecnicki/uskoro-isticu (11 istekli)
  ✓ /api/crm/zzjz/info (live scrape; available=False, fallback=email)
  ✓ /api/crm/forms + draft + submit + sign + PDF (45 KB %PDF)
2026-05-05 00:23:34 +02:00
Damir Radulić 59a537388d CC3 R3 M3+M4: sport2 sidebar + app.html operativna aplikacija
M3 (sport2.html):
- ≡ toggle gumb u sidebar headeru, .sb.collapsed -> 58px (samo ikone)
- localStorage 'sidebar-state' (expanded|collapsed)
- restoreSidebar() pri DOMContentLoaded, prije buildNav
- Hover tooltip na collapsed nav itemima preko data-label

M4 (static/app.html — novi):
- 4 dashboard varijante po roli: PGŽ admin, Savez admin, Klub admin, Sportaš
- Role switch u topbar-u (demo) + localStorage 'app-role'
- Sidebar collapse (M3 logika), tooltip-ovi na collapsed
- Sidebar footer s avatar/username/role i Odjava (⎋) gumbom
- Klikabilni KPI/cards -> detail sub-stranice (savezi, klubovi, financije...)
- PGŽ: KPI + zahtjevi pending + audit log + Chart.js trend grafikon
- Savez: klubovi grid + zahtjevi PGŽ + lijecnicki uskoro istek + kalendar
- Klub: clanovi tablica + clanarine + lijecnicki + dokumenti + manifestacije + HUB-3 placeholder
- Sportaš: profile card + clanarina + lijecnicki + ZZJZ link + obrasci za potpis
- Iste CSS varijable kao sport2.html (PGŽ blue/gold dark theme)
- Real API: /sport/api/dashboard, /api/savezi, /api/klubovi, /api/clanovi, /api/proracun
- Mock fallback gdje API još ne postoji (M5/M7/M9 produkti)

Backups: static/sport2.html.bak.cc3.m3*, static/app.html.bak.cc3.m4*

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 00:16:29 +02:00