Files
GoNtech/web/templates/stranice/blokirane_ip.html
T
Dasko d9f337617b Nizak prioritet iz pregleda koda: indeksi, greške, sitne popravke
- migracija 102: indeksi na FK kolonama (stavke_prodaje, servisni_delovi,
  servisni_potrazivani_delovi, magacinske_promene, stavke_nabavke, pdv_kir,
  pdv_kpr) — potvrđeno kreiranje i idempotentnost
- BrojKriticnihZaliha/KriticneZalihe filtriraju samo proizvode i aktivne
  artikle, usklađeno sa ArtikalRepo.Lista(SamoKriticni)
- url.QueryEscape na query string u magacin.go/klijent.go (paginacija)
- TestFiskalizacije/BeStatus vraćaju generičku poruku, detalj u slog
- SetFlash loguje grešku umesto tihog ignorisanja
- os.WriteFile/os.MkdirAll u main.go proveravaju grešku
- dummyHash generisanje panikuje na startu ako bcrypt ikad zakaže
  (umesto tihog sloma anti-enumeracije)
- PrihvatiPredlozene proverava redovi.Err()
- /healthz endpoint (DB ping)
- hx-boost na "Osveži" linkovima (blokirane_ip, fiskal_pazar)
- MaxBytesReader (4KB) na javne /status/{token}/* POST rute
- komentar u auth.go zašto postoje dva flash mehanizma (namerno, ne spojeno)

Provereno: jePrivatnaAdresa ne radi DNS lookup (nema net.LookupIP u repou),
pa DNS-rebinding nalaz iz pregleda nije primenljiv na trenutni kod.
2026-07-03 23:31:00 +02:00

51 lines
3.4 KiB
HTML

{{template "base" .}} {{define "naslov"}}Blokirane IP adrese — NTech{{end}} {{define "sadrzaj"}}
<div class="stranica-stack" style="display: flex; flex-direction: column; gap: 16px">
<div style="display: flex; align-items: center; gap: 12px; flex-wrap: wrap">
<span class="naslov-traka" style="font-size: 15px; font-weight: 500; color: var(--tekst-glavni)">Blokirane IP adrese</span>
</div>
<div class="kartica animiraj" style="padding: 0; overflow: hidden">
<div style="padding: 16px 20px; border-bottom: 0.5px solid var(--ivica); display: flex; align-items: center; justify-content: space-between">
<span style="font-size: 15px; font-weight: 500; color: var(--tekst-glavni)">IP adrese trenutno zaključane zbog previše neuspelih pokušaja prijave</span>
<a hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML" href="/admin/blokirane-ip" class="btn-sekundarno" style="font-size: 13px; padding: 8px 16px">Osveži</a>
</div>
{{if .Lista}}
<div style="overflow-x: auto">
<table class="tabela">
<thead>
<tr style="border-bottom: 0.5px solid var(--ivica)">
<th style="padding: 10px 20px; text-align: left; font-size: 12px; font-weight: 500; color: var(--tekst-sporedni)">IP adresa</th>
<th style="padding: 10px 20px; text-align: left; font-size: 12px; font-weight: 500; color: var(--tekst-sporedni)">Neuspelih pokušaja</th>
<th style="padding: 10px 20px; text-align: left; font-size: 12px; font-weight: 500; color: var(--tekst-sporedni); white-space: nowrap">Poslednji pokušaj</th>
<th style="padding: 10px 20px; text-align: left; font-size: 12px; font-weight: 500; color: var(--tekst-sporedni)">Preostalo</th>
<th style="padding: 10px 20px; text-align: right; font-size: 12px; font-weight: 500; color: var(--tekst-sporedni)"></th>
</tr>
</thead>
<tbody>
{{range .Lista}}
<tr class="animiraj" style="border-bottom: 0.5px solid var(--ivica)">
<td style="padding: 10px 20px; font-size: 13px; color: var(--tekst-glavni); font-family: monospace">{{.IP}}</td>
<td style="padding: 10px 20px; font-size: 13px; color: var(--tekst-glavni)">{{.BrojNeuspeha}}</td>
<td style="padding: 10px 20px; font-size: 13px; color: var(--tekst-sporedni); white-space: nowrap">{{.PoslednjiPokusaj.Format "02.01.2006. 15:04:05"}}</td>
<td style="padding: 10px 20px; font-size: 13px; color: var(--tekst-sporedni)">{{.Preostalo}}</td>
<td style="padding: 10px 20px; text-align: right">
<form method="POST" action="/admin/blokirane-ip/odblokiraj" style="display:inline;" data-full-reload
onsubmit="return confirm('Odblokirati IP adresu {{.IP}}? Ovo odmah briše sve neuspele pokušaje prijave za nju.')">
<input type="hidden" name="_csrf" value="{{$.CsrfToken}}">
<input type="hidden" name="ip" value="{{.IP}}">
<button type="submit" class="btn-sekundarno" style="font-size: 13px; padding: 6px 14px">Odblokiraj</button>
</form>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{else}}
<div style="padding: 40px 20px; text-align: center; color: var(--tekst-sporedni); font-size: 14px">Trenutno nema blokiranih IP adresa.</div>
{{end}}
</div>
</div>
{{end}}