From f4243f4be5f7bfe0e077a6b59768d28983fcc128 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Thu, 11 Jul 2019 14:58:41 -0500 Subject: [PATCH 1/2] Add options for AnonymousUtils --- integration/test/ParseUserTest.js | 22 +++++++++++++++++++++- src/AnonymousUtils.js | 11 +++++++---- src/ParseUser.js | 10 ++++++---- src/__tests__/AnonymousUtils-test.js | 4 ++-- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/integration/test/ParseUserTest.js b/integration/test/ParseUserTest.js index 2829ed1bd..7f4404f14 100644 --- a/integration/test/ParseUserTest.js +++ b/integration/test/ParseUserTest.js @@ -536,7 +536,6 @@ describe('Parse User', () => { Parse.User.enableUnsafeCurrentUser(); await Parse.User.signUp('foobaz', '1234'); - await Parse.User.logOut(); const user = await Parse.AnonymousUtils.logIn(); user.set('field', 'hello world'); @@ -552,6 +551,27 @@ describe('Parse User', () => { } }); + it('anonymous user logIn does not use currentUser sessionToken', async () => { + Parse.User.enableUnsafeCurrentUser(); + + const user1 = await Parse.User.signUp('anon-not', '1234'); + const user2 = await Parse.AnonymousUtils.logIn(); + expect(user1.getSessionToken()).toBeDefined(); + expect(user2.getSessionToken()).toBeDefined(); + expect(user1.getSessionToken()).not.toBe(user2.getSessionToken()); + }); + + it('facebook logIn does not use currentUser sessionToken', async () => { + Parse.User.enableUnsafeCurrentUser(); + Parse.FacebookUtils.init(); + + const user1 = await Parse.User.signUp('facebook-not', '1234'); + const user2 = await Parse.FacebookUtils.logIn(); + expect(user1.getSessionToken()).toBeDefined(); + expect(user2.getSessionToken()).toBeDefined(); + expect(user1.getSessionToken()).not.toBe(user2.getSessionToken()); + }); + it('can signUp user with subclass', async () => { Parse.User.enableUnsafeCurrentUser(); diff --git a/src/AnonymousUtils.js b/src/AnonymousUtils.js index 801d25b5e..f1dcedd5e 100644 --- a/src/AnonymousUtils.js +++ b/src/AnonymousUtils.js @@ -10,6 +10,7 @@ */ import ParseUser from './ParseUser'; const uuidv4 = require('uuid/v4'); +import type { RequestOptions } from './RESTController'; let registered = false; @@ -62,12 +63,13 @@ const AnonymousUtils = { * * @method logIn * @name Parse.AnonymousUtils.logIn + * @param {Object} options MasterKey / SessionToken. * @returns {Promise} * @static */ - logIn() { + logIn(options?: RequestOptions) { const provider = this._getAuthProvider(); - return ParseUser._logInWith(provider.getAuthType(), provider.getAuthData()); + return ParseUser._logInWith(provider.getAuthType(), provider.getAuthData(), options); }, /** @@ -76,12 +78,13 @@ const AnonymousUtils = { * @method link * @name Parse.AnonymousUtils.link * @param {Parse.User} user User to link. This must be the current user. + * @param {Object} options MasterKey / SessionToken. * @returns {Promise} * @static */ - link(user: ParseUser) { + link(user: ParseUser, options?: RequestOptions) { const provider = this._getAuthProvider(); - return user._linkWith(provider.getAuthType(), provider.getAuthData()); + return user._linkWith(provider.getAuthType(), provider.getAuthData(), options); }, _getAuthProvider() { diff --git a/src/ParseUser.js b/src/ParseUser.js index 7f1d03e9c..a77e5c0db 100644 --- a/src/ParseUser.js +++ b/src/ParseUser.js @@ -685,8 +685,8 @@ class ParseUser extends ParseObject { return controller.hydrate(userJSON); } - static logInWith(provider: any, options?: RequestOptions) { - return ParseUser._logInWith(provider, options); + static logInWith(provider: any, options: { authData?: AuthData }, saveOpts?: FullOptions) { + return ParseUser._logInWith(provider, options, saveOpts); } /** @@ -804,9 +804,11 @@ class ParseUser extends ParseObject { }); } - static _logInWith(provider: any, options?: RequestOptions) { + static _logInWith(provider: any, options: { authData?: AuthData }, saveOpts?: FullOptions = {}) { + saveOpts.sessionToken = saveOpts.sessionToken || ''; + const user = new ParseUser(); - return user._linkWith(provider, options); + return user._linkWith(provider, options, saveOpts); } static _clearCache() { diff --git a/src/__tests__/AnonymousUtils-test.js b/src/__tests__/AnonymousUtils-test.js index f070555cc..e287251c1 100644 --- a/src/__tests__/AnonymousUtils-test.js +++ b/src/__tests__/AnonymousUtils-test.js @@ -74,7 +74,7 @@ describe('AnonymousUtils', () => { jest.spyOn(user, '_linkWith'); AnonymousUtils.link(user); expect(user._linkWith).toHaveBeenCalledTimes(1); - expect(user._linkWith).toHaveBeenCalledWith('anonymous', mockProvider.getAuthData()); + expect(user._linkWith).toHaveBeenCalledWith('anonymous', mockProvider.getAuthData(), undefined); expect(AnonymousUtils._getAuthProvider).toHaveBeenCalledTimes(1); }); @@ -82,7 +82,7 @@ describe('AnonymousUtils', () => { jest.spyOn(MockUser, '_logInWith'); AnonymousUtils.logIn(); expect(MockUser._logInWith).toHaveBeenCalledTimes(1); - expect(MockUser._logInWith).toHaveBeenCalledWith('anonymous', mockProvider.getAuthData()); + expect(MockUser._logInWith).toHaveBeenCalledWith('anonymous', mockProvider.getAuthData(), undefined); expect(AnonymousUtils._getAuthProvider).toHaveBeenCalledTimes(1); }); }); From 2e6bffcadd6a34d5ea87006d91f237c1dbbc4a28 Mon Sep 17 00:00:00 2001 From: Diamond Lewis Date: Thu, 11 Jul 2019 15:44:49 -0500 Subject: [PATCH 2/2] add more tests --- integration/test/ParseUserTest.js | 52 ++++++++++++++++++++++++++++--- src/ParseUser.js | 7 ++--- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/integration/test/ParseUserTest.js b/integration/test/ParseUserTest.js index 7f4404f14..414962238 100644 --- a/integration/test/ParseUserTest.js +++ b/integration/test/ParseUserTest.js @@ -561,6 +561,27 @@ describe('Parse User', () => { expect(user1.getSessionToken()).not.toBe(user2.getSessionToken()); }); + it('anonymous user link currentUser', async () => { + Parse.User.enableUnsafeCurrentUser(); + + const user1 = await Parse.User.signUp('anon-not', '1234'); + const user2 = await Parse.AnonymousUtils.link(user1); + expect(user1.getSessionToken()).toBeDefined(); + expect(user2.getSessionToken()).toBeDefined(); + expect(user1.getSessionToken()).toBe(user2.getSessionToken()); + }); + + it('anonymous user link does not use currentUser sessionToken', async () => { + Parse.User.enableUnsafeCurrentUser(); + + const user1 = await Parse.User.signUp('anon-not', '1234'); + const user2 = new Parse.User(); + await Parse.AnonymousUtils.link(user2); + expect(user1.getSessionToken()).toBeDefined(); + expect(user2.getSessionToken()).toBeDefined(); + expect(user1.getSessionToken()).not.toBe(user2.getSessionToken()); + }); + it('facebook logIn does not use currentUser sessionToken', async () => { Parse.User.enableUnsafeCurrentUser(); Parse.FacebookUtils.init(); @@ -572,6 +593,29 @@ describe('Parse User', () => { expect(user1.getSessionToken()).not.toBe(user2.getSessionToken()); }); + it('facebook link currentUser', async () => { + Parse.User.enableUnsafeCurrentUser(); + Parse.FacebookUtils.init(); + + const user1 = await Parse.User.signUp('facebook-not', '1234'); + const user2 = await Parse.FacebookUtils.link(user1); + expect(user1.getSessionToken()).toBeDefined(); + expect(user2.getSessionToken()).toBeDefined(); + expect(user1.getSessionToken()).toBe(user2.getSessionToken()); + }); + + it('facebook link does not use currentUser sessionToken', async () => { + Parse.User.enableUnsafeCurrentUser(); + Parse.FacebookUtils.init(); + + const user1 = await Parse.User.signUp('facebook-not', '1234'); + const user2 = new Parse.User(); + await Parse.FacebookUtils.link(user2); + expect(user1.getSessionToken()).toBeDefined(); + expect(user2.getSessionToken()).toBeDefined(); + expect(user1.getSessionToken()).not.toBe(user2.getSessionToken()); + }); + it('can signUp user with subclass', async () => { Parse.User.enableUnsafeCurrentUser(); @@ -669,15 +713,13 @@ describe('Parse User', () => { expect(loggedIn.authenticated()).toBeTruthy(); }); - it('linking un-authenticated user without master key will throw', async (done) => { + it('can linking un-authenticated user without master key', async () => { const user = new Parse.User(); user.setUsername('Alice'); user.setPassword('sekrit'); await user.save(null, { useMasterKey: true }); - user._linkWith(provider.getAuthType(), provider.getAuthData()) - .then(() => done.fail('should fail')) - .catch(e => expect(e.message).toBe(`Cannot modify user ${user.id}.`)) - .then(done); + await user._linkWith(provider.getAuthType(), provider.getAuthData()); + expect(user.getSessionToken()).toBeDefined(); }); it('can link with custom auth', async () => { diff --git a/src/ParseUser.js b/src/ParseUser.js index a77e5c0db..f04337afd 100644 --- a/src/ParseUser.js +++ b/src/ParseUser.js @@ -77,7 +77,8 @@ class ParseUser extends ParseObject { * Unlike in the Android/iOS SDKs, logInWith is unnecessary, since you can * call linkWith on the user (even if it doesn't exist yet on the server). */ - _linkWith(provider: any, options: { authData?: AuthData }, saveOpts?: FullOptions): Promise { + _linkWith(provider: any, options: { authData?: AuthData }, saveOpts?: FullOptions = {}): Promise { + saveOpts.sessionToken = saveOpts.sessionToken || this.getSessionToken() || ''; let authType; if (typeof provider === 'string') { authType = provider; @@ -804,9 +805,7 @@ class ParseUser extends ParseObject { }); } - static _logInWith(provider: any, options: { authData?: AuthData }, saveOpts?: FullOptions = {}) { - saveOpts.sessionToken = saveOpts.sessionToken || ''; - + static _logInWith(provider: any, options: { authData?: AuthData }, saveOpts?: FullOptions) { const user = new ParseUser(); return user._linkWith(provider, options, saveOpts); }