From 34dc306845157452501b687b8b16a1a6ec8b7497 Mon Sep 17 00:00:00 2001 From: ashishn Date: Tue, 5 Sep 2023 23:41:05 +0530 Subject: [PATCH 01/18] Added test for Facebook signup, login using await/async as first step to test error 206 raised in https://github.com/parse-community/parse-server/issues/6511 --- spec/rest.spec.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/spec/rest.spec.js b/spec/rest.spec.js index 61a5c728e4..c14c9d479c 100644 --- a/spec/rest.spec.js +++ b/spec/rest.spec.js @@ -409,6 +409,46 @@ describe('rest create', () => { }); }); + //to be added to PR + it('test facebook signup, login', async () => { + const data = { + authData: { + facebook: { + id: '8675309', + access_token: 'jenny', + }, + }, + }; + + let newUserSignedUpByFacebookObjectId; + + try { + const firstResponse = await rest.create(config, auth.nobody(config), '_User', data); + + expect(typeof firstResponse.response.objectId).toEqual('string'); + expect(typeof firstResponse.response.createdAt).toEqual('string'); + expect(typeof firstResponse.response.sessionToken).toEqual('string'); + newUserSignedUpByFacebookObjectId = firstResponse.response.objectId; + + const secondResponse = await rest.create(config, auth.nobody(config), '_User', data); + + expect(typeof secondResponse.response.objectId).toEqual('string'); + expect(typeof secondResponse.response.createdAt).toEqual('string'); + expect(typeof secondResponse.response.username).toEqual('string'); + expect(typeof secondResponse.response.updatedAt).toEqual('string'); + expect(secondResponse.response.objectId).toEqual(newUserSignedUpByFacebookObjectId); + + const sessionResponse = await rest.find(config, auth.master(config), '_Session', { + sessionToken: secondResponse.response.sessionToken, + }); + + expect(sessionResponse.results.length).toEqual(1); + const output = sessionResponse.results[0]; + expect(output.user.objectId).toEqual(newUserSignedUpByFacebookObjectId); + } catch (err) { + jfail(err); + } + }); it('stores pointers', done => { const obj = { foo: 'bar', From 11d2a1f6b42f58a35618ba097550e7f7ca72e9b3 Mon Sep 17 00:00:00 2001 From: ashishn Date: Wed, 6 Sep 2023 23:31:50 +0530 Subject: [PATCH 02/18] Added test in ParseUser.spec.js for testing Facebook sign up followed update --- spec/ParseUser.spec.js | 23 +++++++++++++++++++++++ spec/rest.spec.js | 40 ---------------------------------------- 2 files changed, 23 insertions(+), 40 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 4d3beaf349..8c2b1d3a3d 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1265,6 +1265,29 @@ describe('Parse.User testing', () => { done(); }); + fit('log in with Facebook and update email for signed up User', async done => { + const provider = getMockFacebookProvider(); + const userEmail = 'foo@example.com'; + + Parse.User._registerAuthenticationProvider(provider); + const signedUpUser = await Parse.User._logInWith('facebook'); + ok(signedUpUser instanceof Parse.User, 'Model should be a Parse.User'); + strictEqual(Parse.User.current(), signedUpUser); + ok(signedUpUser.extended(), 'Should have used subclass.'); + strictEqual(provider.authData.id, provider.synchronizedUserId); + strictEqual(provider.authData.access_token, provider.synchronizedAuthToken); + strictEqual(provider.authData.expiration_date, provider.synchronizedExpiration); + ok(signedUpUser._isLinked('facebook'), 'User should be linked to facebook'); + + signedUpUser.set('email', 'foo@example.com'); + signedUpUser.set('loginProvider', 'facebook'); + signedUpUser.set('social_id', provider.authData.id); + signedUpUser.set('account_status', 'active'); + await signedUpUser.save(); + strictEqual(signedUpUser.get('email'), userEmail); + done(); + }); + it('can not set authdata to null', async () => { try { const provider = getMockFacebookProvider(); diff --git a/spec/rest.spec.js b/spec/rest.spec.js index c14c9d479c..61a5c728e4 100644 --- a/spec/rest.spec.js +++ b/spec/rest.spec.js @@ -409,46 +409,6 @@ describe('rest create', () => { }); }); - //to be added to PR - it('test facebook signup, login', async () => { - const data = { - authData: { - facebook: { - id: '8675309', - access_token: 'jenny', - }, - }, - }; - - let newUserSignedUpByFacebookObjectId; - - try { - const firstResponse = await rest.create(config, auth.nobody(config), '_User', data); - - expect(typeof firstResponse.response.objectId).toEqual('string'); - expect(typeof firstResponse.response.createdAt).toEqual('string'); - expect(typeof firstResponse.response.sessionToken).toEqual('string'); - newUserSignedUpByFacebookObjectId = firstResponse.response.objectId; - - const secondResponse = await rest.create(config, auth.nobody(config), '_User', data); - - expect(typeof secondResponse.response.objectId).toEqual('string'); - expect(typeof secondResponse.response.createdAt).toEqual('string'); - expect(typeof secondResponse.response.username).toEqual('string'); - expect(typeof secondResponse.response.updatedAt).toEqual('string'); - expect(secondResponse.response.objectId).toEqual(newUserSignedUpByFacebookObjectId); - - const sessionResponse = await rest.find(config, auth.master(config), '_Session', { - sessionToken: secondResponse.response.sessionToken, - }); - - expect(sessionResponse.results.length).toEqual(1); - const output = sessionResponse.results[0]; - expect(output.user.objectId).toEqual(newUserSignedUpByFacebookObjectId); - } catch (err) { - jfail(err); - } - }); it('stores pointers', done => { const obj = { foo: 'bar', From ab7247816c2abd012dd9288cc01d39604e5851bc Mon Sep 17 00:00:00 2001 From: Ashish Naik Date: Thu, 7 Sep 2023 22:31:38 +0530 Subject: [PATCH 03/18] Update spec/ParseUser.spec.js Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> Signed-off-by: Ashish Naik --- spec/ParseUser.spec.js | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 8c2b1d3a3d..f6bad075b8 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1270,22 +1270,21 @@ describe('Parse.User testing', () => { const userEmail = 'foo@example.com'; Parse.User._registerAuthenticationProvider(provider); - const signedUpUser = await Parse.User._logInWith('facebook'); - ok(signedUpUser instanceof Parse.User, 'Model should be a Parse.User'); - strictEqual(Parse.User.current(), signedUpUser); - ok(signedUpUser.extended(), 'Should have used subclass.'); - strictEqual(provider.authData.id, provider.synchronizedUserId); - strictEqual(provider.authData.access_token, provider.synchronizedAuthToken); - strictEqual(provider.authData.expiration_date, provider.synchronizedExpiration); - ok(signedUpUser._isLinked('facebook'), 'User should be linked to facebook'); - - signedUpUser.set('email', 'foo@example.com'); - signedUpUser.set('loginProvider', 'facebook'); - signedUpUser.set('social_id', provider.authData.id); - signedUpUser.set('account_status', 'active'); - await signedUpUser.save(); - strictEqual(signedUpUser.get('email'), userEmail); - done(); + const user = await Parse.User._logInWith('facebook'); + expect(user instanceof Parse.User).toBeTrue(); + expect(Parse.User.current()).toEqual(user); + expect(user.extended()).toBeTrue(); + expect(provider.authData.id).toBe(provider.synchronizedUserId); + expect(provider.authData.access_token).toBe(provider.synchronizedAuthToken); + expect(provider.authData.expiration_date).toBe(provider.synchronizedExpiration); + expect(user._isLinked('facebook')).toBeTrue(); + + user.set('email', 'foo@example.com'); + user.set('loginProvider', 'facebook'); + user.set('social_id', provider.authData.id); + user.set('account_status', 'active'); + await user.save(); + expect(user.get('email')).toBe(userEmail); }); it('can not set authdata to null', async () => { From d5474d3bb4bd249c037880c0473288aac196dba6 Mon Sep 17 00:00:00 2001 From: ashishn Date: Thu, 7 Sep 2023 23:29:24 +0530 Subject: [PATCH 04/18] Doing reconfigure server with email adaptor options used in index.js. This causes test to fail with error 206. --- spec/ParseUser.spec.js | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index f6bad075b8..a55f22f03a 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1266,6 +1266,34 @@ describe('Parse.User testing', () => { }); fit('log in with Facebook and update email for signed up User', async done => { + const emailAdapter = { + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => Promise.resolve(), + }; + await reconfigureServer({ + appName: 'unused', + verifyUserEmails: true, + emailAdapter: { + module: emailAdapter, + options: { + sender: 'a@a.com', + templates: {}, + }, + passwordPolicy: { + validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/, + validationError: + 'Password must have at least 8 characters, contain at least 1 digit, 1 upper case and 1 lower case character.', + doNotAllowUsername: true, + maxPasswordAge: 90, + maxPasswordHistory: 5, + resetTokenValidityDuration: 24 * 60 * 60, + }, + }, + emailVerifyTokenValidityDuration: 0.5, + preventLoginWithUnverifiedEmail: true, + publicServerURL: 'http://localhost:8378/1', + }); + const provider = getMockFacebookProvider(); const userEmail = 'foo@example.com'; @@ -1281,10 +1309,10 @@ describe('Parse.User testing', () => { user.set('email', 'foo@example.com'); user.set('loginProvider', 'facebook'); - user.set('social_id', provider.authData.id); - user.set('account_status', 'active'); await user.save(); + expect(user.get('email')).toBe(userEmail); + done(); }); it('can not set authdata to null', async () => { From 3d6b9c4e1ec24c8ec87ec761383466a97f4604e6 Mon Sep 17 00:00:00 2001 From: ashishn Date: Fri, 8 Sep 2023 13:34:58 +0530 Subject: [PATCH 05/18] Kept only code that is failing the test. Renamed test. --- spec/ParseUser.spec.js | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index a55f22f03a..b903518dd5 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1265,7 +1265,7 @@ describe('Parse.User testing', () => { done(); }); - fit('log in with Facebook and update email for signed up User', async done => { + fit('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async done => { const emailAdapter = { sendPasswordResetEmail: () => Promise.resolve(), sendMail: () => Promise.resolve(), @@ -1273,30 +1273,14 @@ describe('Parse.User testing', () => { await reconfigureServer({ appName: 'unused', verifyUserEmails: true, + preventLoginWithUnverifiedEmail: true, emailAdapter: { module: emailAdapter, - options: { - sender: 'a@a.com', - templates: {}, - }, - passwordPolicy: { - validatorPattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/, - validationError: - 'Password must have at least 8 characters, contain at least 1 digit, 1 upper case and 1 lower case character.', - doNotAllowUsername: true, - maxPasswordAge: 90, - maxPasswordHistory: 5, - resetTokenValidityDuration: 24 * 60 * 60, - }, }, - emailVerifyTokenValidityDuration: 0.5, - preventLoginWithUnverifiedEmail: true, publicServerURL: 'http://localhost:8378/1', }); const provider = getMockFacebookProvider(); - const userEmail = 'foo@example.com'; - Parse.User._registerAuthenticationProvider(provider); const user = await Parse.User._logInWith('facebook'); expect(user instanceof Parse.User).toBeTrue(); @@ -1307,11 +1291,7 @@ describe('Parse.User testing', () => { expect(provider.authData.expiration_date).toBe(provider.synchronizedExpiration); expect(user._isLinked('facebook')).toBeTrue(); - user.set('email', 'foo@example.com'); - user.set('loginProvider', 'facebook'); await user.save(); - - expect(user.get('email')).toBe(userEmail); done(); }); From 8f11478084c91f8317112f509cb0cb8de7e26deb Mon Sep 17 00:00:00 2001 From: ashishn Date: Fri, 8 Sep 2023 14:59:06 +0530 Subject: [PATCH 06/18] Updated test to use ExpectAsync and removed done() --- spec/ParseUser.spec.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index b903518dd5..68058e0510 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1265,7 +1265,7 @@ describe('Parse.User testing', () => { done(); }); - fit('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async done => { + fit('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async () => { const emailAdapter = { sendPasswordResetEmail: () => Promise.resolve(), sendMail: () => Promise.resolve(), @@ -1291,8 +1291,7 @@ describe('Parse.User testing', () => { expect(provider.authData.expiration_date).toBe(provider.synchronizedExpiration); expect(user._isLinked('facebook')).toBeTrue(); - await user.save(); - done(); + await expectAsync(user.save()); }); it('can not set authdata to null', async () => { From 46f8e10b768f50d0a81869e649f15680845c06af Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:11:17 +0200 Subject: [PATCH 07/18] Update spec/ParseUser.spec.js Signed-off-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/ParseUser.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 68058e0510..6d0ec62cfb 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1291,7 +1291,7 @@ describe('Parse.User testing', () => { expect(provider.authData.expiration_date).toBe(provider.synchronizedExpiration); expect(user._isLinked('facebook')).toBeTrue(); - await expectAsync(user.save()); + await expectAsync(user.save()).toBeResolved(); }); it('can not set authdata to null', async () => { From af1616c13cd8b3c970abe915f8d3195756aa869a Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:11:33 +0200 Subject: [PATCH 08/18] Update spec/ParseUser.spec.js Signed-off-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/ParseUser.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 6d0ec62cfb..74715d5dd9 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1290,7 +1290,6 @@ describe('Parse.User testing', () => { expect(provider.authData.access_token).toBe(provider.synchronizedAuthToken); expect(provider.authData.expiration_date).toBe(provider.synchronizedExpiration); expect(user._isLinked('facebook')).toBeTrue(); - await expectAsync(user.save()).toBeResolved(); }); From 8e818c0ab0173e43f2cb0a5522922d5e57511d8d Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:12:18 +0200 Subject: [PATCH 09/18] Update spec/ParseUser.spec.js Signed-off-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/ParseUser.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 74715d5dd9..6000a9655f 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1266,6 +1266,7 @@ describe('Parse.User testing', () => { }); fit('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async () => { + const provider = getMockFacebookProvider(); const emailAdapter = { sendPasswordResetEmail: () => Promise.resolve(), sendMail: () => Promise.resolve(), @@ -1280,7 +1281,6 @@ describe('Parse.User testing', () => { publicServerURL: 'http://localhost:8378/1', }); - const provider = getMockFacebookProvider(); Parse.User._registerAuthenticationProvider(provider); const user = await Parse.User._logInWith('facebook'); expect(user instanceof Parse.User).toBeTrue(); From def6bff8ac6f63ac7d911134d6e08a7f1f98b32d Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:15:41 +0200 Subject: [PATCH 10/18] Update spec/ParseUser.spec.js Signed-off-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/ParseUser.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 6000a9655f..0e63261da5 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1272,7 +1272,7 @@ describe('Parse.User testing', () => { sendMail: () => Promise.resolve(), }; await reconfigureServer({ - appName: 'unused', + appName: 'ExampleApp', verifyUserEmails: true, preventLoginWithUnverifiedEmail: true, emailAdapter: { From fae2b443bff791ea4c745ecdbe81004a5a7f38b5 Mon Sep 17 00:00:00 2001 From: ashishn Date: Sun, 17 Sep 2023 17:54:58 +0530 Subject: [PATCH 11/18] authProvider is not set currently during auth sign up. Setting storage.authProvider early to test. --- src/RestWrite.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/RestWrite.js b/src/RestWrite.js index a469936fd8..cf34f12586 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -512,6 +512,7 @@ RestWrite.prototype.handleAuthData = async function (authData) { this.data.authData = validatedAuthData; return; } + this.storage.authProvider = Object.keys(authData).join(','); // User found with provided authData if (results.length === 1) { From e01c9f58c03dd3948d455c3725e73385d27e3b88 Mon Sep 17 00:00:00 2001 From: ashishn Date: Sun, 17 Sep 2023 18:03:22 +0530 Subject: [PATCH 12/18] authProvider is not set currently during auth sign up. Setting storage.authProvider early to test --- src/RestWrite.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/RestWrite.js b/src/RestWrite.js index cf34f12586..05ea8d0e51 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -501,6 +501,8 @@ RestWrite.prototype.handleAuthData = async function (authData) { throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); } + this.storage.authProvider = Object.keys(authData).join(','); + // No user found with provided authData we need to validate if (!results.length) { const { authData: validatedAuthData, authDataResponse } = await Auth.handleAuthDataValidation( @@ -512,7 +514,6 @@ RestWrite.prototype.handleAuthData = async function (authData) { this.data.authData = validatedAuthData; return; } - this.storage.authProvider = Object.keys(authData).join(','); // User found with provided authData if (results.length === 1) { From a945431577e1522cc5fbdd47061f59aff7b3393d Mon Sep 17 00:00:00 2001 From: ashishn Date: Tue, 19 Sep 2023 18:18:18 +0530 Subject: [PATCH 13/18] Committing changes done for testing. --- spec/ParseUser.spec.js | 2 +- src/RestWrite.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 0e63261da5..c3e451c027 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1265,7 +1265,7 @@ describe('Parse.User testing', () => { done(); }); - fit('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async () => { + it('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async () => { const provider = getMockFacebookProvider(); const emailAdapter = { sendPasswordResetEmail: () => Promise.resolve(), diff --git a/src/RestWrite.js b/src/RestWrite.js index 05ea8d0e51..c8047814d7 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -524,8 +524,6 @@ RestWrite.prototype.handleAuthData = async function (authData) { throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); } - this.storage.authProvider = Object.keys(authData).join(','); - const { hasMutatedAuthData, mutatedAuthData } = Auth.hasMutatedAuthData( authData, userResult.authData From b78e784e687fe0843cca8dee33559ac500c84d7d Mon Sep 17 00:00:00 2001 From: Ashish Naik Date: Sun, 5 May 2024 14:39:38 +0530 Subject: [PATCH 14/18] Reproducing error using test Reproducing error using test it('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true' Under ParseUser.spec.js. Signed-off-by: Ashish Naik --- src/RestWrite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RestWrite.js b/src/RestWrite.js index 89b1b6b5a1..c69f3b0a3e 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -534,7 +534,6 @@ RestWrite.prototype.handleAuthData = async function (authData) { throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); } - this.storage.authProvider = Object.keys(authData).join(','); // No user found with provided authData we need to validate if (!results.length) { @@ -550,6 +549,7 @@ RestWrite.prototype.handleAuthData = async function (authData) { // User found with provided authData if (results.length === 1) { + this.storage.authProvider = Object.keys(authData).join(','); const { hasMutatedAuthData, mutatedAuthData } = Auth.hasMutatedAuthData( authData, From cf1b227a3dd9998449246791b2b3dbdb0d03dd09 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Sun, 5 May 2024 21:23:02 +0200 Subject: [PATCH 15/18] review Signed-off-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/ParseUser.spec.js | 2 +- src/RestWrite.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index 65f192f08a..d57860c175 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1262,7 +1262,7 @@ describe('Parse.User testing', () => { done(); }); - it('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async () => { + fit('log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async () => { const provider = getMockFacebookProvider(); const emailAdapter = { sendPasswordResetEmail: () => Promise.resolve(), diff --git a/src/RestWrite.js b/src/RestWrite.js index c69f3b0a3e..e7db6db917 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -534,7 +534,6 @@ RestWrite.prototype.handleAuthData = async function (authData) { throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); } - // No user found with provided authData we need to validate if (!results.length) { const { authData: validatedAuthData, authDataResponse } = await Auth.handleAuthDataValidation( @@ -549,7 +548,7 @@ RestWrite.prototype.handleAuthData = async function (authData) { // User found with provided authData if (results.length === 1) { - this.storage.authProvider = Object.keys(authData).join(','); + this.storage.authProvider = Object.keys(authData).join(','); const { hasMutatedAuthData, mutatedAuthData } = Auth.hasMutatedAuthData( authData, From 5937c915a74214a0bab77e2c6a78e8c7486520cf Mon Sep 17 00:00:00 2001 From: Ashish Naik Date: Sun, 12 May 2024 15:57:02 +0530 Subject: [PATCH 16/18] Added test to ParseUser.spec.js Added test "'link and login with provider with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true'" under ParseUser.spec.js. Signed-off-by: Ashish Naik --- spec/ParseUser.spec.js | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index d57860c175..ea16a3e559 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1290,6 +1290,51 @@ describe('Parse.User testing', () => { await expectAsync(user.save()).toBeResolved(); }); + fit('link and login with provider with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async done => { + const provider = getMockFacebookProvider(); + const emailAdapter = { + sendPasswordResetEmail: () => Promise.resolve(), + sendMail: () => Promise.resolve(), + }; + await reconfigureServer({ + appName: 'ExampleApp', + verifyUserEmails: true, + preventLoginWithUnverifiedEmail: false, + emailAdapter: { + module: emailAdapter, + }, + publicServerURL: 'http://localhost:8378/1', + }); + + Parse.User._registerAuthenticationProvider(provider); + var user = new Parse.User(); + await expectAsync(user.save()).toBeResolved(); + console.log("saved") + user.set('username', 'testLinkWithProvider'); + user.set('password', 'mypass'); + await user.signUp(); + console.log("signed up") + user.set('username', 'testLinkWithProvider'); + user.set('password', 'mypass'); + await user.logIn() + console.log("logged in") + const model = await user._linkWith('facebook'); + console.log("linked") + expect(user instanceof Parse.User).toBeTrue(); + expect(user instanceof Parse.User).toBeTrue(); + expect(Parse.User.current()).toEqual(user); + expect(user.extended()).toBeTrue(); + expect(provider.authData.id).toBe(provider.synchronizedUserId); + expect(provider.authData.access_token).toBe(provider.synchronizedAuthToken); + expect(provider.authData.expiration_date).toBe(provider.synchronizedExpiration); + expect(user._isLinked('facebook')).toBeTrue(); + console.log("Linked"); + const loggedinuser = await Parse.User._logInWith('facebook'); + console.log("logged in " + loggedinuser.getSessionToken()); + await expectAsync(loggedinuser.save()).toBeResolved(); + + }); + it('can not set authdata to null', async () => { try { const provider = getMockFacebookProvider(); From 266abe02dde1f07ffdbed9cbc73b7229a62babb7 Mon Sep 17 00:00:00 2001 From: Ashish Naik Date: Mon, 13 May 2024 20:10:11 +0530 Subject: [PATCH 17/18] Update RestWrite.js for solution of Auth error Signed-off-by: Ashish Naik --- src/RestWrite.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/RestWrite.js b/src/RestWrite.js index e7db6db917..cbac86e0a0 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -527,6 +527,8 @@ RestWrite.prototype.handleAuthData = async function (authData) { const userResult = results[0]; const foundUserIsNotCurrentUser = userId && userResult && userId !== userResult.objectId; + this.storage.authProvider = Object.keys(authData).join(','); + if (results.length > 1 || foundUserIsNotCurrentUser) { // To avoid https://github.com/parse-community/parse-server/security/advisories/GHSA-8w3j-g983-8jh5 // Let's run some validation before throwing From 93485f22e11ef29b7f918001a5c8297bbf86f07a Mon Sep 17 00:00:00 2001 From: Ashish Naik Date: Mon, 13 May 2024 20:13:26 +0530 Subject: [PATCH 18/18] Update ParseUser.spec.js - updated test Rewrote test "'log in with Facebook and save signed up User with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true'" . Signed-off-by: Ashish Naik --- spec/ParseUser.spec.js | 56 +++--------------------------------------- 1 file changed, 3 insertions(+), 53 deletions(-) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index ea16a3e559..9d3645c1a1 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -1279,60 +1279,10 @@ describe('Parse.User testing', () => { }); Parse.User._registerAuthenticationProvider(provider); - const user = await Parse.User._logInWith('facebook'); - expect(user instanceof Parse.User).toBeTrue(); - expect(Parse.User.current()).toEqual(user); - expect(user.extended()).toBeTrue(); - expect(provider.authData.id).toBe(provider.synchronizedUserId); - expect(provider.authData.access_token).toBe(provider.synchronizedAuthToken); - expect(provider.authData.expiration_date).toBe(provider.synchronizedExpiration); - expect(user._isLinked('facebook')).toBeTrue(); - await expectAsync(user.save()).toBeResolved(); - }); - - fit('link and login with provider with verifyUserEmails=true and preventLoginWithUnverifiedEmail=true', async done => { - const provider = getMockFacebookProvider(); - const emailAdapter = { - sendPasswordResetEmail: () => Promise.resolve(), - sendMail: () => Promise.resolve(), - }; - await reconfigureServer({ - appName: 'ExampleApp', - verifyUserEmails: true, - preventLoginWithUnverifiedEmail: false, - emailAdapter: { - module: emailAdapter, - }, - publicServerURL: 'http://localhost:8378/1', - }); - - Parse.User._registerAuthenticationProvider(provider); - var user = new Parse.User(); + const user = await Parse.User.logInWith('facebook', {authData: provider.authData}); + expect(user.getSessionToken()).toBeDefined() + user.save() await expectAsync(user.save()).toBeResolved(); - console.log("saved") - user.set('username', 'testLinkWithProvider'); - user.set('password', 'mypass'); - await user.signUp(); - console.log("signed up") - user.set('username', 'testLinkWithProvider'); - user.set('password', 'mypass'); - await user.logIn() - console.log("logged in") - const model = await user._linkWith('facebook'); - console.log("linked") - expect(user instanceof Parse.User).toBeTrue(); - expect(user instanceof Parse.User).toBeTrue(); - expect(Parse.User.current()).toEqual(user); - expect(user.extended()).toBeTrue(); - expect(provider.authData.id).toBe(provider.synchronizedUserId); - expect(provider.authData.access_token).toBe(provider.synchronizedAuthToken); - expect(provider.authData.expiration_date).toBe(provider.synchronizedExpiration); - expect(user._isLinked('facebook')).toBeTrue(); - console.log("Linked"); - const loggedinuser = await Parse.User._logInWith('facebook'); - console.log("logged in " + loggedinuser.getSessionToken()); - await expectAsync(loggedinuser.save()).toBeResolved(); - }); it('can not set authdata to null', async () => {