Skip to content

Commit 4563861

Browse files
committed
Merge remote-tracking branch 'upstream/master' into fixSelectExclude
2 parents ac42142 + 5abbeeb commit 4563861

File tree

7 files changed

+355
-236
lines changed

7 files changed

+355
-236
lines changed

CHANGELOG.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ ___
9595
- Removed [parse-server-simple-mailgun-adapter](https://github.com/parse-community/parse-server-simple-mailgun-adapter) dependency; to continue using the adapter it has to be explicitly installed (Manuel Trezza) [#7321](https://github.com/parse-community/parse-server/pull/7321)
9696
- Remove support for MongoDB 3.6 which has reached its End-of-Life date and PostgreSQL 10 (Manuel Trezza) [#7315](https://github.com/parse-community/parse-server/pull/7315)
9797
- Remove support for Node 10 which has reached its End-of-Life date (Manuel Trezza) [#7314](https://github.com/parse-community/parse-server/pull/7314)
98-
- Remove S3 Files Adapter from Parse Server, instead install separately as `@parse/s3-files-adapter` (Manuel Trezza) [#?](https://github.com/parse-community/parse-server/pull/?)
98+
- Remove S3 Files Adapter from Parse Server, instead install separately as `@parse/s3-files-adapter` (Manuel Trezza) [#7324](https://github.com/parse-community/parse-server/pull/7324)
9999
### Notable Changes
100100
- Added Parse Server Security Check to report weak security settings (Manuel Trezza, dblythy) [#7247](https://github.com/parse-community/parse-server/issues/7247)
101-
- EXPERIMENTAL: Added new page router with placeholder rendering and localization of custom and feature pages such as password reset and email verification (Manuel Trezza) [#6891](https://github.com/parse-community/parse-server/issues/6891)
102-
- EXPERIMENTAL: Added custom routes to easily customize flows for password reset, email verification or build entirely new flows (Manuel Trezza) [#7231](https://github.com/parse-community/parse-server/issues/7231)
101+
- EXPERIMENTAL: Added new page router with placeholder rendering and localization of custom and feature pages such as password reset and email verification (Manuel Trezza) [#7128](https://github.com/parse-community/parse-server/pull/7128)
102+
- EXPERIMENTAL: Added custom routes to easily customize flows for password reset, email verification or build entirely new flows (Manuel Trezza) [#7231](https://github.com/parse-community/parse-server/pull/7231)
103103
- Added Deprecation Policy to govern the introduction of braking changes in a phased pattern that is more predictable for developers (Manuel Trezza) [#7199](https://github.com/parse-community/parse-server/pull/7199)
104104
### Other Changes
105105
- Fix error when a not yet inserted job is updated (Antonio Davi Macedo Coelho de Castro) [#7196](https://github.com/parse-community/parse-server/pull/7196)

package-lock.json

Lines changed: 212 additions & 213 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@
2525
"@graphql-tools/utils": "6.2.4",
2626
"@parse/fs-files-adapter": "1.2.0",
2727
"@parse/push-adapter": "3.4.0",
28-
"apollo-server-express": "2.22.2",
28+
"apollo-server-express": "2.24.0",
2929
"bcryptjs": "2.4.3",
3030
"body-parser": "1.19.0",
3131
"commander": "5.1.0",
3232
"cors": "2.8.5",
3333
"deepcopy": "2.1.0",
3434
"express": "4.17.1",
35-
"follow-redirects": "1.13.3",
35+
"follow-redirects": "1.14.1",
3636
"graphql": "15.5.0",
3737
"graphql-list-fields": "2.0.2",
3838
"graphql-relay": "0.6.0",
39-
"graphql-tag": "2.12.2",
39+
"graphql-tag": "2.12.4",
4040
"graphql-upload": "11.0.0",
4141
"intersect": "1.0.1",
4242
"jsonwebtoken": "8.5.1",
@@ -47,18 +47,18 @@
4747
"mime": "2.5.2",
4848
"mongodb": "3.6.6",
4949
"mustache": "4.2.0",
50-
"parse": "3.1.0",
50+
"parse": "3.2.0",
5151
"pg-monitor": "1.4.1",
52-
"pg-promise": "10.10.1",
52+
"pg-promise": "10.10.2",
5353
"pluralize": "8.0.0",
54-
"redis": "3.1.1",
54+
"redis": "3.1.2",
5555
"semver": "7.3.4",
5656
"subscriptions-transport-ws": "0.9.18",
5757
"tv4": "1.3.0",
5858
"uuid": "8.3.2",
5959
"winston": "3.3.3",
60-
"winston-daily-rotate-file": "4.5.2",
61-
"ws": "7.4.4"
60+
"winston-daily-rotate-file": "4.5.5",
61+
"ws": "7.4.6"
6262
},
6363
"devDependencies": {
6464
"@actions/core": "1.2.6",

spec/ParseAPI.spec.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,28 @@ describe('miscellaneous', function () {
646646
});
647647
});
648648

649+
it_only_db('mongo')('pointer reassign on nested fields is working properly (#7391)', async () => {
650+
const obj = new Parse.Object('GameScore'); // This object will include nested pointers
651+
const ptr1 = new Parse.Object('GameScore');
652+
await ptr1.save(); // Obtain a unique id
653+
const ptr2 = new Parse.Object('GameScore');
654+
await ptr2.save(); // Obtain a unique id
655+
obj.set('data', { ptr: ptr1 });
656+
await obj.save();
657+
658+
obj.set('data.ptr', ptr2);
659+
await obj.save();
660+
661+
const obj2 = await new Parse.Query('GameScore').get(obj.id);
662+
expect(obj2.get('data').ptr.id).toBe(ptr2.id);
663+
664+
const query = new Parse.Query('GameScore');
665+
query.equalTo('data.ptr', ptr2);
666+
const res = await query.find();
667+
expect(res.length).toBe(1);
668+
expect(res[0].get('data').ptr.id).toBe(ptr2.id);
669+
});
670+
649671
it('test afterSave get full object on create and update', function (done) {
650672
let triggerTime = 0;
651673
// Register a mock beforeSave hook

spec/ParseLiveQuery.spec.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,69 @@ describe('ParseLiveQuery', function () {
645645
await object.save();
646646
});
647647

648+
it('LiveQuery with ACL', async () => {
649+
await reconfigureServer({
650+
liveQuery: {
651+
classNames: ['Chat'],
652+
},
653+
startLiveQueryServer: true,
654+
verbose: false,
655+
silent: true,
656+
});
657+
const user = new Parse.User();
658+
user.setUsername('username');
659+
user.setPassword('password');
660+
await user.signUp();
661+
662+
const calls = {
663+
beforeConnect(req) {
664+
expect(req.event).toBe('connect');
665+
expect(req.clients).toBe(0);
666+
expect(req.subscriptions).toBe(0);
667+
expect(req.useMasterKey).toBe(false);
668+
expect(req.installationId).toBeDefined();
669+
expect(req.client).toBeDefined();
670+
},
671+
beforeSubscribe(req) {
672+
expect(req.op).toBe('subscribe');
673+
expect(req.requestId).toBe(1);
674+
expect(req.query).toBeDefined();
675+
expect(req.user).toBeDefined();
676+
},
677+
afterLiveQueryEvent(req) {
678+
expect(req.user).toBeDefined();
679+
expect(req.object.get('foo')).toBe('bar');
680+
},
681+
create(object) {
682+
expect(object.get('foo')).toBe('bar');
683+
},
684+
delete(object) {
685+
expect(object.get('foo')).toBe('bar');
686+
},
687+
};
688+
for (const key in calls) {
689+
spyOn(calls, key).and.callThrough();
690+
}
691+
Parse.Cloud.beforeConnect(calls.beforeConnect);
692+
Parse.Cloud.beforeSubscribe('Chat', calls.beforeSubscribe);
693+
Parse.Cloud.afterLiveQueryEvent('Chat', calls.afterLiveQueryEvent);
694+
695+
const chatQuery = new Parse.Query('Chat');
696+
const subscription = await chatQuery.subscribe();
697+
subscription.on('create', calls.create);
698+
subscription.on('delete', calls.delete);
699+
const object = new Parse.Object('Chat');
700+
const acl = new Parse.ACL(user);
701+
object.setACL(acl);
702+
object.set({ foo: 'bar' });
703+
await object.save();
704+
await object.destroy();
705+
await new Promise(resolve => setTimeout(resolve, 200));
706+
for (const key in calls) {
707+
expect(calls[key]).toHaveBeenCalled();
708+
}
709+
});
710+
648711
it('handle invalid websocket payload length', async done => {
649712
await reconfigureServer({
650713
liveQuery: {

src/Adapters/Storage/Mongo/MongoTransform.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,10 @@ const transformKeyValueForUpdate = (className, restKey, restValue, parseFormatSc
9999

100100
if (
101101
(parseFormatSchema.fields[key] && parseFormatSchema.fields[key].type === 'Pointer') ||
102-
(!parseFormatSchema.fields[key] && restValue && restValue.__type == 'Pointer')
102+
(!key.includes('.') &&
103+
!parseFormatSchema.fields[key] &&
104+
restValue &&
105+
restValue.__type == 'Pointer') // Do not use the _p_ prefix for pointers inside nested documents
103106
) {
104107
key = '_p_' + key;
105108
}
@@ -305,7 +308,10 @@ function transformQueryKeyValue(className, key, value, schema, count = false) {
305308
schema && schema.fields[key] && schema.fields[key].type === 'Pointer';
306309

307310
const field = schema && schema.fields[key];
308-
if (expectedTypeIsPointer || (!schema && value && value.__type === 'Pointer')) {
311+
if (
312+
expectedTypeIsPointer ||
313+
(!schema && !key.includes('.') && value && value.__type === 'Pointer')
314+
) {
309315
key = '_p_' + key;
310316
}
311317

@@ -326,8 +332,11 @@ function transformQueryKeyValue(className, key, value, schema, count = false) {
326332
}
327333

328334
// Handle atomic values
329-
if (transformTopLevelAtom(value) !== CannotTransform) {
330-
return { key, value: transformTopLevelAtom(value) };
335+
const transformRes = key.includes('.')
336+
? transformInteriorAtom(value)
337+
: transformTopLevelAtom(value);
338+
if (transformRes !== CannotTransform) {
339+
return { key, value: transformRes };
331340
} else {
332341
throw new Parse.Error(
333342
Parse.Error.INVALID_JSON,

src/LiveQuery/ParseLiveQueryServer.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,10 @@ class ParseLiveQueryServer {
170170
};
171171
const trigger = getTrigger(className, 'afterEvent', Parse.applicationId);
172172
if (trigger) {
173-
const auth = await this.getAuthForSessionToken(res.sessionToken);
174-
res.user = auth.user;
173+
const auth = await this.getAuthFromClient(client, requestId);
174+
if (auth && auth.user) {
175+
res.user = auth.user;
176+
}
175177
if (res.object) {
176178
res.object = Parse.Object.fromJSON(res.object);
177179
}
@@ -317,8 +319,10 @@ class ParseLiveQueryServer {
317319
if (res.original) {
318320
res.original = Parse.Object.fromJSON(res.original);
319321
}
320-
const auth = await this.getAuthForSessionToken(res.sessionToken);
321-
res.user = auth.user;
322+
const auth = await this.getAuthFromClient(client, requestId);
323+
if (auth && auth.user) {
324+
res.user = auth.user;
325+
}
322326
await runTrigger(trigger, `afterEvent.${className}`, res, auth);
323327
}
324328
if (!res.sendEvent) {
@@ -579,6 +583,24 @@ class ParseLiveQueryServer {
579583
});
580584
}
581585

586+
async getAuthFromClient(client: any, requestId: number, sessionToken: string) {
587+
const getSessionFromClient = () => {
588+
const subscriptionInfo = client.getSubscriptionInfo(requestId);
589+
if (typeof subscriptionInfo === 'undefined') {
590+
return client.sessionToken;
591+
}
592+
return subscriptionInfo.sessionToken || client.sessionToken;
593+
};
594+
if (!sessionToken) {
595+
sessionToken = getSessionFromClient();
596+
}
597+
if (!sessionToken) {
598+
return;
599+
}
600+
const { auth } = await this.getAuthForSessionToken(sessionToken);
601+
return auth;
602+
}
603+
582604
async _matchesACL(acl: any, client: any, requestId: number): Promise<boolean> {
583605
// Return true directly if ACL isn't present, ACL is public read, or client has master key
584606
if (!acl || acl.getPublicReadAccess() || client.hasMasterKey) {
@@ -631,8 +653,10 @@ class ParseLiveQueryServer {
631653
};
632654
const trigger = getTrigger('@Connect', 'beforeConnect', Parse.applicationId);
633655
if (trigger) {
634-
const auth = await this.getAuthForSessionToken(req.sessionToken);
635-
req.user = auth.user;
656+
const auth = await this.getAuthFromClient(client, request.requestId, req.sessionToken);
657+
if (auth && auth.user) {
658+
req.user = auth.user;
659+
}
636660
await runTrigger(trigger, `beforeConnect.@Connect`, req, auth);
637661
}
638662
parseWebsocket.clientId = clientId;
@@ -690,8 +714,10 @@ class ParseLiveQueryServer {
690714
try {
691715
const trigger = getTrigger(className, 'beforeSubscribe', Parse.applicationId);
692716
if (trigger) {
693-
const auth = await this.getAuthForSessionToken(request.sessionToken);
694-
request.user = auth.user;
717+
const auth = await this.getAuthFromClient(client, request.requestId, request.sessionToken);
718+
if (auth && auth.user) {
719+
request.user = auth.user;
720+
}
695721

696722
const parseQuery = new Parse.Query(className);
697723
parseQuery.withJSON(request.query);

0 commit comments

Comments
 (0)