- 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.
51 lines
3.4 KiB
HTML
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}}
|