@@ -257,6 +257,143 @@ describe('Parse.Session', () => {
257257 expect ( newSession . createdWith . authProvider ) . toBeUndefined ( ) ;
258258 } ) ;
259259
260+ it ( 'should reject expiresAt when updating a session via PUT' , async ( ) => {
261+ const user = await Parse . User . signUp ( 'sessionupdateuser1' , 'password' ) ;
262+ const sessionToken = user . getSessionToken ( ) ;
263+
264+ // Get the session objectId
265+ const sessionRes = await request ( {
266+ method : 'GET' ,
267+ url : 'http://localhost:8378/1/sessions/me' ,
268+ headers : {
269+ 'X-Parse-Application-Id' : 'test' ,
270+ 'X-Parse-REST-API-Key' : 'rest' ,
271+ 'X-Parse-Session-Token' : sessionToken ,
272+ } ,
273+ } ) ;
274+ const sessionId = sessionRes . data . objectId ;
275+ const originalExpiresAt = sessionRes . data . expiresAt ;
276+
277+ // Attempt to overwrite expiresAt via PUT
278+ const updateRes = await request ( {
279+ method : 'PUT' ,
280+ url : `http://localhost:8378/1/sessions/${ sessionId } ` ,
281+ headers : {
282+ 'X-Parse-Application-Id' : 'test' ,
283+ 'X-Parse-REST-API-Key' : 'rest' ,
284+ 'X-Parse-Session-Token' : sessionToken ,
285+ 'Content-Type' : 'application/json' ,
286+ } ,
287+ body : {
288+ expiresAt : { __type : 'Date' , iso : '2099-12-31T23:59:59.000Z' } ,
289+ } ,
290+ } ) . catch ( e => e ) ;
291+
292+ expect ( updateRes . data . code ) . toBe ( Parse . Error . INVALID_KEY_NAME ) ;
293+
294+ // Verify expiresAt was not changed
295+ const verifyRes = await request ( {
296+ method : 'GET' ,
297+ url : 'http://localhost:8378/1/sessions/me' ,
298+ headers : {
299+ 'X-Parse-Application-Id' : 'test' ,
300+ 'X-Parse-REST-API-Key' : 'rest' ,
301+ 'X-Parse-Session-Token' : sessionToken ,
302+ } ,
303+ } ) ;
304+ expect ( verifyRes . data . expiresAt ) . toEqual ( originalExpiresAt ) ;
305+ } ) ;
306+
307+ it ( 'should reject createdWith when updating a session via PUT' , async ( ) => {
308+ const user = await Parse . User . signUp ( 'sessionupdateuser2' , 'password' ) ;
309+ const sessionToken = user . getSessionToken ( ) ;
310+
311+ // Get the session objectId
312+ const sessionRes = await request ( {
313+ method : 'GET' ,
314+ url : 'http://localhost:8378/1/sessions/me' ,
315+ headers : {
316+ 'X-Parse-Application-Id' : 'test' ,
317+ 'X-Parse-REST-API-Key' : 'rest' ,
318+ 'X-Parse-Session-Token' : sessionToken ,
319+ } ,
320+ } ) ;
321+ const sessionId = sessionRes . data . objectId ;
322+ const originalCreatedWith = sessionRes . data . createdWith ;
323+
324+ // Attempt to overwrite createdWith via PUT
325+ const updateRes = await request ( {
326+ method : 'PUT' ,
327+ url : `http://localhost:8378/1/sessions/${ sessionId } ` ,
328+ headers : {
329+ 'X-Parse-Application-Id' : 'test' ,
330+ 'X-Parse-REST-API-Key' : 'rest' ,
331+ 'X-Parse-Session-Token' : sessionToken ,
332+ 'Content-Type' : 'application/json' ,
333+ } ,
334+ body : {
335+ createdWith : { action : 'attacker' , authProvider : 'evil' } ,
336+ } ,
337+ } ) . catch ( e => e ) ;
338+
339+ expect ( updateRes . data . code ) . toBe ( Parse . Error . INVALID_KEY_NAME ) ;
340+
341+ // Verify createdWith was not changed
342+ const verifyRes = await request ( {
343+ method : 'GET' ,
344+ url : 'http://localhost:8378/1/sessions/me' ,
345+ headers : {
346+ 'X-Parse-Application-Id' : 'test' ,
347+ 'X-Parse-REST-API-Key' : 'rest' ,
348+ 'X-Parse-Session-Token' : sessionToken ,
349+ } ,
350+ } ) ;
351+ expect ( verifyRes . data . createdWith ) . toEqual ( originalCreatedWith ) ;
352+ } ) ;
353+
354+ it ( 'should allow master key to update expiresAt on a session' , async ( ) => {
355+ const user = await Parse . User . signUp ( 'sessionupdateuser3' , 'password' ) ;
356+ const sessionToken = user . getSessionToken ( ) ;
357+
358+ // Get the session objectId
359+ const sessionRes = await request ( {
360+ method : 'GET' ,
361+ url : 'http://localhost:8378/1/sessions/me' ,
362+ headers : {
363+ 'X-Parse-Application-Id' : 'test' ,
364+ 'X-Parse-REST-API-Key' : 'rest' ,
365+ 'X-Parse-Session-Token' : sessionToken ,
366+ } ,
367+ } ) ;
368+ const sessionId = sessionRes . data . objectId ;
369+ const farFuture = '2099-12-31T23:59:59.000Z' ;
370+
371+ // Master key should be able to update expiresAt
372+ await request ( {
373+ method : 'PUT' ,
374+ url : `http://localhost:8378/1/sessions/${ sessionId } ` ,
375+ headers : {
376+ 'X-Parse-Application-Id' : 'test' ,
377+ 'X-Parse-Master-Key' : 'test' ,
378+ 'Content-Type' : 'application/json' ,
379+ } ,
380+ body : {
381+ expiresAt : { __type : 'Date' , iso : farFuture } ,
382+ } ,
383+ } ) ;
384+
385+ // Verify expiresAt was changed
386+ const verifyRes = await request ( {
387+ method : 'GET' ,
388+ url : `http://localhost:8378/1/sessions/${ sessionId } ` ,
389+ headers : {
390+ 'X-Parse-Application-Id' : 'test' ,
391+ 'X-Parse-Master-Key' : 'test' ,
392+ } ,
393+ } ) ;
394+ expect ( verifyRes . data . expiresAt . iso ) . toBe ( farFuture ) ;
395+ } ) ;
396+
260397 describe ( 'PUT /sessions/me' , ( ) => {
261398 it ( 'should return error with invalid session token' , async ( ) => {
262399 const response = await request ( {
0 commit comments