Skip to content

Commit 1b492a9

Browse files
committed
feat: dry handleAuthData for safer code maintenance in the futur
1 parent 901aaf8 commit 1b492a9

File tree

3 files changed

+47
-22
lines changed

3 files changed

+47
-22
lines changed

spec/AuthenticationAdaptersV2.spec.js

Lines changed: 31 additions & 4 deletions
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 },
@@ -860,7 +887,7 @@ describe('Auth Adapter features', () => {
860887
auth: { challengeAdapter: throwInChallengeAdapter },
861888
});
862889
let logger = require('../lib/logger').logger;
863-
spyOn(logger, 'error').and.callFake(() => {});
890+
spyOn(logger, 'error').and.callFake(() => { });
864891
await expectAsync(
865892
requestWithExpectedError({
866893
headers: headers,
@@ -885,7 +912,7 @@ describe('Auth Adapter features', () => {
885912

886913
await reconfigureServer({ auth: { modernAdapter: throwInSetup } });
887914
logger = require('../lib/logger').logger;
888-
spyOn(logger, 'error').and.callFake(() => {});
915+
spyOn(logger, 'error').and.callFake(() => { });
889916
let user = new Parse.User();
890917
await expectAsync(
891918
user.save({ authData: { modernAdapter: { id: 'modernAdapter' } } })
@@ -907,7 +934,7 @@ describe('Auth Adapter features', () => {
907934

908935
await reconfigureServer({ auth: { modernAdapter: throwInUpdate } });
909936
logger = require('../lib/logger').logger;
910-
spyOn(logger, 'error').and.callFake(() => {});
937+
spyOn(logger, 'error').and.callFake(() => { });
911938
user = new Parse.User();
912939
await user.save({ authData: { modernAdapter: { id: 'updateAdapter' } } });
913940
await expectAsync(
@@ -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();

spec/ParseUser.spec.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3350,7 +3350,7 @@ describe('Parse.User testing', () => {
33503350

33513351
it('should not allow updates to emailVerified', done => {
33523352
const emailAdapter = {
3353-
sendVerificationEmail: () => {},
3353+
sendVerificationEmail: () => { },
33543354
sendPasswordResetEmail: () => Promise.resolve(),
33553355
sendMail: () => Promise.resolve(),
33563356
};
@@ -3386,7 +3386,7 @@ describe('Parse.User testing', () => {
33863386

33873387
it('should not retrieve hidden fields on GET users/me (#3432)', done => {
33883388
const emailAdapter = {
3389-
sendVerificationEmail: () => {},
3389+
sendVerificationEmail: () => { },
33903390
sendPasswordResetEmail: () => Promise.resolve(),
33913391
sendMail: () => Promise.resolve(),
33923392
};
@@ -3429,7 +3429,7 @@ describe('Parse.User testing', () => {
34293429

34303430
it('should not retrieve hidden fields on GET users/id (#3432)', done => {
34313431
const emailAdapter = {
3432-
sendVerificationEmail: () => {},
3432+
sendVerificationEmail: () => { },
34333433
sendPasswordResetEmail: () => Promise.resolve(),
34343434
sendMail: () => Promise.resolve(),
34353435
};
@@ -3477,7 +3477,7 @@ describe('Parse.User testing', () => {
34773477

34783478
it('should not retrieve hidden fields on login (#3432)', done => {
34793479
const emailAdapter = {
3480-
sendVerificationEmail: () => {},
3480+
sendVerificationEmail: () => { },
34813481
sendPasswordResetEmail: () => Promise.resolve(),
34823482
sendMail: () => Promise.resolve(),
34833483
};
@@ -3521,7 +3521,7 @@ describe('Parse.User testing', () => {
35213521

35223522
it('should not allow updates to hidden fields', async () => {
35233523
const emailAdapter = {
3524-
sendVerificationEmail: () => {},
3524+
sendVerificationEmail: () => { },
35253525
sendPasswordResetEmail: () => Promise.resolve(),
35263526
sendMail: () => Promise.resolve(),
35273527
};
@@ -3546,7 +3546,7 @@ describe('Parse.User testing', () => {
35463546

35473547
it('should allow updates to fields with maintenanceKey', async () => {
35483548
const emailAdapter = {
3549-
sendVerificationEmail: () => {},
3549+
sendVerificationEmail: () => { },
35503550
sendPasswordResetEmail: () => Promise.resolve(),
35513551
sendMail: () => Promise.resolve(),
35523552
};
@@ -3576,8 +3576,8 @@ describe('Parse.User testing', () => {
35763576
expect(e.code).toBe(Parse.Error.OBJECT_NOT_FOUND);
35773577
expect(
35783578
e.message === 'Invalid username/password.' ||
3579-
e.message ===
3580-
'Your account is locked due to multiple failed login attempts. Please try again after 1 minute(s)'
3579+
e.message ===
3580+
'Your account is locked due to multiple failed login attempts. Please try again after 1 minute(s)'
35813581
).toBeTrue();
35823582
}
35833583
}

src/RestWrite.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -523,10 +523,15 @@ 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+
529+
const foundUserIsNotCurrentUser = userId && userResult && userId !== userResult.objectId;
530+
531+
if (results.length > 1 || foundUserIsNotCurrentUser) {
527532
// To avoid https://github.com/parse-community/parse-server/security/advisories/GHSA-8w3j-g983-8jh5
528533
// Let's run some validation before throwing
529-
await Auth.handleAuthDataValidation(authData, this, results[0]);
534+
await Auth.handleAuthDataValidation(authData, this, userResult);
530535
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used');
531536
}
532537

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

545550
// User found with provided authData
546551
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-
}
554552

555553
this.storage.authProvider = Object.keys(authData).join(',');
556554

@@ -1311,7 +1309,7 @@ RestWrite.prototype.handleInstallation = function () {
13111309
throw new Parse.Error(
13121310
132,
13131311
'Must specify installationId when deviceToken ' +
1314-
'matches multiple Installation objects'
1312+
'matches multiple Installation objects'
13151313
);
13161314
} else {
13171315
// Multiple device token matches and we specified an installation ID,

0 commit comments

Comments
 (0)