Skip to content

Commit 16954c2

Browse files
authored
fix(#3898): session token deletion (#3937)
* fix(#3898): session token deletion * nits
1 parent 9d79ba1 commit 16954c2

File tree

2 files changed

+101
-12
lines changed

2 files changed

+101
-12
lines changed

spec/ParseUser.spec.js

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,10 +1960,8 @@ describe('Parse.User testing', () => {
19601960
});
19611961

19621962
it("querying for users doesn't get session tokens", (done) => {
1963-
Parse.Promise.as().then(function() {
1964-
return Parse.User.signUp("finn", "human", { foo: "bar" });
1965-
1966-
}).then(function() {
1963+
Parse.User.signUp("finn", "human", { foo: "bar" })
1964+
.then(function() {
19671965
return Parse.User.logOut();
19681966
}).then(() => {
19691967
var user = new Parse.User();
@@ -1992,9 +1990,8 @@ describe('Parse.User testing', () => {
19921990
});
19931991

19941992
it("querying for users only gets the expected fields", (done) => {
1995-
Parse.Promise.as().then(() => {
1996-
return Parse.User.signUp("finn", "human", { foo: "bar" });
1997-
}).then(() => {
1993+
Parse.User.signUp("finn", "human", { foo: "bar" })
1994+
.then(() => {
19981995
request.get({
19991996
headers: {'X-Parse-Application-Id': 'test',
20001997
'X-Parse-REST-API-Key': 'rest'},
@@ -2192,7 +2189,8 @@ describe('Parse.User testing', () => {
21922189
request.put({
21932190
headers: {
21942191
'X-Parse-Application-Id': 'test',
2195-
'X-Parse-Session-Token': user.getSessionToken()
2192+
'X-Parse-Session-Token': user.getSessionToken(),
2193+
'X-Parse-REST-API-Key': 'rest'
21962194
},
21972195
url: 'http://localhost:8378/1/sessions/' + b.objectId,
21982196
body: JSON.stringify({ foo: 'bar' })
@@ -2205,6 +2203,50 @@ describe('Parse.User testing', () => {
22052203
});
22062204
});
22072205

2206+
it('cannot update session if invalid or no session token', (done) => {
2207+
Parse.Promise.as().then(() => {
2208+
return Parse.User.signUp("finn", "human", { foo: "bar" });
2209+
}).then((user) => {
2210+
request.get({
2211+
headers: {
2212+
'X-Parse-Application-Id': 'test',
2213+
'X-Parse-Session-Token': user.getSessionToken(),
2214+
'X-Parse-REST-API-Key': 'rest'
2215+
},
2216+
url: 'http://localhost:8378/1/sessions/me',
2217+
}, (error, response, body) => {
2218+
expect(error).toBe(null);
2219+
var b = JSON.parse(body);
2220+
request.put({
2221+
headers: {
2222+
'X-Parse-Application-Id': 'test',
2223+
'X-Parse-Session-Token': 'foo',
2224+
'X-Parse-REST-API-Key': 'rest'
2225+
},
2226+
url: 'http://localhost:8378/1/sessions/' + b.objectId,
2227+
body: JSON.stringify({ foo: 'bar' })
2228+
}, (error, response, body) => {
2229+
expect(error).toBe(null);
2230+
var b = JSON.parse(body);
2231+
expect(b.error).toBe('invalid session token');
2232+
request.put({
2233+
headers: {
2234+
'X-Parse-Application-Id': 'test',
2235+
'X-Parse-REST-API-Key': 'rest'
2236+
},
2237+
url: 'http://localhost:8378/1/sessions/' + b.objectId,
2238+
body: JSON.stringify({ foo: 'bar' })
2239+
}, (error, response, body) => {
2240+
expect(error).toBe(null);
2241+
var b = JSON.parse(body);
2242+
expect(b.error).toBe('Session token required.');
2243+
done();
2244+
});
2245+
});
2246+
});
2247+
});
2248+
});
2249+
22082250
it('get session only for current user', (done) => {
22092251
Parse.Promise.as().then(() => {
22102252
return Parse.User.signUp("test1", "test", { foo: "bar" });
@@ -2278,13 +2320,55 @@ describe('Parse.User testing', () => {
22782320
expect(error).toBe(null);
22792321
var b = JSON.parse(body);
22802322
expect(b.code).toEqual(209);
2323+
expect(b.error).toBe('invalid session token');
22812324
done();
22822325
});
22832326
});
22842327
});
22852328
});
22862329
});
22872330

2331+
it('cannot delete session if no sessionToken', (done) => {
2332+
Parse.Promise.as().then(() => {
2333+
return Parse.User.signUp("test1", "test", { foo: "bar" });
2334+
}).then(() => {
2335+
return Parse.User.signUp("test2", "test", { foo: "bar" });
2336+
}).then((user) => {
2337+
request.get({
2338+
headers: {
2339+
'X-Parse-Application-Id': 'test',
2340+
'X-Parse-Session-Token': user.getSessionToken(),
2341+
'X-Parse-REST-API-Key': 'rest'
2342+
},
2343+
url: 'http://localhost:8378/1/sessions'
2344+
}, (error, response, body) => {
2345+
expect(error).toBe(null);
2346+
var objId;
2347+
try {
2348+
var b = JSON.parse(body);
2349+
expect(b.results.length).toEqual(1);
2350+
objId = b.results[0].objectId;
2351+
} catch(e) {
2352+
jfail(e);
2353+
done();
2354+
return;
2355+
}
2356+
request.del({
2357+
headers: {
2358+
'X-Parse-Application-Id': 'test',
2359+
'X-Parse-REST-API-Key': 'rest'
2360+
},
2361+
url: 'http://localhost:8378/1/sessions/' + objId
2362+
}, (error,response,body) => {
2363+
var b = JSON.parse(body);
2364+
expect(b.code).toEqual(209);
2365+
expect(b.error).toBe('invalid session token');
2366+
done();
2367+
});
2368+
});
2369+
});
2370+
});
2371+
22882372
it('password format matches hosted parse', (done) => {
22892373
var hashed = '$2a$10$8/wZJyEuiEaobBBqzTG.jeY.XSFJd0rzaN//ososvEI4yLqI.4aie';
22902374
passwordCrypto.compare('test', hashed)

src/rest.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,16 @@ function del(config, auth, className, objectId) {
6565
return find(config, Auth.master(config), className, {objectId: objectId})
6666
.then((response) => {
6767
if (response && response.results && response.results.length) {
68-
response.results[0].className = className;
69-
68+
const firstResult = response.results[0];
69+
firstResult.className = className;
70+
if (className === '_Session' && !auth.isMaster) {
71+
if (!auth.user || firstResult.user.objectId !== auth.user.id) {
72+
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid session token');
73+
}
74+
}
7075
var cacheAdapter = config.cacheController;
71-
cacheAdapter.user.del(response.results[0].sessionToken);
72-
inflatedObject = Parse.Object.fromJSON(response.results[0]);
76+
cacheAdapter.user.del(firstResult.sessionToken);
77+
inflatedObject = Parse.Object.fromJSON(firstResult);
7378
// Notify LiveQuery server if possible
7479
config.liveQueryController.onAfterDelete(inflatedObject.className, inflatedObject);
7580
return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config);

0 commit comments

Comments
 (0)