Fixes #2885 duplicate sessions (#4143)

* Adds test to repro the issue

* Improved test

* Destroy duplicate sessions for User/Installation-id pair

- Sessions will also be created with action login instead of signup when using 3rd party auth
This commit is contained in:
Florent Vilmart
2017-09-11 09:52:18 -04:00
committed by GitHub
parent bc3cef2cd9
commit 839a117246
2 changed files with 43 additions and 3 deletions

View File

@@ -1168,6 +1168,36 @@ describe('Parse.User testing', () => {
}); });
}); });
it('only creates a single session for an installation / user pair (#2885)', done => {
Parse.Object.disableSingleInstance();
const provider = getMockFacebookProvider();
Parse.User._registerAuthenticationProvider(provider);
Parse.User.logInWith('facebook', {
success: () => {
return Parse.User.logInWith('facebook', {
success: () => {
return Parse.User.logInWith('facebook', {
success: (user) => {
const sessionToken = user.getSessionToken();
const query = new Parse.Query('_Session');
return query.find({ useMasterKey: true })
.then((results) => {
expect(results.length).toBe(1);
expect(results[0].get('sessionToken')).toBe(sessionToken);
expect(results[0].get('createdWith')).toEqual({
action: 'login',
authProvider: 'facebook'
});
done();
}).catch(done.fail);
}
});
}
});
}
});
});
it('log in with provider with files', done => { it('log in with provider with files', done => {
const provider = getMockFacebookProvider(); const provider = getMockFacebookProvider();
Parse.User._registerAuthenticationProvider(provider); Parse.User._registerAuthenticationProvider(provider);

View File

@@ -568,7 +568,7 @@ RestWrite.prototype.createSessionToken = function() {
objectId: this.objectId() objectId: this.objectId()
}, },
createdWith: { createdWith: {
'action': 'signup', 'action': this.storage['authProvider'] ? 'login' : 'signup',
'authProvider': this.storage['authProvider'] || 'password' 'authProvider': this.storage['authProvider'] || 'password'
}, },
restricted: false, restricted: false,
@@ -578,8 +578,18 @@ RestWrite.prototype.createSessionToken = function() {
if (this.response && this.response.response) { if (this.response && this.response.response) {
this.response.response.sessionToken = token; this.response.response.sessionToken = token;
} }
var create = new RestWrite(this.config, Auth.master(this.config), '_Session', null, sessionData);
return create.execute(); // Destroy the sessions in 'Background'
this.config.database.destroy('_Session', {
user: {
__type: 'Pointer',
className: '_User',
objectId: this.objectId()
},
installationId: this.auth.installationId,
sessionToken: { '$ne': token },
});
return new RestWrite(this.config, Auth.master(this.config), '_Session', null, sessionData).execute();
} }
// Handles any followup logic // Handles any followup logic