diff --git a/internal/api/attachments.go b/internal/api/attachments.go index 862f544..5a2cfff 100644 --- a/internal/api/attachments.go +++ b/internal/api/attachments.go @@ -186,9 +186,24 @@ func (a *apiServer) handleCreatePasteMultipart(w http.ResponseWriter, r *http.Re case "burn_after_read": p.BurnAfterRead = v == "true" || v == "1" || v == "on" case "burn_after_reads": - if n, err := strconv.Atoi(v); err == nil { - p.BurnAfterReads = &n + if v == "" { // absent value: unset, like the JSON path's omitempty + continue } + n, err := strconv.Atoi(v) + if err != nil { + // malformed burn_after_reads is a 400, not a silently-dropped + // budget: same 400-with-code shape the JSON path uses for + // invalid values (which fail unmarshal into the int field). + writeErrCode(w, 400, "burn_invalid", "burn_after_reads must be a positive number") + return + } + // negative values are invalid too: same 400 burn_invalid shape + // as the JSON path (validate.go:92), identical message text. + if err := parseBurnAfterReads(n); err != nil { + writeErrCode(w, 400, "burn_invalid", err.Error()) + return + } + p.BurnAfterReads = &n } } diff --git a/internal/web/static/app.css b/internal/web/static/app.css index b6f9634..bcbf27d 100644 --- a/internal/web/static/app.css +++ b/internal/web/static/app.css @@ -129,7 +129,7 @@ body { /* new paste page */ .deck { - display: grid; grid-template-columns: 1fr 300px; gap: 16px; + display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; padding: 16px 20px 20px; height: calc(100vh - 76px); max-width: 1400px; margin: 0 auto; } diff --git a/internal/web/templates/layout.html b/internal/web/templates/layout.html index 61eeca0..80cf025 100644 --- a/internal/web/templates/layout.html +++ b/internal/web/templates/layout.html @@ -1,5 +1,6 @@ {{define "head"}} +