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
This commit is contained in:
Florent Vilmart
2017-05-28 17:50:16 -04:00
committed by GitHub
parent 38a525ba5f
commit 57efd89b3d
2 changed files with 68 additions and 11 deletions

View File

@@ -1730,6 +1730,57 @@ describe('Parse.User testing', () => {
}); });
}); });
it('should allow PUT request with stale auth Data', (done) => {
const provider = {
authData: {
id: '12345',
access_token: 'token'
},
restoreAuthentication: function() {
return true;
},
deauthenticate: function() {
provider.authData = {};
},
authenticate: function(options) {
options.success(this, provider.authData);
},
getAuthType: function() {
return "shortLivedAuth";
}
}
defaultConfiguration.auth.shortLivedAuth.setValidAccessToken('token');
Parse.User._registerAuthenticationProvider(provider);
Parse.User._logInWith("shortLivedAuth", {}).then(() => {
// Simulate a remotely expired token (like a short lived one)
// In this case, we want success as it was valid once.
// If the client needs an updated one, do lock the user out
defaultConfiguration.auth.shortLivedAuth.setValidAccessToken('otherToken');
return rp.put({
url: Parse.serverURL + '/users/' + Parse.User.current().id,
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Javascript-Key': Parse.javaScriptKey,
'X-Parse-Session-Token': Parse.User.current().getSessionToken(),
'Content-Type': 'application/json'
},
json: {
key: 'value', // update a key
authData: { // pass the original auth data
shortLivedAuth: {
id: '12345',
access_token: 'token'
}
}
}
})
}).then(() => {
done();
}, (err) => {
done.fail(err);
});
});
it('should properly error when password is missing', (done) => { it('should properly error when password is missing', (done) => {
var provider = getMockFacebookProvider(); var provider = getMockFacebookProvider();
Parse.User._registerAuthenticationProvider(provider); Parse.User._registerAuthenticationProvider(provider);

View File

@@ -288,30 +288,32 @@ RestWrite.prototype.handleAuthData = function(authData) {
this.storage['authProvider'] = Object.keys(authData).join(','); this.storage['authProvider'] = Object.keys(authData).join(',');
if (results.length > 0) { if (results.length > 0) {
const userResult = results[0];
const mutatedAuthData = {};
Object.keys(authData).forEach((provider) => {
const providerData = authData[provider];
const userAuthData = userResult.authData[provider];
if (!_.isEqual(providerData, userAuthData)) {
mutatedAuthData[provider] = providerData;
}
});
const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0;
if (!this.query) { if (!this.query) {
// Login with auth data // Login with auth data
delete results[0].password; delete results[0].password;
const userResult = results[0];
// need to set the objectId first otherwise location has trailing undefined // need to set the objectId first otherwise location has trailing undefined
this.data.objectId = userResult.objectId; this.data.objectId = userResult.objectId;
// Determine if authData was updated // Determine if authData was updated
const mutatedAuthData = {};
Object.keys(authData).forEach((provider) => {
const providerData = authData[provider];
const userAuthData = userResult.authData[provider];
if (!_.isEqual(providerData, userAuthData)) {
mutatedAuthData[provider] = providerData;
}
});
this.response = { this.response = {
response: userResult, response: userResult,
location: this.location() location: this.location()
}; };
// If we didn't change the auth data, just keep going // If we didn't change the auth data, just keep going
if (Object.keys(mutatedAuthData).length === 0) { if (!hasMutatedAuthData) {
return; return;
} }
// We have authData that is updated on login // We have authData that is updated on login
@@ -330,10 +332,14 @@ RestWrite.prototype.handleAuthData = function(authData) {
} else if (this.query && this.query.objectId) { } else if (this.query && this.query.objectId) {
// Trying to update auth data but users // Trying to update auth data but users
// are different // are different
if (results[0].objectId !== this.query.objectId) { if (userResult.objectId !== this.query.objectId) {
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED,
'this auth is already used'); 'this auth is already used');
} }
// No auth data was mutated, just keep going
if (!hasMutatedAuthData) {
return;
}
} }
} }
return this.handleAuthDataValidation(authData); return this.handleAuthDataValidation(authData);