From f8d895100a72042893beb7362e70f8ff8a4ed0dc Mon Sep 17 00:00:00 2001 From: Jessica Lawshe Date: Mon, 1 Jul 2019 17:11:07 -0500 Subject: [PATCH] Return custom error if provider linked to another account GitOrigin-RevId: c34a615b210a22e220736c9ba44d17be5add491b --- .../web/app/src/Features/Errors/Errors.js | 14 ++++++++++- .../User/ThirdPartyIdentityManager.js | 3 +++ .../src/UserThirdPartyIdentityTests.js | 23 ++++++++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/services/web/app/src/Features/Errors/Errors.js b/services/web/app/src/Features/Errors/Errors.js index 73c334e729..d03cec7142 100644 --- a/services/web/app/src/Features/Errors/Errors.js +++ b/services/web/app/src/Features/Errors/Errors.js @@ -139,13 +139,24 @@ var SLInV2Error = function(message) { } SLInV2Error.prototype.__proto__ = Error.prototype +const ThirdPartyIdentityExistsError = function(message) { + if (message == null) { + message = 'provider and external id already linked to another account' + } + const error = new Error(message) + error.name = 'ThirdPartyIdentityExistsError' + error.__proto__ = ThirdPartyIdentityExistsError.prototype + return error +} +ThirdPartyIdentityExistsError.prototype.__proto__ = Error.prototype + const ThirdPartyUserNotFoundError = function(message) { if (message == null) { message = 'user not found for provider and external id' } const error = new Error(message) error.name = 'ThirdPartyUserNotFoundError' - error.__proto__ = SLInV2Error.prototype + error.__proto__ = ThirdPartyUserNotFoundError.prototype return error } ThirdPartyUserNotFoundError.prototype.__proto__ = Error.prototype @@ -178,6 +189,7 @@ module.exports = Errors = { AccountMergeError, NotInV2Error, SLInV2Error, + ThirdPartyIdentityExistsError, ThirdPartyUserNotFoundError, SubscriptionAdminDeletionError } diff --git a/services/web/app/src/Features/User/ThirdPartyIdentityManager.js b/services/web/app/src/Features/User/ThirdPartyIdentityManager.js index 8a2cde5324..9aa0fdf206 100644 --- a/services/web/app/src/Features/User/ThirdPartyIdentityManager.js +++ b/services/web/app/src/Features/User/ThirdPartyIdentityManager.js @@ -94,6 +94,9 @@ const ThirdPartyIdentityManager = (module.exports = { } // add new tpi only if an entry for the provider does not exist UserUpdater.updateUser(query, update, function(err, res) { + if (err && err.code === 11000) { + return callback(new Errors.ThirdPartyIdentityExistsError()) + } if (err != null) { return callback(err) } diff --git a/services/web/test/acceptance/src/UserThirdPartyIdentityTests.js b/services/web/test/acceptance/src/UserThirdPartyIdentityTests.js index 361b7ec17b..7e89edce7b 100644 --- a/services/web/test/acceptance/src/UserThirdPartyIdentityTests.js +++ b/services/web/test/acceptance/src/UserThirdPartyIdentityTests.js @@ -24,7 +24,7 @@ describe('ThirdPartyIdentityManager', function() { this.externalUserId = 'external-user-id' this.externalData = { test: 'data' } this.user = new User() - return this.user.ensureUserExists(done) + this.user.ensureUserExists(done) }) afterEach(function(done) { @@ -161,6 +161,27 @@ describe('ThirdPartyIdentityManager', function() { } ) }) + + // describe('when another account tries to link same provider/externalUserId', function() { + // NOTE: Cannot run this test because we do not have indexes on the test DB + // beforeEach(function(done) { + // this.user2 = new User() + // this.user2.ensureUserExists(done) + // }) + // it('should not link provider', function(done) { + // ThirdPartyIdentityManager.link( + // this.user2.id, + // this.provider, + // this.externalUserId, + // this.externalData, + // (err, user) => { + // expect(err.name).to.equal('ThirdPartyIdentityExistsError') + // return done() + // } + // ) + // this.user2.full_delete_user(this.user2.email, done) + // }) + // }) }) })