Skip to content

Commit ff53d39

Browse files
authored
Merge branch 'alpha' into login-context
2 parents 15873e9 + 0593985 commit ff53d39

17 files changed

+543
-238
lines changed

changelogs/CHANGELOG_alpha.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# [6.3.0-alpha.9](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.8...6.3.0-alpha.9) (2023-09-13)
2+
3+
4+
### Performance Improvements
5+
6+
* Improve performance of recursive pointer iterations ([#8741](https://github.com/parse-community/parse-server/issues/8741)) ([45a3ed0](https://github.com/parse-community/parse-server/commit/45a3ed0fcf2c0170607505a1550fb15896e705fd))
7+
18
# [6.3.0-alpha.8](https://github.com/parse-community/parse-server/compare/6.3.0-alpha.7...6.3.0-alpha.8) (2023-08-30)
29

310

changelogs/CHANGELOG_beta.md

+20
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
# [6.4.0-beta.1](https://github.com/parse-community/parse-server/compare/6.3.0...6.4.0-beta.1) (2023-09-16)
2+
3+
4+
### Bug Fixes
5+
6+
* Parse Server option `fileUpload.fileExtensions` does not work with an array of extensions ([#8688](https://github.com/parse-community/parse-server/issues/8688)) ([6a4a00c](https://github.com/parse-community/parse-server/commit/6a4a00ca7af1163ea74b047b85cd6817366b824b))
7+
* Redis 4 does not reconnect after unhandled error ([#8706](https://github.com/parse-community/parse-server/issues/8706)) ([2b3d4e5](https://github.com/parse-community/parse-server/commit/2b3d4e5d3c85cd142f85af68dec51a8523548d49))
8+
* Remove config logging when launching Parse Server via CLI ([#8710](https://github.com/parse-community/parse-server/issues/8710)) ([ae68f0c](https://github.com/parse-community/parse-server/commit/ae68f0c31b741eeb83379c905c7ddfaa124436ec))
9+
* Server does not start via CLI when `auth` option is set ([#8666](https://github.com/parse-community/parse-server/issues/8666)) ([4e2000b](https://github.com/parse-community/parse-server/commit/4e2000bc563324389584ace3c090a5c1a7796a64))
10+
11+
### Features
12+
13+
* Add conditional email verification via dynamic Parse Server options `verifyUserEmails`, `sendUserEmailVerification` that now accept functions ([#8425](https://github.com/parse-community/parse-server/issues/8425)) ([44acd6d](https://github.com/parse-community/parse-server/commit/44acd6d9ed157ad4842200c9d01f9c77a05fec3a))
14+
* Add property `Parse.Server.version` to determine current version of Parse Server in Cloud Code ([#8670](https://github.com/parse-community/parse-server/issues/8670)) ([a9d376b](https://github.com/parse-community/parse-server/commit/a9d376b61f5b07806eafbda91c4e36c322f09298))
15+
* Add TOTP authentication adapter ([#8457](https://github.com/parse-community/parse-server/issues/8457)) ([cc079a4](https://github.com/parse-community/parse-server/commit/cc079a40f6849a0e9bc6fdc811e8649ecb67b589))
16+
17+
### Performance Improvements
18+
19+
* Improve performance of recursive pointer iterations ([#8741](https://github.com/parse-community/parse-server/issues/8741)) ([45a3ed0](https://github.com/parse-community/parse-server/commit/45a3ed0fcf2c0170607505a1550fb15896e705fd))
20+
121
# [6.3.0-beta.1](https://github.com/parse-community/parse-server/compare/6.2.0...6.3.0-beta.1) (2023-06-10)
222

323

changelogs/CHANGELOG_release.md

+39
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,42 @@
1+
# [6.3.0](https://github.com/parse-community/parse-server/compare/6.2.2...6.3.0) (2023-09-16)
2+
3+
4+
### Bug Fixes
5+
6+
* Cloud Code Trigger `afterSave` executes even if not set ([#8520](https://github.com/parse-community/parse-server/issues/8520)) ([afd0515](https://github.com/parse-community/parse-server/commit/afd0515e207bd947840579d3f245980dffa6f804))
7+
* GridFS file storage doesn't work with certain `enableSchemaHooks` settings ([#8467](https://github.com/parse-community/parse-server/issues/8467)) ([d4cda4b](https://github.com/parse-community/parse-server/commit/d4cda4b26c9bde8c812549b8780bea1cfabdb394))
8+
* Inaccurate table total row count for PostgreSQL ([#8511](https://github.com/parse-community/parse-server/issues/8511)) ([0823a02](https://github.com/parse-community/parse-server/commit/0823a02fbf80bc88dc403bc47e9f5c6597ea78b4))
9+
* LiveQuery server is not shut down properly when `handleShutdown` is called ([#8491](https://github.com/parse-community/parse-server/issues/8491)) ([967700b](https://github.com/parse-community/parse-server/commit/967700bdbc94c74f75ba84d2b3f4b9f3fd2dca0b))
10+
* Rate limit feature is incompatible with Node 14 ([#8578](https://github.com/parse-community/parse-server/issues/8578)) ([f911f2c](https://github.com/parse-community/parse-server/commit/f911f2cd3a8c45cd326272dcd681532764a3761e))
11+
* Unnecessary log entries by `extendSessionOnUse` ([#8562](https://github.com/parse-community/parse-server/issues/8562)) ([fd6a007](https://github.com/parse-community/parse-server/commit/fd6a0077f2e5cf83d65e52172ae5a950ab0f1eae))
12+
13+
### Features
14+
15+
* `extendSessionOnUse` to automatically renew Parse Sessions ([#8505](https://github.com/parse-community/parse-server/issues/8505)) ([6f885d3](https://github.com/parse-community/parse-server/commit/6f885d36b94902fdfea873fc554dee83589e6029))
16+
* Add new Parse Server option `preventSignupWithUnverifiedEmail` to prevent returning a user without session token on sign-up with unverified email address ([#8451](https://github.com/parse-community/parse-server/issues/8451)) ([82da308](https://github.com/parse-community/parse-server/commit/82da30842a55980aa90cb7680fbf6db37ee16dab))
17+
* Add option to change the log level of logs emitted by Cloud Functions ([#8530](https://github.com/parse-community/parse-server/issues/8530)) ([2caea31](https://github.com/parse-community/parse-server/commit/2caea310be412d82b04a85716bc769ccc410316d))
18+
* Add support for `$eq` query constraint in LiveQuery ([#8614](https://github.com/parse-community/parse-server/issues/8614)) ([656d673](https://github.com/parse-community/parse-server/commit/656d673cf5dea354e4f2b3d4dc2b29a41d311b3e))
19+
* Add zones for rate limiting by `ip`, `user`, `session`, `global` ([#8508](https://github.com/parse-community/parse-server/issues/8508)) ([03fba97](https://github.com/parse-community/parse-server/commit/03fba97e0549bfcaeee9f2fa4c9905dbcc91840e))
20+
* Allow `Parse.Object` pointers in Cloud Code arguments ([#8490](https://github.com/parse-community/parse-server/issues/8490)) ([28aeda3](https://github.com/parse-community/parse-server/commit/28aeda3f160efcbbcf85a85484a8d26567fa9761))
21+
22+
### Reverts
23+
24+
* fix: Inaccurate table total row count for PostgreSQL ([6722110](https://github.com/parse-community/parse-server/commit/6722110f203bc5fdcaa68cdf091cf9e7b48d1cff))
25+
26+
## [6.2.2](https://github.com/parse-community/parse-server/compare/6.2.1...6.2.2) (2023-09-04)
27+
28+
29+
### Bug Fixes
30+
31+
* Parse Pointer allows to access internal Parse Server classes and circumvent `beforeFind` query trigger; fixes security vulnerability [GHSA-fcv6-fg5r-jm9q](https://github.com/parse-community/parse-server/security/advisories/GHSA-fcv6-fg5r-jm9q) ([be4c7e2](https://github.com/parse-community/parse-server/commit/be4c7e23c63a2fb690685665cebed0de26be05c5))
32+
33+
## [6.2.1](https://github.com/parse-community/parse-server/compare/6.2.0...6.2.1) (2023-06-28)
34+
35+
36+
### Bug Fixes
37+
38+
* Remote code execution via MongoDB BSON parser through prototype pollution; fixes security vulnerability [GHSA-462x-c3jw-7vr6](https://github.com/parse-community/parse-server/security/advisories/GHSA-462x-c3jw-7vr6) ([#8674](https://github.com/parse-community/parse-server/issues/8674)) ([3dd99dd](https://github.com/parse-community/parse-server/commit/3dd99dd80e27e5e1d99b42844180546d90c7aa90))
39+
140
# [6.2.0](https://github.com/parse-community/parse-server/compare/6.1.0...6.2.0) (2023-05-20)
241

342

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "parse-server",
3-
"version": "6.3.0-alpha.8",
3+
"version": "6.4.0-beta.1",
44
"description": "An express module providing a Parse-compatible API server",
55
"main": "lib/index.js",
66
"repository": {

spec/CloudCode.spec.js

+79
Original file line numberDiff line numberDiff line change
@@ -2398,6 +2398,56 @@ describe('beforeFind hooks', () => {
23982398
});
23992399
});
24002400

2401+
it('sets correct beforeFind trigger isGet parameter for Parse.Object.fetch request', async () => {
2402+
const hook = {
2403+
method: req => {
2404+
expect(req.isGet).toEqual(true);
2405+
return Promise.resolve();
2406+
},
2407+
};
2408+
spyOn(hook, 'method').and.callThrough();
2409+
Parse.Cloud.beforeFind('MyObject', hook.method);
2410+
const obj = new Parse.Object('MyObject');
2411+
await obj.save();
2412+
const getObj = await obj.fetch();
2413+
expect(getObj).toBeInstanceOf(Parse.Object);
2414+
expect(hook.method).toHaveBeenCalledTimes(1);
2415+
});
2416+
2417+
it('sets correct beforeFind trigger isGet parameter for Parse.Query.get request', async () => {
2418+
const hook = {
2419+
method: req => {
2420+
expect(req.isGet).toEqual(false);
2421+
return Promise.resolve();
2422+
},
2423+
};
2424+
spyOn(hook, 'method').and.callThrough();
2425+
Parse.Cloud.beforeFind('MyObject', hook.method);
2426+
const obj = new Parse.Object('MyObject');
2427+
await obj.save();
2428+
const query = new Parse.Query('MyObject');
2429+
const getObj = await query.get(obj.id);
2430+
expect(getObj).toBeInstanceOf(Parse.Object);
2431+
expect(hook.method).toHaveBeenCalledTimes(1);
2432+
});
2433+
2434+
it('sets correct beforeFind trigger isGet parameter for Parse.Query.find request', async () => {
2435+
const hook = {
2436+
method: req => {
2437+
expect(req.isGet).toEqual(false);
2438+
return Promise.resolve();
2439+
},
2440+
};
2441+
spyOn(hook, 'method').and.callThrough();
2442+
Parse.Cloud.beforeFind('MyObject', hook.method);
2443+
const obj = new Parse.Object('MyObject');
2444+
await obj.save();
2445+
const query = new Parse.Query('MyObject');
2446+
const findObjs = await query.find();
2447+
expect(findObjs?.[0]).toBeInstanceOf(Parse.Object);
2448+
expect(hook.method).toHaveBeenCalledTimes(1);
2449+
});
2450+
24012451
it('should have request headers', done => {
24022452
Parse.Cloud.beforeFind('MyObject', req => {
24032453
expect(req.headers).toBeDefined();
@@ -2431,6 +2481,35 @@ describe('beforeFind hooks', () => {
24312481
})
24322482
.then(() => done());
24332483
});
2484+
2485+
it('should run beforeFind on pointers and array of pointers from an object', async () => {
2486+
const obj1 = new Parse.Object('TestObject');
2487+
const obj2 = new Parse.Object('TestObject2');
2488+
const obj3 = new Parse.Object('TestObject');
2489+
obj2.set('aField', 'aFieldValue');
2490+
await obj2.save();
2491+
obj1.set('pointerField', obj2);
2492+
obj3.set('pointerFieldArray', [obj2]);
2493+
await obj1.save();
2494+
await obj3.save();
2495+
const spy = jasmine.createSpy('beforeFindSpy');
2496+
Parse.Cloud.beforeFind('TestObject2', spy);
2497+
const query = new Parse.Query('TestObject');
2498+
await query.get(obj1.id);
2499+
// Pointer not included in query so we don't expect beforeFind to be called
2500+
expect(spy).not.toHaveBeenCalled();
2501+
const query2 = new Parse.Query('TestObject');
2502+
query2.include('pointerField');
2503+
const res = await query2.get(obj1.id);
2504+
expect(res.get('pointerField').get('aField')).toBe('aFieldValue');
2505+
// Pointer included in query so we expect beforeFind to be called
2506+
expect(spy).toHaveBeenCalledTimes(1);
2507+
const query3 = new Parse.Query('TestObject');
2508+
query3.include('pointerFieldArray');
2509+
const res2 = await query3.get(obj3.id);
2510+
expect(res2.get('pointerFieldArray')[0].get('aField')).toBe('aFieldValue');
2511+
expect(spy).toHaveBeenCalledTimes(2);
2512+
});
24342513
});
24352514

24362515
describe('afterFind hooks', () => {

spec/ParseGraphQLServer.spec.js

-1
Original file line numberDiff line numberDiff line change
@@ -5275,7 +5275,6 @@ describe('ParseGraphQLServer', () => {
52755275

52765276
it('should only count', async () => {
52775277
await prepareData();
5278-
52795278
await parseGraphQLServer.parseGraphQLSchema.schemaCache.clear();
52805279

52815280
const where = {

spec/ParseRole.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ describe('Parse Role testing', () => {
142142
return Promise.all(promises);
143143
};
144144

145-
const restExecute = spyOn(RestQuery.prototype, 'execute').and.callThrough();
145+
const restExecute = spyOn(RestQuery._UnsafeRestQuery.prototype, 'execute').and.callThrough();
146146

147147
let user, auth, getAllRolesSpy;
148148
createTestUser()

spec/RestQuery.spec.js

+24-20
Original file line numberDiff line numberDiff line change
@@ -399,15 +399,16 @@ describe('RestQuery.each', () => {
399399
}
400400
const config = Config.get('test');
401401
await Parse.Object.saveAll(objects);
402-
const query = new RestQuery(
402+
const query = await RestQuery({
403+
method: RestQuery.Method.find,
403404
config,
404-
auth.master(config),
405-
'Object',
406-
{ value: { $gt: 2 } },
407-
{ limit: 2 }
408-
);
405+
auth: auth.master(config),
406+
className: 'Object',
407+
restWhere: { value: { $gt: 2 } },
408+
restOptions: { limit: 2 },
409+
});
409410
const spy = spyOn(query, 'execute').and.callThrough();
410-
const classSpy = spyOn(RestQuery.prototype, 'execute').and.callThrough();
411+
const classSpy = spyOn(RestQuery._UnsafeRestQuery.prototype, 'execute').and.callThrough();
411412
const results = [];
412413
await query.each(result => {
413414
expect(result.value).toBeGreaterThan(2);
@@ -438,34 +439,37 @@ describe('RestQuery.each', () => {
438439
* Two queries needed since objectId are sorted and we can't know which one
439440
* going to be the first and then skip by the $gt added by each
440441
*/
441-
const queryOne = new RestQuery(
442+
const queryOne = await RestQuery({
443+
method: RestQuery.Method.get,
442444
config,
443-
auth.master(config),
444-
'Letter',
445-
{
445+
auth: auth.master(config),
446+
className: 'Letter',
447+
restWhere: {
446448
numbers: {
447449
__type: 'Pointer',
448450
className: 'Number',
449451
objectId: object1.id,
450452
},
451453
},
452-
{ limit: 1 }
453-
);
454-
const queryTwo = new RestQuery(
454+
restOptions: { limit: 1 },
455+
});
456+
457+
const queryTwo = await RestQuery({
458+
method: RestQuery.Method.get,
455459
config,
456-
auth.master(config),
457-
'Letter',
458-
{
460+
auth: auth.master(config),
461+
className: 'Letter',
462+
restWhere: {
459463
numbers: {
460464
__type: 'Pointer',
461465
className: 'Number',
462466
objectId: object2.id,
463467
},
464468
},
465-
{ limit: 1 }
466-
);
469+
restOptions: { limit: 1 },
470+
});
467471

468-
const classSpy = spyOn(RestQuery.prototype, 'execute').and.callThrough();
472+
const classSpy = spyOn(RestQuery._UnsafeRestQuery.prototype, 'execute').and.callThrough();
469473
const resultsOne = [];
470474
const resultsTwo = [];
471475
await queryOne.each(result => {

spec/rest.spec.js

+32
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,38 @@ describe('rest create', () => {
660660
});
661661
});
662662

663+
it('cannot get object in volatileClasses if not masterKey through pointer', async () => {
664+
const masterKeyOnlyClassObject = new Parse.Object('_PushStatus');
665+
await masterKeyOnlyClassObject.save(null, { useMasterKey: true });
666+
const obj2 = new Parse.Object('TestObject');
667+
// Anyone is can basically create a pointer to any object
668+
// or some developers can use master key in some hook to link
669+
// private objects to standard objects
670+
obj2.set('pointer', masterKeyOnlyClassObject);
671+
await obj2.save();
672+
const query = new Parse.Query('TestObject');
673+
query.include('pointer');
674+
await expectAsync(query.get(obj2.id)).toBeRejectedWithError(
675+
"Clients aren't allowed to perform the get operation on the _PushStatus collection."
676+
);
677+
});
678+
679+
it('cannot get object in _GlobalConfig if not masterKey through pointer', async () => {
680+
await Parse.Config.save({ privateData: 'secret' }, { privateData: true });
681+
const obj2 = new Parse.Object('TestObject');
682+
obj2.set('globalConfigPointer', {
683+
__type: 'Pointer',
684+
className: '_GlobalConfig',
685+
objectId: 1,
686+
});
687+
await obj2.save();
688+
const query = new Parse.Query('TestObject');
689+
query.include('globalConfigPointer');
690+
await expectAsync(query.get(obj2.id)).toBeRejectedWithError(
691+
"Clients aren't allowed to perform the get operation on the _GlobalConfig collection."
692+
);
693+
});
694+
663695
it('locks down session', done => {
664696
let currentUser;
665697
Parse.User.signUp('foo', 'bar')

0 commit comments

Comments
 (0)