@@ -3318,6 +3318,47 @@ describe('Parse.User testing', () => {
33183318 expect ( session . get ( 'expiresAt' ) ) . toEqual ( expiresAt ) ;
33193319 } ) ;
33203320
3321+ it ( 'should reject expired session token even when served from cache' , async ( ) => {
3322+ // Use a 1-second session length with a 5-second cache TTL (default)
3323+ // so the session expires while the cache entry is still alive
3324+ await reconfigureServer ( { sessionLength : 1 } ) ;
3325+
3326+ // Sign up user — creates a session with expiresAt = now + 1 second
3327+ const user = await Parse . User . signUp ( 'cacheuser' , 'somepass' ) ;
3328+ const sessionToken = user . getSessionToken ( ) ;
3329+
3330+ // Make an authenticated request to prime the user cache
3331+ await request ( {
3332+ method : 'GET' ,
3333+ url : 'http://localhost:8378/1/users/me' ,
3334+ headers : {
3335+ 'X-Parse-Application-Id' : 'test' ,
3336+ 'X-Parse-REST-API-Key' : 'rest' ,
3337+ 'X-Parse-Session-Token' : sessionToken ,
3338+ } ,
3339+ } ) ;
3340+
3341+ // Wait for the session to expire (1 second), but cache entry (5s TTL) is still alive
3342+ await new Promise ( resolve => setTimeout ( resolve , 1500 ) ) ;
3343+
3344+ // This request should be served from cache but still reject the expired session
3345+ try {
3346+ await request ( {
3347+ method : 'GET' ,
3348+ url : 'http://localhost:8378/1/users/me' ,
3349+ headers : {
3350+ 'X-Parse-Application-Id' : 'test' ,
3351+ 'X-Parse-REST-API-Key' : 'rest' ,
3352+ 'X-Parse-Session-Token' : sessionToken ,
3353+ } ,
3354+ } ) ;
3355+ fail ( 'Should have rejected expired session token from cache' ) ;
3356+ } catch ( error ) {
3357+ expect ( error . data . code ) . toEqual ( 209 ) ;
3358+ expect ( error . data . error ) . toEqual ( 'Session token is expired.' ) ;
3359+ }
3360+ } ) ;
3361+
33213362 it ( 'should not create extraneous session tokens' , done => {
33223363 const config = Config . get ( Parse . applicationId ) ;
33233364 config . database
0 commit comments