* Adds failing test for #3451 (on multiple logins) * Factor sessionDestruction as part of Session creation flow in RestWrite * nits
This commit is contained in:
@@ -3453,4 +3453,34 @@ describe('Parse.User testing', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not duplicate session when logging in multiple times #3451', (done) => {
|
||||||
|
const user = new Parse.User();
|
||||||
|
user.signUp({
|
||||||
|
username: 'yolo',
|
||||||
|
password: 'yolo',
|
||||||
|
email: 'yo@lo.com'
|
||||||
|
}).then(() => {
|
||||||
|
const promises = [];
|
||||||
|
while(promises.length != 5) {
|
||||||
|
Parse.User.logIn('yolo', 'yolo')
|
||||||
|
promises.push(Parse.User.logIn('yolo', 'yolo').then((res) => {
|
||||||
|
// ensure a new session token is generated at each login
|
||||||
|
expect(res.getSessionToken()).not.toBe(user.getSessionToken());
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return Promise.all(promises);
|
||||||
|
}).then(() => {
|
||||||
|
// wait because session destruction is not synchronous
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, 100);
|
||||||
|
});
|
||||||
|
}).then(() => {
|
||||||
|
const query = new Parse.Query('_Session');
|
||||||
|
return query.find({ useMasterKey: true });
|
||||||
|
}).then((results) => {
|
||||||
|
// only one session in the end
|
||||||
|
expect(results.length).toBe(1);
|
||||||
|
}).then(done, done.fail);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ RestWrite.prototype.execute = function() {
|
|||||||
return this.transformUser();
|
return this.transformUser();
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return this.expandFilesForExistingObjects();
|
return this.expandFilesForExistingObjects();
|
||||||
|
}).then(() => {
|
||||||
|
return this.destroyDuplicatedSessions();
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return this.runDatabaseOperation();
|
return this.runDatabaseOperation();
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
@@ -588,19 +590,33 @@ RestWrite.prototype.createSessionToken = function() {
|
|||||||
this.response.response.sessionToken = token;
|
this.response.response.sessionToken = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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();
|
return new RestWrite(this.config, Auth.master(this.config), '_Session', null, sessionData).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RestWrite.prototype.destroyDuplicatedSessions = function() {
|
||||||
|
// Only for _Session, and at creation time
|
||||||
|
if (this.className != '_Session' || this.query) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Destroy the sessions in 'Background'
|
||||||
|
const {
|
||||||
|
user,
|
||||||
|
installationId,
|
||||||
|
sessionToken,
|
||||||
|
} = this.data;
|
||||||
|
if (!user || !installationId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!user.objectId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.config.database.destroy('_Session', {
|
||||||
|
user,
|
||||||
|
installationId,
|
||||||
|
sessionToken: { '$ne': sessionToken },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Handles any followup logic
|
// Handles any followup logic
|
||||||
RestWrite.prototype.handleFollowup = function() {
|
RestWrite.prototype.handleFollowup = function() {
|
||||||
if (this.storage && this.storage['clearSessions'] && this.config.revokeSessionOnPasswordReset) {
|
if (this.storage && this.storage['clearSessions'] && this.config.revokeSessionOnPasswordReset) {
|
||||||
|
|||||||
Reference in New Issue
Block a user