* Adds test for #3867 * Always Skip authData validation when nothing is mutated
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user