Syntax highlighting, rate limiting, creator auto-unlock (#1, #2, #26)
CI / test (push) Successful in 19s
CI / docker (push) Skipped

#1: server-side regex highlighter (highlight.go) for go/python/js/json/bash/sql;
token span classes styled in app.css; per-line so gutter stays aligned.
#2: in-memory token-bucket rate limiter (ratelimit.go) on POST /api/pastes,
/api/guess-language and unlock POST; 429 + Retry-After + X-RateLimit headers.
#26: new-page JS POSTs the password to /{id} with ?next= after creation; the
unlock handler honors same-origin ?next= redirect so the creator lands on the
unlocked paste. POST /{id} route added.

Tests: ratelimit_test.go (burst/429, refill, unlock limit, highlight, auto-
unlock e2e); existing tests updated for per-test limiter isolation.
This commit is contained in:
2026-09-08 21:09:25 -05:00
parent 9d75d2f80d
commit 3facff3d1e
11 changed files with 511 additions and 4 deletions
+2 -1
View File
@@ -47,8 +47,9 @@ func TestCustomSlugValidation(t *testing.T) {
{"bad slug", `{"content":"x","custom_slug":"has space"}`, 400},
{"", `{"content":"x","custom_slug":""}`, 201}, // empty = no custom slug, fine
}
for _, c := range cases {
for i, c := range cases {
req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(c.body))
req.RemoteAddr = "10.7.1." + string(rune('1'+i)) + ":1000" // avoid rate-limit bucket sharing
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != c.wantCode {