Defers the session creation after DB operation (#1561)

This commit is contained in:
Florent Vilmart
2016-04-20 11:57:38 -04:00
parent 54b21c2f73
commit 59b4047de8
2 changed files with 60 additions and 32 deletions

View File

@@ -2272,6 +2272,31 @@ 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();
});
});
it('should not overwrite username when unlinking facebook user (regression test for #1532)', done => {
Parse.Object.disableSingleInstance();

View File

@@ -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,