Skip to content
Closed
89 changes: 88 additions & 1 deletion spec/ParseUser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2192,7 +2192,8 @@ describe('Parse.User testing', () => {
request.put({
headers: {
'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,
body: JSON.stringify({ foo: 'bar' })
Expand All @@ -2205,6 +2206,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) => {
Parse.Promise.as().then(() => {
return Parse.User.signUp("test1", "test", { foo: "bar" });
Expand Down Expand Up @@ -2278,13 +2323,55 @@ describe('Parse.User testing', () => {
expect(error).toBe(null);
var b = JSON.parse(body);
expect(b.code).toEqual(209);
expect(b.error).toBe('invalid session token');
done();
});
});
});
});
});

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) => {
var hashed = '$2a$10$8/wZJyEuiEaobBBqzTG.jeY.XSFJd0rzaN//ososvEI4yLqI.4aie';
passwordCrypto.compare('test', hashed)
Expand Down
6 changes: 6 additions & 0 deletions src/Adapters/Storage/Postgres/PostgresStorageAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ const buildWhereClause = ({ schema, query, index }) => {
const initialPatternsLength = patterns.length;
const fieldValue = query[fieldName];

if (schema.className === '_Session' && fieldName === 'sessionToken' && !fieldValue) {
throw new Parse.Error(
Parse.Error.INVALID_SESSION_TOKEN,
'invalid session token'
);
}
// nothingin the schema, it's gonna blow up
if (!schema.fields[fieldName]) {
// as it won't exist
Expand Down
3 changes: 2 additions & 1 deletion src/middlewares.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ export function handleParseHeaders(req, res, next) {
delete info.sessionToken;
}

if (!info.sessionToken) {
//if empty sessionToken and it's not a delete operation on _Session class
if (!info.sessionToken && !(req.method === 'DELETE' && req.url.startsWith("/sessions"))) {
req.auth = new auth.Auth({ config: req.config, installationId: info.installationId, isMaster: false });
next();
return;
Expand Down
5 changes: 4 additions & 1 deletion src/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ function del(config, auth, className, objectId) {
.then((response) => {
if (response && response.results && response.results.length) {
response.results[0].className = className;

if(auth.sessionToken && (response.results[0].sessionToken !== auth.sessionToken)){
throw new Parse.Error(Parse.Error.SESSION_MISSING,
'insufficient auth to delete session');
}
var cacheAdapter = config.cacheController;
cacheAdapter.user.del(response.results[0].sessionToken);
inflatedObject = Parse.Object.fromJSON(response.results[0]);
Expand Down