Skip to content

Commit edf5b51

Browse files
authored
Protected fields fix (#5463)
* fix minor spelling mistake * Always process userSensitiveFields if they exist * Cover change to protectedFields Add start of some more tests for protectedFields which i need to do to document the feature. * re-arrange promise deck chairs to not swallow errors. * remove noop code * protect agains the case where options.protectedFields is set without a _User permission.
1 parent 11976b8 commit edf5b51

File tree

3 files changed

+273
-161
lines changed

3 files changed

+273
-161
lines changed

spec/ProtectedFields.spec.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
describe('ProtectedFields', function() {
2+
it('should handle and empty protectedFields', async function() {
3+
const protectedFields = {};
4+
await reconfigureServer({ protectedFields });
5+
6+
const user = new Parse.User();
7+
user.setUsername('Alice');
8+
user.setPassword('sekrit');
9+
user.set('email', 'alice@aol.com');
10+
user.set('favoriteColor', 'yellow');
11+
await user.save();
12+
13+
const fetched = await new Parse.Query(Parse.User).get(user.id);
14+
expect(fetched.has('email')).toBeFalsy();
15+
expect(fetched.has('favoriteColor')).toBeTruthy();
16+
});
17+
18+
describe('interaction with legacy userSensitiveFields', function() {
19+
it('should fall back on sensitive fields if protected fields are not configured', async function() {
20+
const userSensitiveFields = ['phoneNumber', 'timeZone'];
21+
22+
const protectedFields = { _User: { '*': ['email'] } };
23+
24+
await reconfigureServer({ userSensitiveFields, protectedFields });
25+
const user = new Parse.User();
26+
user.setUsername('Alice');
27+
user.setPassword('sekrit');
28+
user.set('email', 'alice@aol.com');
29+
user.set('phoneNumber', 8675309);
30+
user.set('timeZone', 'America/Los_Angeles');
31+
user.set('favoriteColor', 'yellow');
32+
user.set('favoriteFood', 'pizza');
33+
await user.save();
34+
35+
const fetched = await new Parse.Query(Parse.User).get(user.id);
36+
expect(fetched.has('email')).toBeFalsy();
37+
expect(fetched.has('phoneNumber')).toBeFalsy();
38+
expect(fetched.has('favoriteColor')).toBeTruthy();
39+
});
40+
41+
it('should merge protected and sensitive for extra safety', async function() {
42+
const userSensitiveFields = ['phoneNumber', 'timeZone'];
43+
44+
const protectedFields = { _User: { '*': ['email', 'favoriteFood'] } };
45+
46+
await reconfigureServer({ userSensitiveFields, protectedFields });
47+
const user = new Parse.User();
48+
user.setUsername('Alice');
49+
user.setPassword('sekrit');
50+
user.set('email', 'alice@aol.com');
51+
user.set('phoneNumber', 8675309);
52+
user.set('timeZone', 'America/Los_Angeles');
53+
user.set('favoriteColor', 'yellow');
54+
user.set('favoriteFood', 'pizza');
55+
await user.save();
56+
57+
const fetched = await new Parse.Query(Parse.User).get(user.id);
58+
expect(fetched.has('email')).toBeFalsy();
59+
expect(fetched.has('phoneNumber')).toBeFalsy();
60+
expect(fetched.has('favoriteFood')).toBeFalsy();
61+
expect(fetched.has('favoriteColor')).toBeTruthy();
62+
});
63+
});
64+
65+
describe('non user class', function() {
66+
it('should hide fields in a non user class', async function() {
67+
const protectedFields = {
68+
ClassA: { '*': ['foo'] },
69+
ClassB: { '*': ['bar'] },
70+
};
71+
await reconfigureServer({ protectedFields });
72+
73+
const objA = await new Parse.Object('ClassA')
74+
.set('foo', 'zzz')
75+
.set('bar', 'yyy')
76+
.save();
77+
78+
const objB = await new Parse.Object('ClassB')
79+
.set('foo', 'zzz')
80+
.set('bar', 'yyy')
81+
.save();
82+
83+
const [fetchedA, fetchedB] = await Promise.all([
84+
new Parse.Query('ClassA').get(objA.id),
85+
new Parse.Query('ClassB').get(objB.id),
86+
]);
87+
88+
expect(fetchedA.has('foo')).toBeFalsy();
89+
expect(fetchedA.has('bar')).toBeTruthy();
90+
91+
expect(fetchedB.has('foo')).toBeTruthy();
92+
expect(fetchedB.has('bar')).toBeFalsy();
93+
});
94+
95+
it('should hide fields in non user class and non standard user field at same time', async function() {
96+
const protectedFields = {
97+
_User: { '*': ['phoneNumber'] },
98+
ClassA: { '*': ['foo'] },
99+
ClassB: { '*': ['bar'] },
100+
};
101+
102+
await reconfigureServer({ protectedFields });
103+
104+
const user = new Parse.User();
105+
user.setUsername('Alice');
106+
user.setPassword('sekrit');
107+
user.set('email', 'alice@aol.com');
108+
user.set('phoneNumber', 8675309);
109+
user.set('timeZone', 'America/Los_Angeles');
110+
user.set('favoriteColor', 'yellow');
111+
user.set('favoriteFood', 'pizza');
112+
await user.save();
113+
114+
const objA = await new Parse.Object('ClassA')
115+
.set('foo', 'zzz')
116+
.set('bar', 'yyy')
117+
.save();
118+
119+
const objB = await new Parse.Object('ClassB')
120+
.set('foo', 'zzz')
121+
.set('bar', 'yyy')
122+
.save();
123+
124+
const [fetchedUser, fetchedA, fetchedB] = await Promise.all([
125+
new Parse.Query(Parse.User).get(user.id),
126+
new Parse.Query('ClassA').get(objA.id),
127+
new Parse.Query('ClassB').get(objB.id),
128+
]);
129+
130+
expect(fetchedA.has('foo')).toBeFalsy();
131+
expect(fetchedA.has('bar')).toBeTruthy();
132+
133+
expect(fetchedB.has('foo')).toBeTruthy();
134+
expect(fetchedB.has('bar')).toBeFalsy();
135+
136+
expect(fetchedUser.has('email')).toBeFalsy();
137+
expect(fetchedUser.has('phoneNumber')).toBeFalsy();
138+
expect(fetchedUser.has('favoriteColor')).toBeTruthy();
139+
});
140+
});
141+
});

0 commit comments

Comments
 (0)