@@ -580,6 +580,97 @@ describe('Callback URL handling', () => {
580580 expect ( data . session ) . toBeDefined ( )
581581 expect ( data . session ?. access_token ) . toBe ( 'test-token' )
582582 } )
583+
584+ it ( 'should detect Supabase callback with sb parameter' , async ( ) => {
585+ // Simulate Supabase OAuth redirect with sb identifier
586+ window . location . href =
587+ 'http://localhost:9999/callback#access_token=test-token&refresh_token=test-refresh&expires_in=3600&token_type=bearer&sb'
588+
589+ // Mock fetch for user info
590+ mockFetch . mockImplementation ( ( url : string ) => {
591+ if ( url . includes ( '/user' ) ) {
592+ return Promise . resolve ( {
593+ ok : true ,
594+ json : ( ) =>
595+ Promise . resolve ( {
596+ id : 'test-user' ,
597+ 598+ created_at : new Date ( ) . toISOString ( ) ,
599+ } ) ,
600+ } )
601+ }
602+ return Promise . resolve ( { ok : true , json : ( ) => Promise . resolve ( { } ) } )
603+ } )
604+
605+ const client = new ( require ( '../src/GoTrueClient' ) . default ) ( {
606+ url : 'http://localhost:9999' ,
607+ detectSessionInUrl : true ,
608+ autoRefreshToken : false ,
609+ storage : mockStorage ,
610+ } )
611+
612+ await client . initialize ( )
613+
614+ // Should process the callback because sb parameter is present
615+ const { data } = await client . getSession ( )
616+ expect ( data . session ) . toBeDefined ( )
617+ expect ( data . session ?. access_token ) . toBe ( 'test-token' )
618+ } )
619+
620+ it ( 'should detect legacy callbacks without sb parameter for backwards compatibility' , async ( ) => {
621+ // Simulate legacy Supabase OAuth redirect without sb identifier
622+ window . location . href =
623+ 'http://localhost:9999/callback#access_token=test-token&refresh_token=test-refresh&expires_in=3600&token_type=bearer'
624+
625+ // Mock fetch for user info
626+ mockFetch . mockImplementation ( ( url : string ) => {
627+ if ( url . includes ( '/user' ) ) {
628+ return Promise . resolve ( {
629+ ok : true ,
630+ json : ( ) =>
631+ Promise . resolve ( {
632+ id : 'test-user' ,
633+ 634+ created_at : new Date ( ) . toISOString ( ) ,
635+ } ) ,
636+ } )
637+ }
638+ return Promise . resolve ( { ok : true , json : ( ) => Promise . resolve ( { } ) } )
639+ } )
640+
641+ const client = new ( require ( '../src/GoTrueClient' ) . default ) ( {
642+ url : 'http://localhost:9999' ,
643+ detectSessionInUrl : true ,
644+ autoRefreshToken : false ,
645+ storage : mockStorage ,
646+ } )
647+
648+ await client . initialize ( )
649+
650+ // Should still process the callback for backwards compatibility
651+ const { data } = await client . getSession ( )
652+ expect ( data . session ) . toBeDefined ( )
653+ expect ( data . session ?. access_token ) . toBe ( 'test-token' )
654+ } )
655+
656+ it ( 'should detect error callbacks with sb parameter' , async ( ) => {
657+ // Simulate Supabase OAuth error redirect with sb identifier
658+ window . location . href =
659+ 'http://localhost:9999/callback#error=access_denied&error_description=User%20denied%20access&sb'
660+
661+ const client = new ( require ( '../src/GoTrueClient' ) . default ) ( {
662+ url : 'http://localhost:9999' ,
663+ detectSessionInUrl : true ,
664+ autoRefreshToken : false ,
665+ storage : mockStorage ,
666+ } )
667+
668+ const { error } = await client . initialize ( )
669+
670+ // Should detect and process the error callback
671+ expect ( error ) . toBeDefined ( )
672+ expect ( error ?. message ) . toContain ( 'access_denied' )
673+ } )
583674} )
584675
585676describe ( 'GoTrueClient BroadcastChannel' , ( ) => {
0 commit comments