Skip to content

Commit 2a67e55

Browse files
author
Arthur Cinader
authored
Merge branch 'master' into greenkeeper/parse-server-s3-adapter-1.2.0
2 parents 22b4735 + 92d51de commit 2a67e55

14 files changed

+388
-18
lines changed

spec/AuthenticationAdapters.spec.js

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ describe('AuthenticationProviers', function() {
7171
});
7272

7373
var createOAuthUser = function(callback) {
74+
return createOAuthUserWithSessionToken(undefined, callback);
75+
}
76+
77+
var createOAuthUserWithSessionToken = function(token, callback) {
7478
var jsonBody = {
7579
authData: {
7680
myoauth: getMockMyOauthProvider().authData
@@ -81,18 +85,27 @@ describe('AuthenticationProviers', function() {
8185
headers: {'X-Parse-Application-Id': 'test',
8286
'X-Parse-REST-API-Key': 'rest',
8387
'X-Parse-Installation-Id': 'yolo',
88+
'X-Parse-Session-Token': token,
8489
'Content-Type': 'application/json' },
8590
url: 'http://localhost:8378/1/users',
86-
body: JSON.stringify(jsonBody)
91+
body: jsonBody,
92+
json: true
8793
};
8894

89-
return request.post(options, callback);
95+
return new Promise((resolve) => {
96+
request.post(options, (err, res, body) => {
97+
resolve({err, res, body});
98+
if (callback) {
99+
callback(err, res, body);
100+
}
101+
});
102+
});
90103
}
91104

92105
it("should create user with REST API", done => {
93106
createOAuthUser((error, response, body) => {
94107
expect(error).toBe(null);
95-
var b = JSON.parse(body);
108+
var b = body;
96109
ok(b.sessionToken);
97110
expect(b.objectId).not.toBeNull();
98111
expect(b.objectId).not.toBeUndefined();
@@ -118,14 +131,14 @@ describe('AuthenticationProviers', function() {
118131
var objectId;
119132
createOAuthUser((error, response, body) => {
120133
expect(error).toBe(null);
121-
var b = JSON.parse(body);
134+
var b = body
122135
expect(b.objectId).not.toBeNull();
123136
expect(b.objectId).not.toBeUndefined();
124137
objectId = b.objectId;
125138

126139
createOAuthUser((error, response, body) => {
127140
expect(error).toBe(null);
128-
var b = JSON.parse(body);
141+
var b = body;
129142
expect(b.objectId).not.toBeNull();
130143
expect(b.objectId).not.toBeUndefined();
131144
expect(b.objectId).toBe(objectId);
@@ -134,6 +147,22 @@ describe('AuthenticationProviers', function() {
134147
});
135148
});
136149

150+
it("should fail to link if session token don't match user", (done) => {
151+
Parse.User.signUp('myUser', 'password').then((user) => {
152+
return createOAuthUserWithSessionToken(user.getSessionToken());
153+
}).then(() => {
154+
return Parse.User.logOut();
155+
}).then(() => {
156+
return Parse.User.signUp('myUser2', 'password');
157+
}).then((user) => {
158+
return createOAuthUserWithSessionToken(user.getSessionToken());
159+
}).then(({ body }) => {
160+
expect(body.code).toBe(208);
161+
expect(body.error).toBe('this auth is already used');
162+
done();
163+
}).catch(done.fail);
164+
});
165+
137166
it("unlink and link with custom provider", (done) => {
138167
var provider = getMockMyOauthProvider();
139168
Parse.User._registerAuthenticationProvider(provider);

spec/CloudCode.spec.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,61 @@ describe('Cloud Code', () => {
12001200
});
12011201
});
12021202

1203+
describe('beforeSave hooks', () => {
1204+
it('should have request headers', (done) => {
1205+
Parse.Cloud.beforeSave('MyObject', (req, res) => {
1206+
expect(req.headers).toBeDefined();
1207+
res.success();
1208+
});
1209+
1210+
const MyObject = Parse.Object.extend('MyObject');
1211+
const myObject = new MyObject();
1212+
myObject.save().then(() => done());
1213+
});
1214+
});
1215+
1216+
describe('afterSave hooks', () => {
1217+
it('should have request headers', (done) => {
1218+
Parse.Cloud.afterSave('MyObject', (req) => {
1219+
expect(req.headers).toBeDefined();
1220+
});
1221+
1222+
const MyObject = Parse.Object.extend('MyObject');
1223+
const myObject = new MyObject();
1224+
myObject.save()
1225+
.then(() => done());
1226+
});
1227+
});
1228+
1229+
describe('beforeDelete hooks', () => {
1230+
it('should have request headers', (done) => {
1231+
Parse.Cloud.beforeDelete('MyObject', (req, res) => {
1232+
expect(req.headers).toBeDefined();
1233+
res.success();
1234+
});
1235+
1236+
const MyObject = Parse.Object.extend('MyObject');
1237+
const myObject = new MyObject();
1238+
myObject.save()
1239+
.then(myObj => myObj.destroy())
1240+
.then(() => done());
1241+
});
1242+
});
1243+
1244+
describe('afterDelete hooks', () => {
1245+
it('should have request headers', (done) => {
1246+
Parse.Cloud.afterDelete('MyObject', (req) => {
1247+
expect(req.headers).toBeDefined();
1248+
});
1249+
1250+
const MyObject = Parse.Object.extend('MyObject');
1251+
const myObject = new MyObject();
1252+
myObject.save()
1253+
.then(myObj => myObj.destroy())
1254+
.then(() => done());
1255+
});
1256+
});
1257+
12031258
describe('beforeFind hooks', () => {
12041259
it('should add beforeFind trigger', (done) => {
12051260
Parse.Cloud.beforeFind('MyObject', (req) => {
@@ -1334,6 +1389,26 @@ describe('beforeFind hooks', () => {
13341389
});
13351390
});
13361391
});
1392+
1393+
it('should have request headers', (done) => {
1394+
Parse.Cloud.beforeFind('MyObject', (req) => {
1395+
expect(req.headers).toBeDefined();
1396+
});
1397+
1398+
const MyObject = Parse.Object.extend('MyObject');
1399+
const myObject = new MyObject();
1400+
myObject.save()
1401+
.then((myObj) => {
1402+
const query = new Parse.Query('MyObject');
1403+
query.equalTo('objectId', myObj.id);
1404+
return Promise.all([
1405+
query.get(myObj.id),
1406+
query.first(),
1407+
query.find(),
1408+
]);
1409+
})
1410+
.then(() => done());
1411+
});
13371412
});
13381413

13391414
describe('afterFind hooks', () => {
@@ -1531,4 +1606,25 @@ describe('afterFind hooks', () => {
15311606
done();
15321607
});
15331608
});
1609+
1610+
it('should have request headers', (done) => {
1611+
Parse.Cloud.afterFind('MyObject', (req, res) => {
1612+
expect(req.headers).toBeDefined();
1613+
res.success();
1614+
});
1615+
1616+
const MyObject = Parse.Object.extend('MyObject');
1617+
const myObject = new MyObject();
1618+
myObject.save()
1619+
.then((myObj) => {
1620+
const query = new Parse.Query('MyObject');
1621+
query.equalTo('objectId', myObj.id);
1622+
return Promise.all([
1623+
query.get(myObj.id),
1624+
query.first(),
1625+
query.find(),
1626+
]);
1627+
})
1628+
.then(() => done());
1629+
});
15341630
});

spec/Middlewares.spec.js

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,161 @@ describe('middlewares', () => {
133133
});
134134
});
135135
});
136+
137+
it('should not succeed if the ip does not belong to masterKeyIps list', () => {
138+
AppCache.put(fakeReq.body._ApplicationId, {
139+
masterKey: 'masterKey',
140+
masterKeyIps: ['ip1','ip2']
141+
});
142+
fakeReq.ip = 'ip3';
143+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
144+
middlewares.handleParseHeaders(fakeReq, fakeRes);
145+
expect(fakeRes.status).toHaveBeenCalledWith(403);
146+
});
147+
148+
it('should succeed if the ip does belong to masterKeyIps list', (done) => {
149+
AppCache.put(fakeReq.body._ApplicationId, {
150+
masterKey: 'masterKey',
151+
masterKeyIps: ['ip1','ip2']
152+
});
153+
fakeReq.ip = 'ip1';
154+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
155+
middlewares.handleParseHeaders(fakeReq, fakeRes,() => {
156+
expect(fakeRes.status).not.toHaveBeenCalled();
157+
done();
158+
});
159+
});
160+
161+
it('should not succeed if the connection.remoteAddress does not belong to masterKeyIps list', () => {
162+
AppCache.put(fakeReq.body._ApplicationId, {
163+
masterKey: 'masterKey',
164+
masterKeyIps: ['ip1','ip2']
165+
});
166+
fakeReq.connection = {remoteAddress : 'ip3'};
167+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
168+
middlewares.handleParseHeaders(fakeReq, fakeRes);
169+
expect(fakeRes.status).toHaveBeenCalledWith(403);
170+
});
171+
172+
it('should succeed if the connection.remoteAddress does belong to masterKeyIps list', (done) => {
173+
AppCache.put(fakeReq.body._ApplicationId, {
174+
masterKey: 'masterKey',
175+
masterKeyIps: ['ip1','ip2']
176+
});
177+
fakeReq.connection = {remoteAddress : 'ip1'};
178+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
179+
middlewares.handleParseHeaders(fakeReq, fakeRes,() => {
180+
expect(fakeRes.status).not.toHaveBeenCalled();
181+
done();
182+
});
183+
});
184+
185+
it('should not succeed if the socket.remoteAddress does not belong to masterKeyIps list', () => {
186+
AppCache.put(fakeReq.body._ApplicationId, {
187+
masterKey: 'masterKey',
188+
masterKeyIps: ['ip1','ip2']
189+
});
190+
fakeReq.socket = {remoteAddress : 'ip3'};
191+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
192+
middlewares.handleParseHeaders(fakeReq, fakeRes);
193+
expect(fakeRes.status).toHaveBeenCalledWith(403);
194+
});
195+
196+
it('should succeed if the socket.remoteAddress does belong to masterKeyIps list', (done) => {
197+
AppCache.put(fakeReq.body._ApplicationId, {
198+
masterKey: 'masterKey',
199+
masterKeyIps: ['ip1','ip2']
200+
});
201+
fakeReq.socket = {remoteAddress : 'ip1'};
202+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
203+
middlewares.handleParseHeaders(fakeReq, fakeRes,() => {
204+
expect(fakeRes.status).not.toHaveBeenCalled();
205+
done();
206+
});
207+
});
208+
209+
it('should not succeed if the connection.socket.remoteAddress does not belong to masterKeyIps list', () => {
210+
AppCache.put(fakeReq.body._ApplicationId, {
211+
masterKey: 'masterKey',
212+
masterKeyIps: ['ip1','ip2']
213+
});
214+
fakeReq.connection = { socket : {remoteAddress : 'ip3'}};
215+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
216+
middlewares.handleParseHeaders(fakeReq, fakeRes);
217+
expect(fakeRes.status).toHaveBeenCalledWith(403);
218+
});
219+
220+
it('should succeed if the connection.socket.remoteAddress does belong to masterKeyIps list', (done) => {
221+
AppCache.put(fakeReq.body._ApplicationId, {
222+
masterKey: 'masterKey',
223+
masterKeyIps: ['ip1','ip2']
224+
});
225+
fakeReq.connection = { socket : {remoteAddress : 'ip1'}};
226+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
227+
middlewares.handleParseHeaders(fakeReq, fakeRes,() => {
228+
expect(fakeRes.status).not.toHaveBeenCalled();
229+
done();
230+
});
231+
});
232+
233+
it('should allow any ip to use masterKey if masterKeyIps is empty', (done) => {
234+
AppCache.put(fakeReq.body._ApplicationId, {
235+
masterKey: 'masterKey',
236+
masterKeyIps: []
237+
});
238+
fakeReq.ip = 'ip1';
239+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
240+
middlewares.handleParseHeaders(fakeReq, fakeRes,() => {
241+
expect(fakeRes.status).not.toHaveBeenCalled();
242+
done();
243+
});
244+
});
245+
246+
it('should succeed if xff header does belong to masterKeyIps', (done) => {
247+
AppCache.put(fakeReq.body._ApplicationId, {
248+
masterKey: 'masterKey',
249+
masterKeyIps: ['ip1']
250+
});
251+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
252+
fakeReq.headers['x-forwarded-for'] = 'ip1, ip2, ip3';
253+
middlewares.handleParseHeaders(fakeReq, fakeRes,() => {
254+
expect(fakeRes.status).not.toHaveBeenCalled();
255+
done();
256+
});
257+
});
258+
259+
it('should succeed if xff header with one ip does belong to masterKeyIps', (done) => {
260+
AppCache.put(fakeReq.body._ApplicationId, {
261+
masterKey: 'masterKey',
262+
masterKeyIps: ['ip1']
263+
});
264+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
265+
fakeReq.headers['x-forwarded-for'] = 'ip1';
266+
middlewares.handleParseHeaders(fakeReq, fakeRes,() => {
267+
expect(fakeRes.status).not.toHaveBeenCalled();
268+
done();
269+
});
270+
});
271+
272+
it('should not succeed if xff header does not belong to masterKeyIps', () => {
273+
AppCache.put(fakeReq.body._ApplicationId, {
274+
masterKey: 'masterKey',
275+
masterKeyIps: ['ip4']
276+
});
277+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
278+
fakeReq.headers['x-forwarded-for'] = 'ip1, ip2, ip3';
279+
middlewares.handleParseHeaders(fakeReq, fakeRes);
280+
expect(fakeRes.status).toHaveBeenCalledWith(403);
281+
});
282+
283+
it('should not succeed if xff header is empty and masterKeyIps is set', () => {
284+
AppCache.put(fakeReq.body._ApplicationId, {
285+
masterKey: 'masterKey',
286+
masterKeyIps: ['ip1']
287+
});
288+
fakeReq.headers['x-parse-master-key'] = 'masterKey';
289+
fakeReq.headers['x-forwarded-for'] = '';
290+
middlewares.handleParseHeaders(fakeReq, fakeRes);
291+
expect(fakeRes.status).toHaveBeenCalledWith(403);
292+
});
136293
});

spec/ParseQuery.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,21 @@ describe('Parse.Query testing', () => {
274274
});
275275
});
276276

277+
it('containedIn null array', (done) => {
278+
const emails = ['[email protected]', '[email protected]', null];
279+
const user = new Parse.User();
280+
user.setUsername(emails[0]);
281+
user.setPassword('asdf');
282+
user.signUp().then(() => {
283+
const query = new Parse.Query(Parse.User);
284+
query.containedIn('username', emails);
285+
return query.find({ useMasterKey: true });
286+
}).then((results) => {
287+
equal(results.length, 1);
288+
done();
289+
}, done.fail);
290+
});
291+
277292
it("containsAll number array queries", function(done) {
278293
var NumberSet = Parse.Object.extend({ className: "NumberSet" });
279294

spec/ParseUser.spec.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,10 +1185,7 @@ describe('Parse.User testing', () => {
11851185
expect(fileAgain.url()).toMatch(/yolo.txt$/);
11861186
}).then(() => {
11871187
done();
1188-
}, error => {
1189-
jfail(error);
1190-
done();
1191-
});
1188+
}).catch(done.fail);
11921189
});
11931190

11941191
it("log in with provider twice", (done) => {

0 commit comments

Comments
 (0)