Skip to content

Commit 19c74dc

Browse files
pragatimodikevinthecheunglahirumaramba
authored
chore: Excluding certain event_types from processing uid (#2370)
* adding optional param to token verifier * update _verifyAuthBlockingToken method * fix lint * adding public definitions * add AuthBlockingEventType type * use decoded payload instead * remove debug statement * formatting * add unit tests * unit test * unit test * add comment per code review * Apply suggestions from code review Co-authored-by: Kevin Cheung <[email protected]> * fix unit test messages * fix lint --------- Co-authored-by: Kevin Cheung <[email protected]> Co-authored-by: Lahiru Maramba <[email protected]>
1 parent a833f4e commit 19c74dc

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

src/auth/token-verifier.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,19 @@ export class FirebaseTokenVerifier {
529529
errorMessage = `${this.tokenInfo.jwtName} has incorrect "iss" (issuer) claim. Expected ` +
530530
`"${this.issuer}` + projectId + '" but got "' +
531531
payload.iss + '".' + projectIdMatchMessage + verifyJwtTokenDocsMessage;
532-
} else if (typeof payload.sub !== 'string') {
533-
errorMessage = `${this.tokenInfo.jwtName} has no "sub" (subject) claim.` + verifyJwtTokenDocsMessage;
534-
} else if (payload.sub === '') {
535-
errorMessage = `${this.tokenInfo.jwtName} has an empty string "sub" (subject) claim.` + verifyJwtTokenDocsMessage;
536-
} else if (payload.sub.length > 128) {
537-
errorMessage = `${this.tokenInfo.jwtName} has "sub" (subject) claim longer than 128 characters.` +
538-
verifyJwtTokenDocsMessage;
532+
} else if (!(payload.event_type !== undefined &&
533+
(payload.event_type === 'beforeSendSms' || payload.event_type === 'beforeSendEmail'))) {
534+
// excluding `beforeSendSms` and `beforeSendEmail` from processing `sub` as there is no user record available.
535+
// `sub` is the same as `uid` which is part of the user record.
536+
if (typeof payload.sub !== 'string') {
537+
errorMessage = `${this.tokenInfo.jwtName} has no "sub" (subject) claim.` + verifyJwtTokenDocsMessage;
538+
} else if (payload.sub === '') {
539+
errorMessage = `${this.tokenInfo.jwtName} has an empty "sub" (subject) claim.` +
540+
verifyJwtTokenDocsMessage;
541+
} else if (payload.sub.length > 128) {
542+
errorMessage = `${this.tokenInfo.jwtName} has a "sub" (subject) claim longer than 128 characters.` +
543+
verifyJwtTokenDocsMessage;
544+
}
539545
}
540546
if (errorMessage) {
541547
throw new FirebaseAuthError(AuthClientErrorCode.INVALID_ARGUMENT, errorMessage);

test/unit/auth/token-verifier.spec.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ describe('FirebaseTokenVerifier', () => {
341341
});
342342

343343
return tokenVerifier.verifyJWT(mockIdToken)
344-
.should.eventually.be.rejectedWith('Firebase ID token has "sub" (subject) claim longer than 128 characters');
344+
.should.eventually.be.rejectedWith('Firebase ID token has a "sub" (subject) claim longer than 128 ' +
345+
'characters');
345346
});
346347
});
347348

@@ -659,7 +660,7 @@ describe('FirebaseTokenVerifier', () => {
659660

660661
return authBlockingTokenVerifier._verifyAuthBlockingToken(mockAuthBlockingToken, false, undefined)
661662
.should.eventually.be.rejectedWith(
662-
'Firebase Auth Blocking token has "sub" (subject) claim longer than 128 characters');
663+
'Firebase Auth Blocking token has a "sub" (subject) claim longer than 128 characters');
663664
});
664665
});
665666

@@ -780,5 +781,41 @@ describe('FirebaseTokenVerifier', () => {
780781
await authBlockingTokenVerifier._verifyAuthBlockingToken(idTokenNoHeader, false, undefined)
781782
.should.eventually.be.rejectedWith('Firebase Auth Blocking token has no "kid" claim.');
782783
});
784+
785+
const eventTypesWithoutUid = ['beforeSendSms', 'beforeSendEmail'];
786+
eventTypesWithoutUid.forEach((eventType) => {
787+
it('should not throw error on invalid `sub` when event_type is "' + eventType + '"' , async () => {
788+
const verifierStub = sinon.stub(PublicKeySignatureVerifier.prototype, 'verify')
789+
.resolves();
790+
stubs.push(verifierStub);
791+
792+
const mockAuthBlockingToken = mocks.generateAuthBlockingToken({
793+
subject: ''
794+
}, {
795+
event_type: eventType,
796+
});
797+
return authBlockingTokenVerifier._verifyAuthBlockingToken(mockAuthBlockingToken, false, undefined)
798+
.should.eventually.be.fulfilled;
799+
});
800+
});
801+
802+
const eventTypesWithUid = ['beforeCreate', 'beforeSignIn', undefined];
803+
eventTypesWithUid.forEach((eventType) => {
804+
it('should not throw error on invalid `sub` when event_type is "' + eventType + '"', async () => {
805+
const verifierStub = sinon.stub(PublicKeySignatureVerifier.prototype, 'verify')
806+
.resolves();
807+
stubs.push(verifierStub);
808+
809+
const mockAuthBlockingToken = mocks.generateAuthBlockingToken({
810+
subject: ''
811+
}, {
812+
event_type: eventType,
813+
});
814+
return authBlockingTokenVerifier._verifyAuthBlockingToken(mockAuthBlockingToken, false, undefined)
815+
.should.eventually.be.rejectedWith('Firebase Auth Blocking token has an empty "sub" (subject) claim.' +
816+
' See https://cloud.google.com/identity-platform/docs/blocking-functions for details on how to retrieve an' +
817+
' Auth Blocking token.');
818+
});
819+
});
783820
});
784821
});

0 commit comments

Comments
 (0)