@@ -50,7 +50,8 @@ func init() {
5050func TestFlowLifecycle (t * testing.T ) {
5151 ctx := context .Background ()
5252 conf , reg := internal .NewFastRegistryWithMocks (t )
53- reg .SetHydra (hydra .NewFake ())
53+ fakeHydra := hydra .NewFake ()
54+ reg .SetHydra (fakeHydra )
5455
5556 routerPublic := httprouterx .NewTestRouterPublic (t )
5657 ts , _ := testhelpers .NewKratosServerWithRouters (t , reg , routerPublic , httprouterx .NewTestRouterAdminWithPrefix (t ))
@@ -837,6 +838,31 @@ func TestFlowLifecycle(t *testing.T) {
837838
838839 assert .NotEmpty (t , gjson .GetBytes (body , "oauth2_login_request" ).Value (), "%s" , body )
839840 })
841+
842+ t .Run ("case=oauth2 flow with existing session and JSON request should not return null" , func (t * testing.T ) {
843+ // This test reproduces issue #10255 where the /self-service/login/browser endpoint
844+ // returns null when called with an existing session, a Hydra login challenge, and
845+ // an Accept: application/json header.
846+
847+ // Has a side effect on this test suite but since its running serial and there is no significantly easier way it's acceptable.
848+ fakeHydra .Skip = true
849+ t .Cleanup (func () {
850+ fakeHydra .Skip = false
851+ })
852+
853+ // Make a login request with an authenticated session, Hydra login challenge, and JSON accept
854+ req := testhelpers .NewTestHTTPRequest (t , "GET" , ts .URL + login .RouteInitBrowserFlow + "?login_challenge=" + hydra .FakeValidLoginChallenge , nil )
855+ req .Header .Set ("Accept" , "application/json" )
856+ body , res := testhelpers .MockMakeAuthenticatedRequest (t , reg , conf , routerPublic , req )
857+
858+ // Before the fix, this would return 200 OK with "null" as body because of variable shadowing
859+ // After the fix, it should return a proper error response with ErrAlreadyLoggedIn
860+ assert .Equal (t , http .StatusBadRequest , res .StatusCode , "Response should be 400 Bad Request, got body: %s" , body )
861+ assert .NotEqual (t , "null" , string (body ), "Response should not be null" )
862+ assert .NotEmpty (t , gjson .GetBytes (body , "error.id" ).String (), "Should have error.id field, got body: %s" , body )
863+ assert .Equal (t , "session_already_available" , gjson .GetBytes (body , "error.id" ).String (), "Should return session_already_available error, got body: %s" , body )
864+ assert .Contains (t , gjson .GetBytes (body , "error.reason" ).String (), "A valid session was detected" , "Should have proper error reason, got body: %s" , body )
865+ })
840866 })
841867
842868 t .Run ("case=relative redirect when self-service login ui is a relative URL" , func (t * testing.T ) {
0 commit comments