fix(#3898): session token deletion (#3937)

* fix(#3898): session token deletion

* nits
This commit is contained in:
Florent Vilmart
2017-06-16 12:56:28 -04:00
committed by GitHub
parent 9d79ba1ccb
commit 16954c2f74
2 changed files with 101 additions and 12 deletions

View File

@@ -1960,10 +1960,8 @@ describe('Parse.User testing', () => {
}); });
it("querying for users doesn't get session tokens", (done) => { it("querying for users doesn't get session tokens", (done) => {
Parse.Promise.as().then(function() { Parse.User.signUp("finn", "human", { foo: "bar" })
return Parse.User.signUp("finn", "human", { foo: "bar" }); .then(function() {
}).then(function() {
return Parse.User.logOut(); return Parse.User.logOut();
}).then(() => { }).then(() => {
var user = new Parse.User(); var user = new Parse.User();
@@ -1992,9 +1990,8 @@ describe('Parse.User testing', () => {
}); });
it("querying for users only gets the expected fields", (done) => { it("querying for users only gets the expected fields", (done) => {
Parse.Promise.as().then(() => { Parse.User.signUp("finn", "human", { foo: "bar" })
return Parse.User.signUp("finn", "human", { foo: "bar" }); .then(() => {
}).then(() => {
request.get({ request.get({
headers: {'X-Parse-Application-Id': 'test', headers: {'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest'}, 'X-Parse-REST-API-Key': 'rest'},
@@ -2192,7 +2189,8 @@ describe('Parse.User testing', () => {
request.put({ request.put({
headers: { headers: {
'X-Parse-Application-Id': 'test', 'X-Parse-Application-Id': 'test',
'X-Parse-Session-Token': user.getSessionToken() 'X-Parse-Session-Token': user.getSessionToken(),
'X-Parse-REST-API-Key': 'rest'
}, },
url: 'http://localhost:8378/1/sessions/' + b.objectId, url: 'http://localhost:8378/1/sessions/' + b.objectId,
body: JSON.stringify({ foo: 'bar' }) body: JSON.stringify({ foo: 'bar' })
@@ -2205,6 +2203,50 @@ describe('Parse.User testing', () => {
}); });
}); });
it('cannot update session if invalid or no session token', (done) => {
Parse.Promise.as().then(() => {
return Parse.User.signUp("finn", "human", { foo: "bar" });
}).then((user) => {
request.get({
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-Session-Token': user.getSessionToken(),
'X-Parse-REST-API-Key': 'rest'
},
url: 'http://localhost:8378/1/sessions/me',
}, (error, response, body) => {
expect(error).toBe(null);
var b = JSON.parse(body);
request.put({
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-Session-Token': 'foo',
'X-Parse-REST-API-Key': 'rest'
},
url: 'http://localhost:8378/1/sessions/' + b.objectId,
body: JSON.stringify({ foo: 'bar' })
}, (error, response, body) => {
expect(error).toBe(null);
var b = JSON.parse(body);
expect(b.error).toBe('invalid session token');
request.put({
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest'
},
url: 'http://localhost:8378/1/sessions/' + b.objectId,
body: JSON.stringify({ foo: 'bar' })
}, (error, response, body) => {
expect(error).toBe(null);
var b = JSON.parse(body);
expect(b.error).toBe('Session token required.');
done();
});
});
});
});
});
it('get session only for current user', (done) => { it('get session only for current user', (done) => {
Parse.Promise.as().then(() => { Parse.Promise.as().then(() => {
return Parse.User.signUp("test1", "test", { foo: "bar" }); return Parse.User.signUp("test1", "test", { foo: "bar" });
@@ -2278,6 +2320,7 @@ describe('Parse.User testing', () => {
expect(error).toBe(null); expect(error).toBe(null);
var b = JSON.parse(body); var b = JSON.parse(body);
expect(b.code).toEqual(209); expect(b.code).toEqual(209);
expect(b.error).toBe('invalid session token');
done(); done();
}); });
}); });
@@ -2285,6 +2328,47 @@ describe('Parse.User testing', () => {
}); });
}); });
it('cannot delete session if no sessionToken', (done) => {
Parse.Promise.as().then(() => {
return Parse.User.signUp("test1", "test", { foo: "bar" });
}).then(() => {
return Parse.User.signUp("test2", "test", { foo: "bar" });
}).then((user) => {
request.get({
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-Session-Token': user.getSessionToken(),
'X-Parse-REST-API-Key': 'rest'
},
url: 'http://localhost:8378/1/sessions'
}, (error, response, body) => {
expect(error).toBe(null);
var objId;
try {
var b = JSON.parse(body);
expect(b.results.length).toEqual(1);
objId = b.results[0].objectId;
} catch(e) {
jfail(e);
done();
return;
}
request.del({
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-REST-API-Key': 'rest'
},
url: 'http://localhost:8378/1/sessions/' + objId
}, (error,response,body) => {
var b = JSON.parse(body);
expect(b.code).toEqual(209);
expect(b.error).toBe('invalid session token');
done();
});
});
});
});
it('password format matches hosted parse', (done) => { it('password format matches hosted parse', (done) => {
var hashed = '$2a$10$8/wZJyEuiEaobBBqzTG.jeY.XSFJd0rzaN//ososvEI4yLqI.4aie'; var hashed = '$2a$10$8/wZJyEuiEaobBBqzTG.jeY.XSFJd0rzaN//ososvEI4yLqI.4aie';
passwordCrypto.compare('test', hashed) passwordCrypto.compare('test', hashed)

View File

@@ -65,11 +65,16 @@ function del(config, auth, className, objectId) {
return find(config, Auth.master(config), className, {objectId: objectId}) return find(config, Auth.master(config), className, {objectId: objectId})
.then((response) => { .then((response) => {
if (response && response.results && response.results.length) { if (response && response.results && response.results.length) {
response.results[0].className = className; const firstResult = response.results[0];
firstResult.className = className;
if (className === '_Session' && !auth.isMaster) {
if (!auth.user || firstResult.user.objectId !== auth.user.id) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid session token');
}
}
var cacheAdapter = config.cacheController; var cacheAdapter = config.cacheController;
cacheAdapter.user.del(response.results[0].sessionToken); cacheAdapter.user.del(firstResult.sessionToken);
inflatedObject = Parse.Object.fromJSON(response.results[0]); inflatedObject = Parse.Object.fromJSON(firstResult);
// Notify LiveQuery server if possible // Notify LiveQuery server if possible
config.liveQueryController.onAfterDelete(inflatedObject.className, inflatedObject); config.liveQueryController.onAfterDelete(inflatedObject.className, inflatedObject);
return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config); return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config);