package calendartest import ( "net/http" "net/http/httptest" "net/url" "strings" "testing" ) // The scheduled-tick route must be mounted OUTSIDE csrf.Protect, and // this test is the whole reason to believe it is. // // csrf.Protect refuses any POST that carries no Sec-Fetch-Site, Origin // or Referer. The platform's scheduler is not a browser and sends none // of the three, so a tick route mounted inside the protected router // answers 403 — and the platform reads 4xx as "do not retry". The // result is reminders that never fire, on an app that looks entirely // healthy, with nothing in any log to say why. // // So: a POST with none of the CSRF evidence must NOT be refused by // CSRF. It is refused by carlos.Tick instead, which is a different // refusal for a different reason — and off-platform, with no // $CARLOS_ADMIN_TOKEN in the environment, Tick is false, so 403 here is // the correct answer arrived at correctly. // // The two are told apart by the body: csrf.Protect writes its own, and // this handler writes "forbidden". func TestTheTickRouteIsNotBehindCSRF(t *testing.T) { h := newApp(t).Handler() // Deliberately bare: no Origin, no Referer, no Sec-Fetch-Site — // exactly what the platform's scheduler sends. req := httptest.NewRequest(http.MethodPost, "/jobs/reminders", nil) rec := httptest.NewRecorder() h.ServeHTTP(rec, req) if rec.Code != http.StatusForbidden { t.Fatalf("POST /jobs/reminders: status %d, want 403 from the tick guard", rec.Code) } if got := strings.TrimSpace(rec.Body.String()); got != "forbidden" { t.Errorf("POST /jobs/reminders was refused by %q, which is not the tick guard — "+ "it is almost certainly csrf.Protect, which means the route is inside the "+ "protected router and ticks will 403 forever", got) } } // The contrast case: an ordinary state-changing route IS behind CSRF, // so the test above is proving a difference rather than proving that // CSRF is off everywhere. func TestOrdinaryPostsAreBehindCSRF(t *testing.T) { h := newApp(t).Handler() req := httptest.NewRequest(http.MethodPost, "/signin", strings.NewReader(url.Values{"address": {"someone@example.com"}}.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // No Origin: a cross-origin POST, which must be refused. req.Header.Set("Sec-Fetch-Site", "cross-site") rec := httptest.NewRecorder() h.ServeHTTP(rec, req) if rec.Code == http.StatusSeeOther { t.Error("a cross-site POST to /signin succeeded; csrf.Protect is not covering the app") } }