From 523227bb90b247ae9ad50d2a5f091cbc14571aaf Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 19 Apr 2016 22:15:40 -0400 Subject: [PATCH] Defers the session creation after DB operation --- spec/ParseUser.spec.js | 25 ++++++++++++++++ src/RestWrite.js | 67 ++++++++++++++++++++++-------------------- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 9523f20d63..56d79726ff 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -2272,5 +2272,30 @@ describe('Parse.User testing', () => { } }); }); + + it('should not create extraneous session tokens', (done) => { + let config = new Config(Parse.applicationId); + config.database.loadSchema().then((s) => { + // Lock down the _User class for creation + return s.addClassIfNotExists('_User', {}, {create: {}}) + }).then((res) => { + let user = new Parse.User(); + return user.save({'username': 'user', 'password': 'pass'}); + }).then(() => { + fail('should not be able to save the user'); + }, (err) => { + return Promise.resolve(); + }).then(() => { + let q = new Parse.Query('_Session'); + return q.find({useMasterKey: true}) + }).then((res) => { + // We should have no session created + expect(res.length).toBe(0); + done(); + }, (err) => { + fail('should not fail'); + done(); + }); + }); }); diff --git a/src/RestWrite.js b/src/RestWrite.js index 0b88b71a8f..29084f0186 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -79,6 +79,8 @@ RestWrite.prototype.execute = function() { return this.expandFilesForExistingObjects(); }).then(() => { return this.runDatabaseOperation(); + }).then(() => { + return this.createSessionTokenIfNeeded(); }).then(() => { return this.handleFollowup(); }).then(() => { @@ -316,35 +318,6 @@ RestWrite.prototype.transformUser = function() { var promise = Promise.resolve(); - if (!this.query) { - var token = 'r:' + cryptoUtils.newToken(); - this.storage['token'] = token; - promise = promise.then(() => { - var expiresAt = this.config.generateSessionExpiresAt(); - var sessionData = { - sessionToken: token, - user: { - __type: 'Pointer', - className: '_User', - objectId: this.objectId() - }, - createdWith: { - 'action': 'signup', - 'authProvider': this.storage['authProvider'] || 'password' - }, - restricted: false, - installationId: this.auth.installationId, - expiresAt: Parse._encode(expiresAt) - }; - if (this.response && this.response.response) { - this.response.response.sessionToken = token; - } - var create = new RestWrite(this.config, Auth.master(this.config), - '_Session', null, sessionData); - return create.execute(); - }); - } - // If we're updating a _User object, clear the user cache for the session if (this.query && this.auth.user && this.auth.user.getSessionToken()) { cache.users.remove(this.auth.user.getSessionToken()); @@ -412,6 +385,39 @@ RestWrite.prototype.transformUser = function() { }); }; +RestWrite.prototype.createSessionTokenIfNeeded = function() { + if (this.className !== '_User') { + return; + } + if (this.query) { + return; + } + var token = 'r:' + cryptoUtils.newToken(); + + var expiresAt = this.config.generateSessionExpiresAt(); + var sessionData = { + sessionToken: token, + user: { + __type: 'Pointer', + className: '_User', + objectId: this.objectId() + }, + createdWith: { + 'action': 'signup', + 'authProvider': this.storage['authProvider'] || 'password' + }, + restricted: false, + installationId: this.auth.installationId, + expiresAt: Parse._encode(expiresAt) + }; + if (this.response && this.response.response) { + this.response.response.sessionToken = token; + } + var create = new RestWrite(this.config, Auth.master(this.config), + '_Session', null, sessionData); + return create.execute(); +} + // Handles any followup logic RestWrite.prototype.handleFollowup = function() { @@ -775,9 +781,6 @@ RestWrite.prototype.runDatabaseOperation = function() { return memo; }, resp); } - if (this.storage['token']) { - resp.sessionToken = this.storage['token']; - } this.response = { status: 201, response: resp,