@@ -1395,3 +1395,45 @@ test('custom sessionKey isolates state from another strategy', async (t) => {
13951395 t . truthy ( harness1 . session [ 'strategy-b' ] )
13961396 t . not ( harness1 . session [ 'strategy-a' ] , harness1 . session [ 'strategy-b' ] )
13971397} )
1398+
1399+ // --- Session state cleanup ---
1400+
1401+ test ( 'successful callback calls success and clears session state' , async ( t ) => {
1402+ const { port, server } = await startTokenEndpoint ( )
1403+ t . teardown ( ( ) => close ( server ) )
1404+
1405+ const harness = createStrategyHarness ( port )
1406+ const redirectTo = await doAuthorizationRequest ( harness )
1407+
1408+ await doAuthorizationCodeGrant (
1409+ harness ,
1410+ `${ new URL ( redirectTo ) . origin } /cb?code=ok` ,
1411+ )
1412+
1413+ t . truthy ( harness . results . successUser )
1414+ t . deepEqual ( harness . session , { } )
1415+ } )
1416+
1417+ test ( 'replayed callback fails because state was consumed' , async ( t ) => {
1418+ const { port, server } = await startTokenEndpoint ( )
1419+ t . teardown ( ( ) => close ( server ) )
1420+
1421+ const harness = createStrategyHarness ( port )
1422+ const redirectTo = await doAuthorizationRequest ( harness )
1423+ const callbackUrl = `${ new URL ( redirectTo ) . origin } /cb?code=ok`
1424+
1425+ // First callback succeeds
1426+ await doAuthorizationCodeGrant ( harness , callbackUrl )
1427+ t . truthy ( harness . results . successUser )
1428+
1429+ // Reset results
1430+ harness . results . successUser = undefined
1431+ harness . results . failInfo = undefined
1432+
1433+ // Second callback with same session should fail
1434+ await doAuthorizationCodeGrant ( harness , callbackUrl )
1435+ t . truthy ( harness . results . failInfo )
1436+ t . like ( harness . results . failInfo as Record < string , unknown > , {
1437+ message : 'Unable to verify authorization request state' ,
1438+ } )
1439+ } )
0 commit comments