Skip to content

Commit 57efd89

Browse files
authored
fix(AuthAdapters): Do not revalidate auth data if hasn't changed (#3867) (#3872)
* Adds test for #3867 * Always Skip authData validation when nothing is mutated
1 parent 38a525b commit 57efd89

File tree

2 files changed

+68
-11
lines changed

2 files changed

+68
-11
lines changed

spec/ParseUser.spec.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,57 @@ describe('Parse.User testing', () => {
17301730
});
17311731
});
17321732

1733+
it('should allow PUT request with stale auth Data', (done) => {
1734+
const provider = {
1735+
authData: {
1736+
id: '12345',
1737+
access_token: 'token'
1738+
},
1739+
restoreAuthentication: function() {
1740+
return true;
1741+
},
1742+
deauthenticate: function() {
1743+
provider.authData = {};
1744+
},
1745+
authenticate: function(options) {
1746+
options.success(this, provider.authData);
1747+
},
1748+
getAuthType: function() {
1749+
return "shortLivedAuth";
1750+
}
1751+
}
1752+
defaultConfiguration.auth.shortLivedAuth.setValidAccessToken('token');
1753+
Parse.User._registerAuthenticationProvider(provider);
1754+
Parse.User._logInWith("shortLivedAuth", {}).then(() => {
1755+
// Simulate a remotely expired token (like a short lived one)
1756+
// In this case, we want success as it was valid once.
1757+
// If the client needs an updated one, do lock the user out
1758+
defaultConfiguration.auth.shortLivedAuth.setValidAccessToken('otherToken');
1759+
return rp.put({
1760+
url: Parse.serverURL + '/users/' + Parse.User.current().id,
1761+
headers: {
1762+
'X-Parse-Application-Id': Parse.applicationId,
1763+
'X-Parse-Javascript-Key': Parse.javaScriptKey,
1764+
'X-Parse-Session-Token': Parse.User.current().getSessionToken(),
1765+
'Content-Type': 'application/json'
1766+
},
1767+
json: {
1768+
key: 'value', // update a key
1769+
authData: { // pass the original auth data
1770+
shortLivedAuth: {
1771+
id: '12345',
1772+
access_token: 'token'
1773+
}
1774+
}
1775+
}
1776+
})
1777+
}).then(() => {
1778+
done();
1779+
}, (err) => {
1780+
done.fail(err);
1781+
});
1782+
});
1783+
17331784
it('should properly error when password is missing', (done) => {
17341785
var provider = getMockFacebookProvider();
17351786
Parse.User._registerAuthenticationProvider(provider);

src/RestWrite.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,30 +288,32 @@ RestWrite.prototype.handleAuthData = function(authData) {
288288
this.storage['authProvider'] = Object.keys(authData).join(',');
289289

290290
if (results.length > 0) {
291+
const userResult = results[0];
292+
const mutatedAuthData = {};
293+
Object.keys(authData).forEach((provider) => {
294+
const providerData = authData[provider];
295+
const userAuthData = userResult.authData[provider];
296+
if (!_.isEqual(providerData, userAuthData)) {
297+
mutatedAuthData[provider] = providerData;
298+
}
299+
});
300+
const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0;
291301
if (!this.query) {
292302
// Login with auth data
293303
delete results[0].password;
294-
const userResult = results[0];
295304

296305
// need to set the objectId first otherwise location has trailing undefined
297306
this.data.objectId = userResult.objectId;
298307

299308
// Determine if authData was updated
300-
const mutatedAuthData = {};
301-
Object.keys(authData).forEach((provider) => {
302-
const providerData = authData[provider];
303-
const userAuthData = userResult.authData[provider];
304-
if (!_.isEqual(providerData, userAuthData)) {
305-
mutatedAuthData[provider] = providerData;
306-
}
307-
});
309+
308310
this.response = {
309311
response: userResult,
310312
location: this.location()
311313
};
312314

313315
// If we didn't change the auth data, just keep going
314-
if (Object.keys(mutatedAuthData).length === 0) {
316+
if (!hasMutatedAuthData) {
315317
return;
316318
}
317319
// We have authData that is updated on login
@@ -330,10 +332,14 @@ RestWrite.prototype.handleAuthData = function(authData) {
330332
} else if (this.query && this.query.objectId) {
331333
// Trying to update auth data but users
332334
// are different
333-
if (results[0].objectId !== this.query.objectId) {
335+
if (userResult.objectId !== this.query.objectId) {
334336
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED,
335337
'this auth is already used');
336338
}
339+
// No auth data was mutated, just keep going
340+
if (!hasMutatedAuthData) {
341+
return;
342+
}
337343
}
338344
}
339345
return this.handleAuthDataValidation(authData);

0 commit comments

Comments
 (0)