Commit Graph
114 Commits
Author SHA1 Message Date
fen a95ee57000 Merge pull request 'Split new-paste editor header into title pill and settings pill (#147)' (#149) from fix-147-header-split into dev
CI / test (push) Successful in 31s
CI / docker (push) Successful in 33s
2026-09-10 04:12:05 +00:00
fen b096c2073c Merge pull request 'Fix result box wrap: word boundaries, keep long-token breaking (#135)' (#145) from fix-135-result-wrap into dev
CI / test (push) Successful in 27s
CI / docker (push) Successful in 41s
2026-09-10 04:09:13 +00:00
fen 4d50e644b9 Merge pull request 'Fix #146: untitled paste ID fallback renders as plain text like titled pastes' (#148) from fix-146-id-fallback-plain into dev
CI / test (push) Successful in 27s
CI / docker (push) Successful in 39s
2026-09-10 04:07:04 +00:00
fen 8abf821ce9 Merge pull request 'Admin lock page: replace explanatory paragraph with centered key input' (#119) from fix-admin-lock-center into dev
CI / test (push) Successful in 27s
CI / docker (push) Successful in 32s
2026-09-10 04:01:45 +00:00
fen da9039b606 Split new-paste editor header into title pill and settings pill (#147)
CI / test (pull_request) Successful in 30s
CI / docker (pull_request) Skipped
2026-09-09 22:58:41 -05:00
fen 7dc70d62f6 Fix #146: render untitled paste ID fallback as plain text like titled pastes
CI / test (pull_request) Successful in 26s
CI / docker (pull_request) Skipped
The PASTE column fallback for untitled pastes used the .slug class, which
renders as a monospace chip with a background pill. Give it a dedicated
paste-name modifier that strips the chip styling (background, padding,
radius, mono font) so the fallback looks identical to a titled paste
(var(--fg) plain text). The dedicated ID column and URL column chips keep
their existing styling. Applied to both /history and /mine tables.
2026-09-09 22:56:53 -05:00
fen 0073335875 #38 QA fix: render GetAttachmentForPaste in paste view; dedupe dark-toggle CSS
CI / test (pull_request) Successful in 27s
CI / docker (pull_request) Skipped
- renderPaste now looks up the paste's attachment and passes it as
  'Attachment' so the paste.html attachment chip/image preview renders
- remove duplicated .iconbtn.dark-toggle blocks (3x from stacked
  branches #127/#128) and duplicate mobile-media variants

Verified: go vet + go test pass; live render on :18098 shows
attachment-chip + img src=/f/id/name for a png upload (served 200
image/png) and chip-with-filename, no preview, for an html upload.
2026-09-09 22:53:39 -05:00
fen fa2e9b1bb5 History: keep pagination over filtered/sorted set, pin pager to page bottom (#133)
CI / test (pull_request) Successful in 26s
CI / docker (pull_request) Skipped
2026-09-09 22:48:25 -05:00
fen 9f4ed91b8f Fix result box wrap: word boundaries instead of break-all (#135)
CI / test (pull_request) Successful in 26s
CI / docker (pull_request) Skipped
2026-09-09 22:43:30 -05:00
fen 7cc6a9c706 Add line wrap toggle for editor and paste viewer (#130)
CI / test (pull_request) Successful in 27s
CI / docker (pull_request) Skipped
Shared client-side preference in localStorage 'palette-wrap', default
off. Toggle button on /new editor head and paste title bar, plus a Line
wrap checkbox in the settings menu; all read/write the same preference.
Active state uses the accent treatment like other toggles. No em dashes
in UI text.
2026-09-09 22:35:49 -05:00
fen 19cb8d1d45 Merge pull request 'Theme pairs with dark mode toggle, gear active state, PALETTE_DEFAULT_DARK' (#128) from fix-theme-pairs-darkmode into dev
CI / test (push) Successful in 25s
CI / docker (push) Successful in 32s
2026-09-10 03:25:35 +00:00
fen 4948ef9f1c #38 iteration 1: file attachments, 1 file per paste
CI / test (pull_request) Successful in 26s
CI / docker (pull_request) Skipped
- internal/store/blob.go: BlobStore interface + fs implementation with
  traversal-safe keys (<paste-id>/<sha256>), put/get/stat/delete
- attachments table migration (id, paste_id, filename sanitized to 255,
  mime sniffed server-side, size, sha256, created_at)
- POST /api/pastes now accepts multipart/form-data with a 'file' part;
  1 file = 1 paste: file replaces text content when both are sent
- 25 MB per-file limit enforced server-side (413 file_too_large)
- GET /f/{attachment-id}/{filename}: stored sniffed mime, nosniff,
  inline only for images/pdf, html/svg/xml forced to text/plain (#34 rule)
- paste view renders attachment chip + inline image preview
- /new: dropzone with file picker, drag-and-drop, Ctrl+V file paste,
  file chip with name/size/remove, matches pill/radius design
- tests: blob roundtrip/traversal/sanitize; multipart create (mime
  sniffing, client mime ignored, size limit, two-file reject, html/svg
  forcing, 404s, password/expiry fields)
2026-09-09 22:21:15 -05:00
fen dcf2d66a82 Theme pairs with dark mode toggle, gear active state, PALETTE_DEFAULT_DARK (#127)
CI / test (pull_request) Successful in 25s
CI / docker (pull_request) Skipped
- Collapse the 10 theme cards into 5 pairs: light swatches top row, dark bottom row
- Dark mode toggle in settings and topbar (sun/moon inline SVG)
- Toggling dark mode switches to the other variant of the selected pair
- Persist pair id in localStorage palette-theme, dark flag in palette-dark
- Head script resolves base+dark to variant; URL ?theme= accepts both ids and wins
- Settings gear highlights like nav tabs on /settings
- PALETTE_DEFAULT_DARK env var sets server default dark state (default on)
- Server-side resolution helpers + tests
2026-09-09 22:17:50 -05:00
fen 821f49993f Theme pairs with dark mode toggle, gear active state, PALETTE_DEFAULT_DARK (#127)
- Collapse the 10 theme cards into 5 pairs: light swatches top row, dark bottom row
- Dark mode toggle in settings and topbar (sun/moon inline SVG)
- Toggling dark mode switches to the other variant of the selected pair
- Persist pair id in localStorage palette-theme, dark flag in palette-dark
- Head script resolves base+dark to variant; URL ?theme= accepts both ids and wins
- Settings gear highlights like nav tabs on /settings
- PALETTE_DEFAULT_DARK env var sets server default dark state (default on)
- Server-side resolution helpers + tests
2026-09-09 22:17:04 -05:00
fen 8eabeb4839 Merge dev into fix-124: resolve new.html conflict, keep #124 removals and #125 placeholder
CI / test (pull_request) Successful in 25s
CI / docker (pull_request) Skipped
2026-09-09 21:53:00 -05:00
fen 8104cdba4c Remove custom URL reservation note and Can contents menu from new paste page
CI / test (pull_request) Successful in 25s
CI / docker (pull_request) Skipped
Fixes #124
2026-09-09 21:47:50 -05:00
fen be3ff81e5c base 2026-09-09 21:45:42 -05:00
fen 1e317d11da UI polish: placeholder slash, styled controls, admin link spacing (#123)
CI / test (pull_request) Successful in 24s
CI / docker (pull_request) Skipped
2026-09-09 21:45:22 -05:00
fen 70c284b15d Fix #120: add matching light/dark variant for every theme
CI / test (pull_request) Successful in 31s
CI / docker (pull_request) Skipped
2026-09-09 21:33:56 -05:00
fen 8dde83ff68 Admin lock: replace explanation paragraph with centered key input
CI / test (pull_request) Successful in 28s
CI / docker (pull_request) Skipped
2026-09-09 21:28:11 -05:00
fen 073d39ccba Fix #116: allow inline styles in CSP (style-src 'self' 'unsafe-inline')
CI / test (pull_request) Successful in 24s
CI / docker (pull_request) Skipped
2026-09-09 21:18:53 -05:00
fen a677e627a8 Fix #114: use presetColors(t.id) for theme card swatches
CI / test (pull_request) Successful in 24s
CI / docker (pull_request) Skipped
t.colors was removed by #113; rendering threw on first iteration and
the theme grid rendered empty. Use the colors returned by
presetColors(t.id) instead. Verified in headless chromium: 5
theme-card elements render on /settings.
2026-09-09 20:55:13 -05:00
fen 6b95994c53 Admin lock on every load, drop settings hint, derive theme swatches from CSS vars (#112)
CI / test (pull_request) Successful in 24s
CI / docker (pull_request) Skipped
2026-09-09 19:52:32 -05:00
fen 7fde147500 Merge pull request 'Fix theme persistence on reload' (#109) from fix-100-theme-persist into dev
CI / test (push) Successful in 23s
CI / docker (push) Successful in 38s
2026-09-10 00:22:04 +00:00
fen df73d56e32 Merge remote-tracking branch 'origin/fix-93-version-label' into dev
CI / test (push) Successful in 28s
CI / docker (push) Successful in 49s
2026-09-09 18:41:26 -05:00
fen 805cc3ff2b web: restore persisted theme on page load (#100)
CI / test (pull_request) Successful in 24s
CI / docker (pull_request) Skipped
2026-09-09 18:40:09 -05:00
poslop f37cc932c4 store: burn_after_reads>0 implies burn-after-read mode (#82)
CI / test (pull_request) Successful in 24s
CI / docker (pull_request) Skipped
2026-09-09 18:28:00 -05:00
agent 65ed0c7043 Show actual version in topbar instead of hardcoded beta (Fixes #93)
CI / test (pull_request) Successful in 26s
CI / docker (pull_request) Skipped
2026-09-09 18:27:57 -05:00
poslop 69da340224 Settings page: theme switcher with live preview (#100)
CI / test (push) Successful in 23s
CI / docker (push) Skipped
2026-09-09 18:21:45 -05:00
poslop 9df6224a27 Result box: color-code by status + friendly error messages from error codes (#105)
CI / test (push) Successful in 23s
CI / docker (push) Skipped
- Backend create/can validation paths emit machine-readable error codes
  (slug_taken, slug_invalid, content_empty, content_too_large,
  expiry_invalid, rate_limited, ...) alongside the human message
- new.html JS maps codes to plain-language guidance with generic fallback
- Result card colored via --ok/--err/--warn left border (result-ok/err/warn)
- docs/API.md error section documents the code field
- Tests assert the code on every validation path
2026-09-09 17:28:25 -05:00
poslop c35531e03e Settings page: small muted Admin link (#102)
CI / test (push) Successful in 22s
CI / docker (push) Skipped
2026-09-09 17:17:00 -05:00
poslop be2b4fb47f Sort arrows: left of label, further spaced, vertically centered, no label shift (#101)
Arrow is absolutely positioned at left:8px in the th, label padding-left
24px; translateY(-50%) keeps it centered regardless of row height, and
being out of flow the label never moves between sorted/unsorted states.
2026-09-09 17:17:00 -05:00
poslop 064f05536a Admin page: validate key before persisting to sessionStorage (#99)
Panel was already display:none-gated until auth; tightened so a wrong
submitted key is never stored in sessionStorage — the typed key is
validated via the settings API first, and only persisted on 200.
2026-09-09 17:17:00 -05:00
poslop 4175ffef3e CSS: inline sort arrow with uniform 8px gap (#103), full-pill slug roundness (#104)
CI / test (push) Successful in 22s
CI / docker (push) Skipped
2026-09-09 17:10:24 -05:00
poslop ea9edc211a UI: consistent sort arrow gap, uniform pill roundness (slug -> radius-sm)
CI / test (push) Successful in 22s
CI / docker (push) Skipped
2026-09-09 16:50:06 -05:00
poslop b21be29daa minor fixes: version label (#93), view dedupe tests (#95) 2026-09-09 16:40:53 -05:00
poslop cd70dd0b0e Merge origin/main (license, compose, #65 leak guard) into cans work
CI / test (push) Failing after 6s
CI / docker (push) Skipped
2026-09-09 16:39:14 -05:00
poslop 5b9be808ed Merge origin/main: keep can listing rows with #65 password-metadata leak guard 2026-09-09 16:36:55 -05:00
poslop 19804d47a3 Cans UI + parity: unlock-cookie flow, /can page, listings badge, custom slug, delete, sweeper; #32 perf notes (#4, #32) 2026-09-09 16:34:51 -05:00
poslop 959a83be1e Merge pull request 'Bound title and language at create time (#86)' (#91) from fix-86-field-bounds into main
CI / test (push) Successful in 24s
CI / docker (push) Successful in 42s
2026-09-09 15:59:32 +00:00
poslop 5b068faf8f Merge pull request 'ratelimit: rightmost untrusted-hop-safe client IP (fixes #85)' (#89) from fix-85-xff into main
CI / test (push) Successful in 27s
CI / docker (push) Skipped
2026-09-09 15:59:29 +00:00
poslop b0360af79c Merge pull request 'Fix #83: create API ignores boolean public field' (#88) from fix-83-public-false into main
CI / test (push) Successful in 26s
CI / docker (push) Skipped
2026-09-09 15:59:26 +00:00
poslop 806798fae6 Merge pull request 'Rate-limit all password verification attempts (#81)' (#90) from fix-81-password-ratelimit into main
CI / test (push) Successful in 26s
CI / docker (push) Skipped
2026-09-09 15:59:24 +00:00
fen 389e4d333f Bound title and language at create time (#86)
CI / test (pull_request) Successful in 21s
CI / docker (pull_request) Skipped
Titles are trimmed and truncated to 200 characters; language must be
blank or match ^[a-zA-Z0-9+#-]{1,40}$ (max 40 chars) or the create is
rejected with a clear 400. Regression tests cover truncation, malformed
and oversized language values, valid identifiers, and blank metadata.
2026-09-09 10:58:34 -05:00
fen 99a044e8a2 Rate-limit all password verification attempts (#81)
CI / test (pull_request) Successful in 22s
CI / docker (pull_request) Skipped
GET ?password= and X-Paste-Password header checks in handleGetPaste were
unlimited (pentest2: 8 wrong = 8x401, no 429). Gate every password
verification on the same per-IP+paste unlock limiter (5/min, 429 with
Retry-After) already used by the POST unlock form path.

Regression tests: repeated wrong passwords via GET ?password= and via
header must eventually 429; correct password within burst still 200.

Fixes #81
2026-09-09 10:58:21 -05:00
agent 3d1d5ee1fd ratelimit: key on rightmost X-Forwarded-For entry (fixes #85)
CI / test (pull_request) Successful in 21s
CI / docker (pull_request) Skipped
2026-09-09 10:57:59 -05:00
Hermes Agent ccb22a2d28 #83: accept boolean public field in create API (false->unlisted, true->public)
CI / test (pull_request) Successful in 23s
CI / docker (pull_request) Skipped
2026-09-09 10:57:56 -05:00
fen 3d415edbdc fix #84: security headers dropped because they were set post-flush; set pre-handler
CI / test (pull_request) Successful in 21s
CI / docker (pull_request) Skipped
2026-09-09 10:54:16 -05:00
poslop 4cb8a3e127 Merge pull request 'Search: loading indicator and performance note (#32)' (#72) from issue-32-search-indicator into main
CI / test (push) Successful in 30s
CI / docker (push) Skipped
2026-09-09 14:26:25 +00:00
poslop 91dbf6f344 Merge pull request 'fix: input validation gaps (#68)' (#78) from issue-68-input-validation into main
CI / test (push) Successful in 23s
CI / docker (push) Skipped
2026-09-09 14:26:19 +00:00