Ispravke: QR proxy šema, race šifra, JM validacija, zaštita zaliha, magacin history flash

- servis.go: qrNalogURL helper čita X-Forwarded-Proto za ispravan HTTPS QR kod iza proxy-ja
- magacin_forma.go: šifra se generiše pre INSERT (uklanja race condition); normalizujJM validacija 4 kar.; blokada promene tipa ako postoji stanje na lageru
- prodaja.go + repository.go: Obrisi beleži magacinsku promenu (PromenaPovracaj) uz korisnikID; ispravljeni zamenjeni potpisi interfejsa ServisRepository/ProdajaRepository
- kategorije.html: UI hint kada kategorija nema kôd (prefiks šifre)
- 061_backfill_kategorija_kod.sql: popunjava kod postojećim kategorijama iz naziva
- magacin.html: htmx:beforeHistorySave sklanja bez-anim pre snimanja snapshota (fix flash animacije)
This commit is contained in:
2026-06-20 21:43:34 +02:00
parent b0250b2917
commit fec84f98d5
8 changed files with 94 additions and 39 deletions
+17 -15
View File
@@ -644,11 +644,7 @@ func (h *Handler) StampaServisa(w http.ResponseWriter, r *http.Request) {
}
// QR kod vodi na javnu status stranicu — dostupnu bez prijave
scheme := "http"
if r.TLS != nil {
scheme = "https"
}
nalogURL := scheme + "://" + r.Host + "/status/" + nalog.JavniToken
nalogURL := qrNalogURL(r, nalog.JavniToken)
var qrKod string
if png, err := qrcode.Encode(nalogURL, qrcode.Medium, 160); err == nil {
qrKod = base64.StdEncoding.EncodeToString(png)
@@ -754,11 +750,7 @@ func (h *Handler) StampaOtpremnice(w http.ResponseWriter, r *http.Request) {
}
}
nalogURL := "http"
if r.TLS != nil {
nalogURL += "s"
}
nalogURL += "://" + r.Host + "/status/" + nalog.JavniToken
nalogURL := qrNalogURL(r, nalog.JavniToken)
var qrKodOtpr string
if png, err := qrcode.Encode(nalogURL, qrcode.Medium, 160); err == nil {
qrKodOtpr = base64.StdEncoding.EncodeToString(png)
@@ -894,11 +886,7 @@ func (h *Handler) StampaPredracuna(w http.ResponseWriter, r *http.Request) {
vaziDo := datumIzdavanja.AddDate(0, 0, rok)
// QR kod vodi na javnu status stranicu — dostupnu bez prijave
nalogURL := "http"
if r.TLS != nil {
nalogURL += "s"
}
nalogURL += "://" + r.Host + "/status/" + nalog.JavniToken
nalogURL := qrNalogURL(r, nalog.JavniToken)
var qrKod string
if png, err := qrcode.Encode(nalogURL, qrcode.Medium, 160); err == nil {
qrKod = base64.StdEncoding.EncodeToString(png)
@@ -991,3 +979,17 @@ func (h *Handler) ServisJavniStatus(w http.ResponseWriter, r *http.Request) {
SviStatusi: model.SviStatusi,
})
}
// qrNalogURL konstruiše URL za QR kod vodeći računa o reverse proxy-ju.
// Ako aplikacija radi iza nginx/Caddy/Traefik koji prekida TLS, r.TLS je nil,
// ali X-Forwarded-Proto header sadrži stvarnu šemu.
func qrNalogURL(r *http.Request, token string) string {
scheme := "http"
if r.TLS != nil {
scheme = "https"
}
if r.Header.Get("X-Forwarded-Proto") == "https" {
scheme = "https"
}
return scheme + "://" + r.Host + "/status/" + token
}