@@ -2028,6 +2028,44 @@ func Test_noCacheHeaders(t *testing.T) {
20282028 })
20292029}
20302030
2031+func TestSignOutCallsBackendLogoutURL(t *testing.T) {
2032+ const testIDToken = "test-id-token-12345"
2033+ var receivedURL string
2034+ backendLogoutServer := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
2035+ receivedURL = req.URL.String()
2036+ rw.WriteHeader(http.StatusOK)
2037+ }))
2038+ defer backendLogoutServer.Close()
2039+
2040+ opts := baseTestOptions()
2041+ opts.Providers[0].BackendLogoutURL = backendLogoutServer.URL + "/logout?id_token_hint={id_token}"
2042+ err := validation.Validate(opts)
2043+ require.NoError(t, err)
2044+
2045+ proxy, err := NewOAuthProxy(opts, func(string) bool { return true })
2046+ require.NoError(t, err)
2047+
2048+ // Save a session with IDToken so backend logout can use it
2049+ rw := httptest.NewRecorder()
2050+ req := httptest.NewRequest(http.MethodGet, "/", nil)
2051+ err = proxy.sessionStore.Save(rw, req, &sessions.SessionState{
2052+ Email: "user@example.com",
2053+ IDToken: testIDToken,
2054+ })
2055+ require.NoError(t, err)
2056+ cookie := rw.Header().Values("Set-Cookie")[0]
2057+
2058+ // Hit sign_out with the session cookie; backend logout should be called before session is cleared
2059+ signOutReq := httptest.NewRequest(http.MethodGet, "/oauth2/sign_out", nil)
2060+ signOutReq.Header.Set("Cookie", cookie)
2061+ rec := httptest.NewRecorder()
2062+ proxy.ServeHTTP(rec, signOutReq)
2063+
2064+ assert.Equal(t, http.StatusFound, rec.Code, "sign_out should redirect")
2065+ assert.Contains(t, receivedURL, "id_token_hint="+testIDToken,
2066+ "backend logout URL should have been called with id_token from session")
2067+}
2068+
20312069func baseTestOptions() *options.Options {
20322070 opts := options.NewOptions()
20332071 opts.Cookie.Secret = rawCookieSecret