Skip to content

Commit 6d4663b

Browse files
authored
refactor: Dry handleAuthData for safer code maintenance in the future (#9025)
1 parent 1a2b513 commit 6d4663b

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

spec/AuthenticationAdaptersV2.spec.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,33 @@ describe('Auth Adapter features', () => {
487487
expect(baseAdapter2.validateAuthData).toHaveBeenCalledTimes(2);
488488
});
489489

490+
it('should not perform authData validation twice when data mutated', async () => {
491+
spyOn(baseAdapter, 'validateAuthData').and.resolveTo({});
492+
await reconfigureServer({
493+
auth: { baseAdapter },
494+
allowExpiredAuthDataToken: false,
495+
});
496+
497+
const user = new Parse.User();
498+
499+
await user.save({
500+
authData: {
501+
baseAdapter: { id: 'baseAdapter', token: "sometoken1" },
502+
},
503+
});
504+
505+
expect(baseAdapter.validateAuthData).toHaveBeenCalledTimes(1);
506+
507+
const user2 = new Parse.User();
508+
await user2.save({
509+
authData: {
510+
baseAdapter: { id: 'baseAdapter', token: "sometoken2" },
511+
},
512+
});
513+
514+
expect(baseAdapter.validateAuthData).toHaveBeenCalledTimes(2);
515+
});
516+
490517
it('should require additional provider if configured', async () => {
491518
await reconfigureServer({
492519
auth: { baseAdapter, additionalAdapter },
@@ -937,7 +964,7 @@ describe('Auth Adapter features', () => {
937964
allowExpiredAuthDataToken: false,
938965
});
939966
logger = require('../lib/logger').logger;
940-
spyOn(logger, 'error').and.callFake(() => {});
967+
spyOn(logger, 'error').and.callFake(() => { });
941968
user = new Parse.User();
942969
await user.save({ authData: { modernAdapter: { id: 'modernAdapter' } } });
943970
const user2 = new Parse.User();

src/RestWrite.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -523,10 +523,14 @@ RestWrite.prototype.handleAuthData = async function (authData) {
523523
const r = await Auth.findUsersWithAuthData(this.config, authData);
524524
const results = this.filteredObjectsByACL(r);
525525

526-
if (results.length > 1) {
526+
const userId = this.getUserId();
527+
const userResult = results[0];
528+
const foundUserIsNotCurrentUser = userId && userResult && userId !== userResult.objectId;
529+
530+
if (results.length > 1 || foundUserIsNotCurrentUser) {
527531
// To avoid https://github.com/parse-community/parse-server/security/advisories/GHSA-8w3j-g983-8jh5
528532
// Let's run some validation before throwing
529-
await Auth.handleAuthDataValidation(authData, this, results[0]);
533+
await Auth.handleAuthDataValidation(authData, this, userResult);
530534
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used');
531535
}
532536

@@ -544,13 +548,6 @@ RestWrite.prototype.handleAuthData = async function (authData) {
544548

545549
// User found with provided authData
546550
if (results.length === 1) {
547-
const userId = this.getUserId();
548-
const userResult = results[0];
549-
// Prevent duplicate authData id
550-
if (userId && userId !== userResult.objectId) {
551-
await Auth.handleAuthDataValidation(authData, this, results[0]);
552-
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used');
553-
}
554551

555552
this.storage.authProvider = Object.keys(authData).join(',');
556553

0 commit comments

Comments
 (0)