Preserve safe return paths through sign-in
CI / test (push) Failing after 3m18s

This commit is contained in:
2026-09-16 05:36:36 +02:00
parent b6d264c9ec
commit 87809b2344
8 changed files with 116 additions and 6 deletions
+53 -3
View File
@@ -272,8 +272,32 @@ func TestProtectedPageRedirectsWithoutSession(t *testing.T) {
if response.Code != http.StatusSeeOther {
t.Fatalf("status: got %d, want %d", response.Code, http.StatusSeeOther)
}
if location := response.Header().Get("Location"); location != "/login" {
t.Errorf("Location: got %q, want %q", location, "/login")
if location := response.Header().Get("Location"); location != "/login?return_to=%2Fgardens" {
t.Errorf("Location: got %q, want login with return path", location)
}
}
func TestProtectedInvitationRedirectPreservesToken(t *testing.T) {
apiHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/v1/session" {
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write([]byte(`{"error":"you must be authenticated"}`))
return
}
http.NotFound(w, r)
})
app := newAPIBackedTestApplication(t, apiHandler)
request := httptest.NewRequest(http.MethodGet, "/invite?token=garden-invite-token", nil)
response := httptest.NewRecorder()
app.routes().ServeHTTP(response, request)
if response.Code != http.StatusSeeOther {
t.Fatalf("status: got %d, want %d", response.Code, http.StatusSeeOther)
}
want := "/login?return_to=%2Finvite%3Ftoken%3Dgarden-invite-token"
if location := response.Header().Get("Location"); location != want {
t.Errorf("Location: got %q, want %q", location, want)
}
}
@@ -288,7 +312,7 @@ func TestSignInForwardsAPISessionCookie(t *testing.T) {
_, _ = w.Write([]byte(`{"user":{"id":7,"name":"Alice","activated":true}}`))
})
app := newAPIBackedTestApplication(t, apiHandler)
form := url.Values{"email": {"alice@example.com"}, "password": {"correct horse battery staple"}}
form := url.Values{"email": {"alice@example.com"}, "password": {"correct horse battery staple"}, "return_to": {"/invite?token=garden-invite-token"}}
request := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader(form.Encode()))
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request = request.WithContext(client.NewContext(request.Context(), app.apiClient))
@@ -302,6 +326,32 @@ func TestSignInForwardsAPISessionCookie(t *testing.T) {
if cookies := response.Result().Cookies(); len(cookies) != 1 || cookies[0].Value != "new-session" {
t.Fatalf("forwarded cookies: got %+v", cookies)
}
if location := response.Header().Get("Location"); location != "/invite?token=garden-invite-token" {
t.Errorf("Location: got %q, want invitation URL", location)
}
}
func TestSignInRejectsExternalReturnURL(t *testing.T) {
apiHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost || r.URL.Path != "/v1/session" {
http.NotFound(w, r)
return
}
w.WriteHeader(http.StatusCreated)
_, _ = w.Write([]byte(`{"user":{"id":7,"name":"Alice","activated":true}}`))
})
app := newAPIBackedTestApplication(t, apiHandler)
form := url.Values{"email": {"alice@example.com"}, "password": {"correct horse battery staple"}, "return_to": {"https://example.com/phishing"}}
request := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader(form.Encode()))
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request = request.WithContext(client.NewContext(request.Context(), app.apiClient))
response := httptest.NewRecorder()
app.signInPost(response, request)
if location := response.Header().Get("Location"); location != "/gardens?auto=1" {
t.Errorf("Location: got %q, want default landing page", location)
}
}
func TestInactiveSignInRedirectsToActivation(t *testing.T) {