Skip to content

Commit 92d51de

Browse files
authored
Fixes issue affecting linking users to a 3rd party auth (#4047)
* Fixes issue affecting linking users to a 3rd party auth * Fixes problematic test * Better fix * nits
1 parent 7e54265 commit 92d51de

File tree

3 files changed

+45
-12
lines changed

3 files changed

+45
-12
lines changed

spec/AuthenticationAdapters.spec.js

+34-5
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/ParseUser.spec.js

+1-4
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) => {

src/RestWrite.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,14 @@ RestWrite.prototype.handleAuthData = function(authData) {
297297
}
298298
});
299299
const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0;
300-
if (!this.query) {
300+
let userId;
301+
if (this.query && this.query.objectId) {
302+
userId = this.query.objectId;
303+
} else if (this.auth && this.auth.user && this.auth.user.id) {
304+
userId = this.auth.user.id;
305+
}
306+
if (!userId || userId === userResult.objectId) { // no user making the call
307+
// OR the user making the call is the right one
301308
// Login with auth data
302309
delete results[0].password;
303310

@@ -328,10 +335,10 @@ RestWrite.prototype.handleAuthData = function(authData) {
328335
// Just update the authData part
329336
return this.config.database.update(this.className, {objectId: this.data.objectId}, {authData: mutatedAuthData}, {});
330337
});
331-
} else if (this.query && this.query.objectId) {
338+
} else if (userId) {
332339
// Trying to update auth data but users
333340
// are different
334-
if (userResult.objectId !== this.query.objectId) {
341+
if (userResult.objectId !== userId) {
335342
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED,
336343
'this auth is already used');
337344
}

0 commit comments

Comments
 (0)